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安全衛士提取出來的資源中拿到的。如果還有不懂的歡迎進行留言提問。下一篇就開始將文本框的制作敬請期待喔。。


本文來自 放肆雷特 | 胖子的技術博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM