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 && 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 <= 8) 95 { 96 if (point.Y <= 8) m.Result = (IntPtr)Win32.HTTOPLEFT; else if (point.Y > Height - 8) 97 m.Result = (IntPtr)Win32.HTBOTTOMLEFT; 98 else 99 m.Result = (IntPtr)Win32.HTLEFT; 100 } 101 else if (point.X >= Width - 8) 102 { 103 if (point.Y <= 8) m.Result = (IntPtr)Win32.HTTOPRIGHT; else if (point.Y >= Height - 8) 104 m.Result = (IntPtr)Win32.HTBOTTOMRIGHT; 105 else 106 m.Result = (IntPtr)Win32.HTRIGHT; 107 } 108 else if (point.Y <= 8) { m.Result = (IntPtr)Win32.HTTOP; } else if (point.Y >= 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) && (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安全卫士提取出来的资源中拿到的。如果还有不懂的欢迎进行留言提问。下一篇就开始将文本框的制作敬请期待喔。。
本文来自 放肆雷特 | 胖子的技术博客