Loading

C#制作高仿360安全卫士窗体<二>

继上次C#制作高仿360安全卫士窗体<一>发布之后响应还不错,我的博客放肆雷特也来了不少的新朋友,在这里先谢谢大家的支持!我自己也反复看了一下觉得对不起大家,写的非常乱而且很少文字介绍。在这里先说明一下,我是一个纯粹想搞技术的,文笔较差。我也想锻炼自己所以才会慢慢的将自己的所学分享出来。一来可以锻炼自己的文笔,二来可以分享知识留给像我一样喜欢这些东西的朋友。所以以后如果缺少介绍和说明,请大家多多补充指正,相互提高。下面进入主题。 上一篇主要讲的如何绘制一个按钮,那么今天讲解如何绘制窗体。之前也说过,先制作按钮的作用是可以将按钮用到窗体上面那些系统按钮如最大化、最小化、关闭、还原等。首先我们对按钮的不同状态的图片进行提取,在上一篇提出来皮肤文件之后,将按钮的文件sys_button_max.png,sys_button_min.png,sys_button_close.png,sys_button_max.png,sys_button_restore.png这几个图片文件进行提取。在这里说明,可以直接使用,也可以自己进行加工。以下是我加工过的(如果需要可以直接右键另存为)

 

一、嵌入资源 图片素材准备好之后在解决方案中Images目录里面建立一个FormImages文件夹,将图片素材拷贝进去,并设置图片属性中生成操作选择为“嵌入的资源”。 二、创建窗体 资源嵌入之后再在ControlEx目录中建立一个FormEx文件夹,在该文件夹下创建一个名为BaseForm的窗体。该窗体需要修改的选项很少,大部分可以使用代码来解决。窗体创建完毕后,将创建好的ButtonEx拖进窗体,这里需要拖放5个。为了使内容更好看,还拖一个Panel进来。摆放的位置可以随意,后期通过代码控制,但是为了便于开发我摆放为如下:

 

三、编码

控件摆放完了之后就可以开始编码了,窗体编码主要难度在于消息的处理还有一个比较麻烦一点的是窗体中不同状态下按钮的位置处理,我直接上代码不懂的留言询问我再详细解答:

1、变量申明

 1 #region 声明
 2 private int Rgn;
 3 private Graphics g;
 4 private bool _IsResize = true;//是否允许改变窗口大小
 5 private FormSystemBtn _FormSystemBtnSet = FormSystemBtn.SystemAll;
 6 private Bitmap btn_closeImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_close.png");
 7 private Bitmap btn_maxImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_max.png");
 8 private Bitmap btn_miniImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_mini.png");
 9 private Bitmap btn_restoreImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.btn_restore.png");
10 private Bitmap _BackImg = ImageObject.GetResBitmap("FANGSI.UI.Images.FormImages.background_mainwnd.jpg");
11 private Size oldSize;//记录当前窗口大小
12 private bool _MaximizeBox = true;//是否启用最大化按钮
13 private int _TopHeight = 100;//窗体头部高度
14 //枚举系统按钮状态
15 public enum FormSystemBtn
16 {
17     SystemAll = 0,
18     SystemNo = 1,
19     btn_close = 2,
20     btn_miniAndbtn_close = 3,
21     btn_maxAndbtn_close = 4
22 }
23 #endregion

2、构建方法,主要将窗体消息的处理以及按钮位置等信息进行设置

  1 #region 方法
  2 protected void SystemBtnSet()
  3 {
  4     int btnTop = 0;
  5     int btnRight = 6;
  6     int panelMargin = 2;
  7     if (WindowState == FormWindowState.Maximized &amp;&amp; FormBorderStyle != System.Windows.Forms.FormBorderStyle.None)
  8     {
  9         btnTop = 10;
 10         btnRight = 16;
 11         panelMargin = 10;
 12     }
 13     this.ContentPanel.Location = new Point(panelMargin, _TopHeight);
 14     this.ContentPanel.Size = new Size(ClientRectangle.Width - (panelMargin * 2), ClientRectangle.Height - _TopHeight - panelMargin);
 15 
 16     switch ((int)_FormSystemBtnSet)
 17     {
 18         case 0:
 19             btn_close.BackImg = btn_closeImg;
 20             btn_close.Location = new Point(this.Width - 32, btnTop);
 21             btn_mini.BackImg = btn_miniImg;
 22             btn_mini.Location = new Point(this.Width - 86, btnTop);
 23             btn_max.BackImg = btn_maxImg;
 24             btn_restore.BackImg = btn_restoreImg;
 25             if (WindowState == FormWindowState.Normal)
 26             {
 27                 btn_max.Location = new Point(this.Width - 59, btnTop);
 28                 btn_restore.Location = new Point(this.Width - 59, -22);
 29             }
 30             else
 31             {
 32                 btn_max.Location = new Point(this.Width - 59, -22);
 33                 btn_restore.Location = new Point(this.Width - 59, btnTop);
 34             }
 35             break;
 36         case 1:
 37             btn_close.BackImg = btn_closeImg;
 38             btn_close.Location = new Point(this.Width - 32, -22);
 39             btn_max.BackImg = btn_maxImg;
 40             btn_max.Location = new Point(this.Width - 59, -22);
 41             btn_mini.BackImg = btn_miniImg;
 42             btn_mini.Location = new Point(this.Width - 86, -22);
 43             btn_restore.BackImg = btn_restoreImg;
 44             btn_restore.Location = new Point(this.Width - 59, -22);
 45             break;
 46         case 2:
 47             btn_close.BackImg = btn_closeImg;
 48             btn_close.Location = new Point(this.Width - 32, btnTop);
 49             btn_max.BackImg = btn_maxImg;
 50             btn_max.Location = new Point(this.Width - 59, -22);
 51             btn_mini.BackImg = btn_miniImg;
 52             btn_mini.Location = new Point(this.Width - 86, -22);
 53             btn_restore.BackImg = btn_restoreImg;
 54             btn_restore.Location = new Point(this.Width - 59, -22);
 55             break;
 56         case 3:
 57             btn_close.BackImg = btn_closeImg;
 58             btn_close.Location = new Point(this.Width - 32, btnTop);
 59             btn_max.BackImg = btn_maxImg;
 60             btn_max.Location = new Point(this.Width - 59, -22);
 61             btn_mini.BackImg = btn_miniImg;
 62             btn_mini.Location = new Point(this.Width - 59, 0);
 63             btn_restore.BackImg = btn_restoreImg;
 64             btn_restore.Location = new Point(this.Width - 59, -22);
 65             break;
 66         case 4:
 67             btn_close.BackImg = btn_closeImg;
 68             btn_close.Location = new Point(this.Width - 32, btnTop);
 69             btn_mini.BackImg = btn_miniImg;
 70             btn_mini.Location = new Point(this.Width - 86, -22);
 71             btn_max.BackImg = btn_maxImg;
 72             btn_restore.BackImg = btn_restoreImg;
 73             if (WindowState == FormWindowState.Normal)
 74             {
 75                 btn_max.Location = new Point(this.Width - 59, btnTop);
 76                 btn_restore.Location = new Point(this.Width - 59, -22);
 77             }
 78             else
 79             {
 80                 btn_max.Location = new Point(this.Width - 59, -22);
 81                 btn_restore.Location = new Point(this.Width - 59, btnTop);
 82             }
 83             break;
 84     }
 85 }
 86 
 87 private void WM_NCHITTEST(ref Message m)
 88 {
 89     int wparam = m.LParam.ToInt32();
 90     Point point = new Point(Win32.LOWORD(wparam), Win32.HIWORD(wparam));
 91     point = PointToClient(point);
 92     if (_IsResize)
 93     {
 94         if (point.X &lt;= 8)
 95         {
 96             if (point.Y &lt;= 8)                 m.Result = (IntPtr)Win32.HTTOPLEFT;             else if (point.Y &gt; Height - 8)
 97                 m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
 98             else
 99                 m.Result = (IntPtr)Win32.HTLEFT;
100         }
101         else if (point.X &gt;= Width - 8)
102         {
103             if (point.Y &lt;= 8)                 m.Result = (IntPtr)Win32.HTTOPRIGHT;             else if (point.Y &gt;= Height - 8)
104                 m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
105             else
106                 m.Result = (IntPtr)Win32.HTRIGHT;
107         }
108         else if (point.Y &lt;= 8)         {             m.Result = (IntPtr)Win32.HTTOP;         }         else if (point.Y &gt;= Height - 8)
109             m.Result = (IntPtr)Win32.HTBOTTOM;
110         else
111             m.Result = (IntPtr)Win32.HTCAPTION;
112     }
113     else
114     { m.Result = (IntPtr)Win32.HTCAPTION; }
115 }
116 
117 private void btn_close_Click(object sender, EventArgs e)
118 {
119     this.Close();
120 }
121 
122 private void btn_mini_Click(object sender, EventArgs e)
123 {
124     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MINIMIZE, 0);
125 }
126 
127 private void btn_max_Click(object sender, EventArgs e)
128 {
129     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MAXIMIZE, 0);
130 }
131 
132 private void btn_restore_Click(object sender, EventArgs e)
133 {
134     Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_RESTORE, 0);
135 }
136 
137 private void btn_close_MouseEnter(object sender, EventArgs e)
138 {
139     toolTip1.SetToolTip(btn_close, "关闭");
140 }
141 
142 private void btn_max_MouseEnter(object sender, EventArgs e)
143 {
144     toolTip1.SetToolTip(btn_max, "最大化");
145 }
146 
147 private void btn_mini_MouseEnter(object sender, EventArgs e)
148 {
149     toolTip1.SetToolTip(btn_mini, "最小化");
150 }
151 
152 private void btn_restore_MouseEnter(object sender, EventArgs e)
153 {
154     toolTip1.SetToolTip(btn_restore, "还原");
155 }
156 #endregion

3、属性定义以及方法重写,将扩展属性和窗体重绘等方法结合上一篇的基础类库进行处理

  1 #region 重写方法
  2 protected override void OnInvalidated(InvalidateEventArgs e)
  3 {
  4     base.OnInvalidated(e);
  5 }
  6 
  7 //重绘窗口
  8 protected override void OnPaint(PaintEventArgs e)
  9 {
 10     try
 11     {
 12         g = e.Graphics;
 13         g.SmoothingMode = SmoothingMode.HighQuality; //高质量
 14         g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
 15         ImageDrawRect.DrawRect(g, ClientRectangle, base.BackColor, _TopHeight);//绘制白色内容区域
 16         Brush brush = new SolidBrush(Color.White);//定义画笔
 17         PointF point = new PointF(10, 10);//定义标题显示坐标
 18         Font TitleFont = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
 19         g.DrawString(base.Text, TitleFont, brush, point.X, point.Y);
 20 
 21     }
 22     catch
 23     { }
 24 }
 25 
 26 //重载WndProc方法
 27 protected override void WndProc(ref Message m)
 28 {
 29     try
 30     {
 31         switch (m.Msg)
 32         {
 33             //用户选择最大化按钮,最小化按钮,复原按钮或关闭按钮时,窗口将会接收该消息
 34             case Win32.WM_SYSCOMMAND:
 35                 #region
 36                 if ((m.WParam != (IntPtr)Win32.SC_MAXIMIZE) &amp;&amp; (m.WParam.ToInt32() != 0xf032))
 37                 {
 38                     if ((m.WParam == (IntPtr)Win32.SC_RESTORE) || (m.WParam.ToInt32() == 0xf122))
 39                     {
 40                         base.Size = this.oldSize;
 41                     }
 42                     else if ((m.WParam == (IntPtr)Win32.SC_MINIMIZE) || (m.WParam.ToInt32() == 0xf022))
 43                     {
 44                         if (this.oldSize.Width == 0)
 45                         {
 46                             this.oldSize = base.Size;
 47                         }
 48                     }
 49                     break;
 50                 }
 51                 this.oldSize = base.Size;
 52 
 53                 #endregion
 54                 break;
 55             //在需要计算窗口客户区的大小和位置时发送。通过处理这个消息,应用程序可以在窗口大小或位置改变时控制客户区的内容
 56             case Win32.WM_NCCALCSIZE:
 57             //窗体客户区以外的重绘消息,一般是由系统负责处理
 58             case Win32.WM_NCPAINT:
 59                 return;
 60             //鼠标移动,按下或释放都会执行该消息
 61             case Win32.WM_NCHITTEST:
 62                 WM_NCHITTEST(ref m);
 63                 return;
 64             //画窗体被激活或者没有被激活时的样子
 65             case Win32.WM_NCACTIVATE:
 66                 #region
 67                 if (m.WParam == (IntPtr)Win32.WM_FALSE)
 68                 {
 69                     m.Result = (IntPtr)Win32.WM_TRUE;
 70                 }
 71                 #endregion
 72                 return;
 73             default:
 74                 base.WndProc(ref m);
 75                 return;
 76         }
 77         base.WndProc(ref m);
 78     }
 79     catch { }
 80 }
 81 
 82 private void BaseForm_Resize(object sender, EventArgs e)
 83 {
 84     SystemBtnSet();
 85 }
 86 
 87 protected override void OnResizeEnd(EventArgs e)
 88 {
 89     base.OnResizeEnd(e);
 90     this.oldSize = base.Size;
 91 }
 92 
 93 ///
 94 /// 重写标题属性
 95 ///
 96 public override string Text
 97 {
 98     set
 99     {
100         if (value != base.Text)
101         {
102             base.Text = value;
103             this.Invalidate();
104         }
105     }
106     get
107     {
108         return base.Text;
109     }
110 }
111 #endregion

3、窗体属性的定义

 1 #region 属性
 2 
 3 [DefaultValue(true)]
 4 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("是否允许改变窗口大小")]
 5 public bool IsResize
 6 {
 7     get { return this._IsResize; }
 8     set { _IsResize = value; }
 9 }
10 
11 [DefaultValue(true)]
12 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("是否在右上角显示最大化按钮")]
13 public new bool MaximizeBox
14 {
15     get
16     {
17         return base.MaximizeBox;
18     }
19     set
20     {
21         base.MaximizeBox = value; this.btn_max.Enabled = value;
22     }
23 }
24 
25 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("系统按钮设置")]
26 public FormSystemBtn FormSystemBtnSet
27 {
28     get
29     {
30         return _FormSystemBtnSet;
31     }
32     set
33     {
34         _FormSystemBtnSet = value;
35         this.Invalidate();
36 
37     }
38 }
39 
40 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("获取或设置窗体图标")]
41 public new Icon Icon
42 {
43     get
44     {
45         return base.Icon;
46     }
47     set
48     {
49         if (value != base.Icon)
50         {
51             base.Icon = value;
52             this.Invalidate();
53         }
54 
55     }
56 }
57 
58 [CategoryAttribute("放肆雷特皮肤扩展属性"), Description("获取或设置窗体头部高度"), DefaultValue(100)]
59 public new int TopHeight
60 {
61     get
62     {
63         return _TopHeight;
64     }
65     set
66     {
67         _TopHeight = value;
68         this.Invalidate();
69 
70     }
71 }
72 #endregion

4、窗体构造函数中窗体样式以及动作进行初始化设置

 1 #region 构造函数
 2 public BaseForm()
 3 {
 4     InitializeComponent();
 5     this.SetStyle(ControlStyles.UserPaint, true);//自绘
 6     this.SetStyle(ControlStyles.DoubleBuffer, true);// 双缓冲
 7     this.SetStyle(ControlStyles.ResizeRedraw, true);//调整大小时重绘
 8     this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
 9     this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);// 双缓冲
10     this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);   //透明效果
11     if (this.BackgroundImage == null)
12     {
13         this.BackgroundImage = _BackImg;
14     }
15     SystemBtnSet();
16 }
17 #endregion

使用的时候只需要在窗体中继承这个窗体就可以使用窗体的风格了!下面是效果图:

进行到这里窗体和按钮结合的窗体就已经出来了,中间的背景图片是从360安全卫士提取出来的资源中拿到的。如果还有不懂的欢迎进行留言提问。下一篇就开始将文本框的制作敬请期待喔。。


本文来自 放肆雷特 | 胖子的技术博客

posted @ 2013-08-06 12:22  Kovin  阅读(8202)  评论(34编辑  收藏  举报