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進來。擺放的位置可以隨意,后期通過代碼控制,但是為了便于開發我擺放為如下:

          BaseForm窗體初始狀態

          三、編碼
          控件擺放完了之后就可以開始編碼了,窗體編碼主要難度在于消息的處理還有一個比較麻煩一點的是窗體中不同狀態下按鈕的位置處理,我直接上代碼不懂的留言詢問我再詳細解答:

          1、變量申明
          [code lang=”csharp”]#region 聲明
          private int Rgn;
          private Graphics g;
          private bool _IsResize = true;//是否允許改變窗口大小
          private FormSystemBtn _FormSystemBtnSet = FormSystemBtn.SystemAll;
          private Bitmap btn_closeImg = ImageObject.GetResBitmap(“FANGSI.UI.Images.FormImages.btn_close.png”);
          private Bitmap btn_maxImg = ImageObject.GetResBitmap(“FANGSI.UI.Images.FormImages.btn_max.png”);
          private Bitmap btn_miniImg = ImageObject.GetResBitmap(“FANGSI.UI.Images.FormImages.btn_mini.png”);
          private Bitmap btn_restoreImg = ImageObject.GetResBitmap(“FANGSI.UI.Images.FormImages.btn_restore.png”);
          private Bitmap _BackImg = ImageObject.GetResBitmap(“FANGSI.UI.Images.FormImages.background_mainwnd.jpg”);
          private Size oldSize;//記錄當前窗口大小
          private bool _MaximizeBox = true;//是否啟用最大化按鈕
          private int _TopHeight = 100;//窗體頭部高度
          //枚舉系統按鈕狀態
          public enum FormSystemBtn
          {
          SystemAll = 0,
          SystemNo = 1,
          btn_close = 2,
          btn_miniAndbtn_close = 3,
          btn_maxAndbtn_close = 4
          }
          #endregion[/code]
          2、構建方法,主要將窗體消息的處理以及按鈕位置等信息進行設置
          [code lang=”csharp”]#region 方法
          protected void SystemBtnSet()
          {
          int btnTop = 0;
          int btnRight = 6;
          int panelMargin = 2;
          if (WindowState == FormWindowState.Maximized && FormBorderStyle != System.Windows.Forms.FormBorderStyle.None)
          {
          btnTop = 10;
          btnRight = 16;
          panelMargin = 10;
          }
          this.ContentPanel.Location = new Point(panelMargin, _TopHeight);
          this.ContentPanel.Size = new Size(ClientRectangle.Width – (panelMargin * 2), ClientRectangle.Height – _TopHeight – panelMargin);

          switch ((int)_FormSystemBtnSet)
          {
          case 0:
          btn_close.BackImg = btn_closeImg;
          btn_close.Location = new Point(this.Width – 32, btnTop);
          btn_mini.BackImg = btn_miniImg;
          btn_mini.Location = new Point(this.Width – 86, btnTop);
          btn_max.BackImg = btn_maxImg;
          btn_restore.BackImg = btn_restoreImg;
          if (WindowState == FormWindowState.Normal)
          {
          btn_max.Location = new Point(this.Width – 59, btnTop);
          btn_restore.Location = new Point(this.Width – 59, -22);
          }
          else
          {
          btn_max.Location = new Point(this.Width – 59, -22);
          btn_restore.Location = new Point(this.Width – 59, btnTop);
          }
          break;
          case 1:
          btn_close.BackImg = btn_closeImg;
          btn_close.Location = new Point(this.Width – 32, -22);
          btn_max.BackImg = btn_maxImg;
          btn_max.Location = new Point(this.Width – 59, -22);
          btn_mini.BackImg = btn_miniImg;
          btn_mini.Location = new Point(this.Width – 86, -22);
          btn_restore.BackImg = btn_restoreImg;
          btn_restore.Location = new Point(this.Width – 59, -22);
          break;
          case 2:
          btn_close.BackImg = btn_closeImg;
          btn_close.Location = new Point(this.Width – 32, btnTop);
          btn_max.BackImg = btn_maxImg;
          btn_max.Location = new Point(this.Width – 59, -22);
          btn_mini.BackImg = btn_miniImg;
          btn_mini.Location = new Point(this.Width – 86, -22);
          btn_restore.BackImg = btn_restoreImg;
          btn_restore.Location = new Point(this.Width – 59, -22);
          break;
          case 3:
          btn_close.BackImg = btn_closeImg;
          btn_close.Location = new Point(this.Width – 32, btnTop);
          btn_max.BackImg = btn_maxImg;
          btn_max.Location = new Point(this.Width – 59, -22);
          btn_mini.BackImg = btn_miniImg;
          btn_mini.Location = new Point(this.Width – 59, 0);
          btn_restore.BackImg = btn_restoreImg;
          btn_restore.Location = new Point(this.Width – 59, -22);
          break;
          case 4:
          btn_close.BackImg = btn_closeImg;
          btn_close.Location = new Point(this.Width – 32, btnTop);
          btn_mini.BackImg = btn_miniImg;
          btn_mini.Location = new Point(this.Width – 86, -22);
          btn_max.BackImg = btn_maxImg;
          btn_restore.BackImg = btn_restoreImg;
          if (WindowState == FormWindowState.Normal)
          {
          btn_max.Location = new Point(this.Width – 59, btnTop);
          btn_restore.Location = new Point(this.Width – 59, -22);
          }
          else
          {
          btn_max.Location = new Point(this.Width – 59, -22);
          btn_restore.Location = new Point(this.Width – 59, btnTop);
          }
          break;
          }
          }

          private void WM_NCHITTEST(ref Message m)
          {
          int wparam = m.LParam.ToInt32();
          Point point = new Point(Win32.LOWORD(wparam), Win32.HIWORD(wparam));
          point = PointToClient(point);
          if (_IsResize)
          {
          if (point.X <= 8) { if (point.Y <= 8) m.Result = (IntPtr)Win32.HTTOPLEFT; else if (point.Y > Height – 8)
          m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
          else
          m.Result = (IntPtr)Win32.HTLEFT;
          }
          else if (point.X >= Width – 8)
          {
          if (point.Y <= 8) m.Result = (IntPtr)Win32.HTTOPRIGHT; else if (point.Y >= Height – 8)
          m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
          else
          m.Result = (IntPtr)Win32.HTRIGHT;
          }
          else if (point.Y <= 8) { m.Result = (IntPtr)Win32.HTTOP; } else if (point.Y >= Height – 8)
          m.Result = (IntPtr)Win32.HTBOTTOM;
          else
          m.Result = (IntPtr)Win32.HTCAPTION;
          }
          else
          { m.Result = (IntPtr)Win32.HTCAPTION; }
          }

          private void btn_close_Click(object sender, EventArgs e)
          {
          this.Close();
          }

          private void btn_mini_Click(object sender, EventArgs e)
          {
          Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MINIMIZE, 0);
          }

          private void btn_max_Click(object sender, EventArgs e)
          {
          Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MAXIMIZE, 0);
          }

          private void btn_restore_Click(object sender, EventArgs e)
          {
          Win32.PostMessage(base.Handle, Win32.WM_SYSCOMMAND, Win32.SC_RESTORE, 0);
          }

          private void btn_close_MouseEnter(object sender, EventArgs e)
          {
          toolTip1.SetToolTip(btn_close, “關閉”);
          }

          private void btn_max_MouseEnter(object sender, EventArgs e)
          {
          toolTip1.SetToolTip(btn_max, “最大化”);
          }

          private void btn_mini_MouseEnter(object sender, EventArgs e)
          {
          toolTip1.SetToolTip(btn_mini, “最小化”);
          }

          private void btn_restore_MouseEnter(object sender, EventArgs e)
          {
          toolTip1.SetToolTip(btn_restore, “還原”);
          }
          #endregion[/code]
          3、屬性定義以及方法重寫,將擴展屬性和窗體重繪等方法結合上一篇的基礎類庫進行處理
          [code lang=”csharp”]#region 重寫方法
          protected override void OnInvalidated(InvalidateEventArgs e)
          {
          base.OnInvalidated(e);
          }

          //重繪窗口
          protected override void OnPaint(PaintEventArgs e)
          {
          try
          {
          g = e.Graphics;
          g.SmoothingMode = SmoothingMode.HighQuality; //高質量
          g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移質量
          ImageDrawRect.DrawRect(g, ClientRectangle, base.BackColor, _TopHeight);//繪制白色內容區域
          Brush brush = new SolidBrush(Color.White);//定義畫筆
          PointF point = new PointF(10, 10);//定義標題顯示坐標
          Font TitleFont = new System.Drawing.Font(“微軟雅黑”, 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
          g.DrawString(base.Text, TitleFont, brush, point.X, point.Y);

          }
          catch
          { }
          }

          //重載WndProc方法
          protected override void WndProc(ref Message m)
          {
          try
          {
          switch (m.Msg)
          {
          //用戶選擇最大化按鈕,最小化按鈕,復原按鈕或關閉按鈕時,窗口將會接收該消息
          case Win32.WM_SYSCOMMAND:
          #region
          if ((m.WParam != (IntPtr)Win32.SC_MAXIMIZE) && (m.WParam.ToInt32() != 0xf032))
          {
          if ((m.WParam == (IntPtr)Win32.SC_RESTORE) || (m.WParam.ToInt32() == 0xf122))
          {
          base.Size = this.oldSize;
          }
          else if ((m.WParam == (IntPtr)Win32.SC_MINIMIZE) || (m.WParam.ToInt32() == 0xf022))
          {
          if (this.oldSize.Width == 0)
          {
          this.oldSize = base.Size;
          }
          }
          break;
          }
          this.oldSize = base.Size;

          #endregion
          break;
          //在需要計算窗口客戶區的大小和位置時發送。通過處理這個消息,應用程序可以在窗口大小或位置改變時控制客戶區的內容
          case Win32.WM_NCCALCSIZE:
          //窗體客戶區以外的重繪消息,一般是由系統負責處理
          case Win32.WM_NCPAINT:
          return;
          //鼠標移動,按下或釋放都會執行該消息
          case Win32.WM_NCHITTEST:
          WM_NCHITTEST(ref m);
          return;
          //畫窗體被激活或者沒有被激活時的樣子
          case Win32.WM_NCACTIVATE:
          #region
          if (m.WParam == (IntPtr)Win32.WM_FALSE)
          {
          m.Result = (IntPtr)Win32.WM_TRUE;
          }
          #endregion
          return;
          default:
          base.WndProc(ref m);
          return;
          }
          base.WndProc(ref m);
          }
          catch { }
          }

          private void BaseForm_Resize(object sender, EventArgs e)
          {
          SystemBtnSet();
          }

          protected override void OnResizeEnd(EventArgs e)
          {
          base.OnResizeEnd(e);
          this.oldSize = base.Size;
          }

          ///
          /// 重寫標題屬性
          ///
          public override string Text
          {
          set
          {
          if (value != base.Text)
          {
          base.Text = value;
          this.Invalidate();
          }
          }
          get
          {
          return base.Text;
          }
          }
          #endregion[/code]
          3、窗體屬性的定義
          [code lang=”csharp”]#region 屬性

          [DefaultValue(true)]
          [CategoryAttribute(“放肆雷特皮膚擴展屬性”), Description(“是否允許改變窗口大小”)]
          public bool IsResize
          {
          get { return this._IsResize; }
          set { _IsResize = value; }
          }

          [DefaultValue(true)]
          [CategoryAttribute(“放肆雷特皮膚擴展屬性”), Description(“是否在右上角顯示最大化按鈕”)]
          public new bool MaximizeBox
          {
          get
          {
          return base.MaximizeBox;
          }
          set
          {
          base.MaximizeBox = value; this.btn_max.Enabled = value;
          }
          }

          [CategoryAttribute(“放肆雷特皮膚擴展屬性”), Description(“系統按鈕設置”)]
          public FormSystemBtn FormSystemBtnSet
          {
          get
          {
          return _FormSystemBtnSet;
          }
          set
          {
          _FormSystemBtnSet = value;
          this.Invalidate();

          }
          }

          [CategoryAttribute(“放肆雷特皮膚擴展屬性”), Description(“獲取或設置窗體圖標”)]
          public new Icon Icon
          {
          get
          {
          return base.Icon;
          }
          set
          {
          if (value != base.Icon)
          {
          base.Icon = value;
          this.Invalidate();
          }

          }
          }

          [CategoryAttribute(“放肆雷特皮膚擴展屬性”), Description(“獲取或設置窗體頭部高度”), DefaultValue(100)]
          public new int TopHeight
          {
          get
          {
          return _TopHeight;
          }
          set
          {
          _TopHeight = value;
          this.Invalidate();

          }
          }
          #endregion[/code]
          4、窗體構造函數中窗體樣式以及動作進行初始化設置
          [code lang=”csharp”]#region 構造函數
          public BaseForm()
          {
          InitializeComponent();
          this.SetStyle(ControlStyles.UserPaint, true);//自繪
          this.SetStyle(ControlStyles.DoubleBuffer, true);// 雙緩沖
          this.SetStyle(ControlStyles.ResizeRedraw, true);//調整大小時重繪
          this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
          this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);// 雙緩沖
          this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); //透明效果
          if (this.BackgroundImage == null)
          {
          this.BackgroundImage = _BackImg;
          }
          SystemBtnSet();
          }
          #endregion[/code]
          使用的時候只需要在窗體中繼承這個窗體就可以使用窗體的風格了!下面是效果圖:
          窗體預覽
          進行到這里窗體和按鈕結合的窗體就已經出來了,中間的背景圖片是從360安全衛士提取出來的資源中拿到的。如果還有不懂的歡迎進行留言提問。下一篇就開始將文本框的制作敬請期待喔。。

          本博客所有文章如無特別注明均為原創

          如果覺得對你有幫助,可以通過下方打賞對作者表示鼓勵

          本文采用知識共享署名-非商業性使用-相同方式共享

          如若轉載,請注明出處:《C#制作高仿360安全衛士窗體(二)- 普通按鈕》http://www.solariosolutions.com/435.html

          (0)
          打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
          鋒哥的頭像鋒哥管理員
          上一篇 2013年8月6日 00:27
          下一篇 2013年8月14日 08:53

          相關推薦

          發表回復

          登錄后才能評論

          評論列表(8條)

          • 徐萌萌
            徐萌萌 2014年12月12日 11:22

            需要學習的東西好多撒

          • 沒頭腦
            沒頭腦 2014年3月21日 10:27

            必須支持!

          • 新新手
            新新手 2013年8月7日 13:21

            學習下,一直在搞winform,但一直都只關注業務邏輯,頁面基本就是幾個控件在那里放著。。。。謝謝樓主的知識分享,頂一下

            • 胖子的頭像
              鋒哥 2013年8月7日 21:39

              @新新手其實關注業務邏輯是最基本的,然后如果想讓用戶體驗度更好,用戶黏度增加除了把業務邏輯精簡還需要設計出比較友好的界面與易用性的操作方式。一起學習吧!

          • fonlan
            fonlan 2013年8月6日 13:14

            我想知道有沒有辦法仿Chrome的多標簽界面

            • 胖子的頭像
              鋒哥 2013年8月6日 13:37

              @fonlan應該是可以的,不過我沒有研究過。改天有時間研究一下。

          国产厨房乱子伦露脸,XXXXAAA欧美,日本 888 XXXX,国产欧美日韩一区二区图片