Winform 自定义窗体皮肤组件

匿名 (未验证) 提交于 2019-12-02 22:10:10

分享一个很久之前写的一个Winform换肤组件。

主要利用CBT钩子,NativeWindow来实现。可实现动态换皮肤插件修改窗体显示外观。
我们先定义一个自定义组件

using Skin; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace SkinControl { public class LySkinEngine : Component { #region 字段 public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);     private static HookProc _cbtHook;      private static IntPtr Hook;      private static string m_SkinName = "";     #endregion      #region API     /// <summary>     /// SetWindowsHookEx     /// </summary>     /// <param name="idHook"></param>     /// <param name="lpfn"></param>     /// <param name="hMod"></param>     /// <param name="dwThreadId"></param>     /// <returns></returns>     [DllImport("User32.dll", CharSet = CharSet.Auto)]     public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, int hMod, int dwThreadId);      /// <summary>     /// CallNextHookEx     /// </summary>     /// <param name="hhk"></param>     /// <param name="nCode"></param>     /// <param name="wParam"></param>     /// <param name="lParam"></param>     /// <returns></returns>     [DllImport("User32.dll", CharSet = CharSet.Auto)]     public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);      /// <summary>     /// UnhookWindowsHookEx     /// </summary>     /// <param name="hhk"></param>     /// <returns></returns>     [DllImport("User32.dll", CharSet = CharSet.Auto)]     public static extern bool UnhookWindowsHookEx(IntPtr hhk);     #endregion      #region FnHookProc     /// <summary>     /// FnHookProc     /// </summary>     /// <param name="nCode"></param>     /// <param name="wParam"></param>     /// <param name="lParam"></param>     /// <returns></returns>     private static IntPtr FnHookProc(int nCode, IntPtr wParam, IntPtr lParam)     {          switch (nCode)         {             case 5:                 Control control = Control.FromHandle(wParam);                  if (control != null)                 {                      Skin.SkinResource tmpSkinClass = GetSkin();                      FormBase frmBase = new FormBase(control as Form, tmpSkinClass);                  }                 break;             default:                 break;         }         return CallNextHookEx(Hook, nCode, wParam, lParam);     }     #endregion      #region 动态加载皮肤资源     private static SkinResource GetSkin()     {         SkinResource tmpResource = new SkinResource();          Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + @"\Skin\" + m_SkinName + @".dll");          Type type = ass.GetType("SkinFile.Skin");          //生成实例 Skin1         Object obj = Activator.CreateInstance(type);          //标题背景         PropertyInfo pi = type.GetProperty("CaptionBackgroundColor");         tmpResource.CaptionBackgroundColor = (Color)pi.GetValue(obj, null);         //标题前景色         PropertyInfo pi1 = type.GetProperty("CaptionColor");         tmpResource.CaptionColor = (Color)pi1.GetValue(obj, null);           return tmpResource;     }     #endregion          public void SetSkin(string varSkinName)     {         m_SkinName = varSkinName;         if (Hook == IntPtr.Zero)         {             _cbtHook = new HookProc(FnHookProc);             Hook = SetWindowsHookEx(5, _cbtHook, 0, AppDomain.GetCurrentThreadId());             Application.ApplicationExit += new EventHandler(Application_ApplicationExit);         }     }      /// <summary>     /// Application_ApplicationExit     /// </summary>     /// <param name="sender"></param>     /// <param name="e"></param>     private void Application_ApplicationExit(object sender, EventArgs e)     {         //Engine.Dispose(false);         UnhookWindowsHookEx(Hook);     }  } }
View Code

新增一个皮肤资源类,主要用于存储皮肤文件中的信息

namespace Skin { public class SkinResource { public Color CaptionColor {get;set;} public Color CaptionBackgroundColor {get;set;} } }

新增一个类,主要实现对窗体的消息接管和绘制

namespace Skin { public partial class FormBase : NativeWindow { Form m_f = null;     public FormBase(Form varForm,  Skin.SkinResource varSkin)     {         try         {             m_f = varForm;             AssignHandle(m_f.Handle);             m_f.HandleDestroyed += new EventHandler(this.OnHandleDestroyed);              CloseButtonImage = Resource1.close_normal;             CloseButtonHoverImage = Resource1.close_highlight;             CloseButtonPressDownImage = Resource1.close_press;              MaximumButtonImage = Resource1.max_normal;             MaximumButtonHoverImage = Resource1.max_highlight;             MaximumButtonPressDownImage = Resource1.max_press;              MaximumNormalButtonImage = Resource1.restore_normal;             MaximumNormalButtonHoverImage = Resource1.restore_highlight;             MaximumNormalButtonPressDownImage = Resource1.restore_press;              MinimumButtonImage = Resource1.min_normal;             MinimumButtonHoverImage = Resource1.min_highlight;             MinimumButtonPressDownImage = Resource1.min_press;              HelpButtonImage = Resource1.skin_normal;             HelpButtonHoverImage = Resource1.skin_highlight;             HelpButtonPressDownImage = Resource1.skin_press;              CaptionColor = varSkin.CaptionColor;             CaptionBackgroundColor = varSkin.CaptionBackgroundColor;          }         catch(Exception ex)         {         }           }       #region 字段      struct _NonClientSizeInfo     {         public Size CaptionButtonSize;         public Size BorderSize;         public int CaptionHeight;         public Rectangle CaptionRect;         public Rectangle Rect;         public Rectangle ClientRect;         public int Width;         public int Height;     };      #region 常量      const int WM_NCACTIVATE = 0x86;     const int WM_NCPAINT = 0x85;     const int WM_NCLBUTTONDOWN = 0xA1;     const int WM_NCRBUTTONDOWN = 0x00A4;     const int WM_NCRBUTTONUP = 0x00A5;     const int WM_NCMOUSEMOVE = 0x00A0;     const int WM_NCLBUTTONUP = 0x00A2;     const int WM_NCCALCSIZE = 0x0083;     const int WM_NCMOUSEHOVER = 0x02A0;     const int WM_NCMOUSELEAVE = 0x02A2;     const int WM_NCHITTEST = 0x0084;     const int WM_NCCREATE = 0x0081;     //const int WM_RBUTTONUP = 0x0205;      const int WM_LBUTTONDOWN = 0x0201;     const int WM_CAPTURECHANGED = 0x0215;     const int WM_LBUTTONUP = 0x0202;     const int WM_SETCURSOR = 0x0020;     const int WM_CLOSE = 0x0010;     const int WM_SYSCOMMAND = 0x0112;     const int WM_MOUSEMOVE = 0x0200;     const int WM_SIZE = 0x0005;     const int WM_SIZING = 0x0214;     const int WM_GETMINMAXINFO = 0x0024;     const int WM_ENTERSIZEMOVE = 0x0231;     const int WM_WINDOWPOSCHANGING = 0x0046;       // FOR WM_SIZING MSG WPARAM     const int WMSZ_BOTTOM = 6;     const int WMSZ_BOTTOMLEFT = 7;     const int WMSZ_BOTTOMRIGHT = 8;     const int WMSZ_LEFT = 1;     const int WMSZ_RIGHT = 2;     const int WMSZ_TOP = 3;     const int WMSZ_TOPLEFT = 4;     const int WMSZ_TOPRIGHT = 5;      // left mouse button is down.     const int MK_LBUTTON = 0x0001;      const int SC_CLOSE = 0xF060;     const int SC_MAXIMIZE = 0xF030;     const int SC_MINIMIZE = 0xF020;     const int SC_RESTORE = 0xF120;     const int SC_CONTEXTHELP = 0xF180;      const int HTCAPTION = 2;     const int HTCLOSE = 20;     const int HTHELP = 21;     const int HTMAXBUTTON = 9;     const int HTMINBUTTON = 8;     const int HTTOP = 12;      const int SM_CYBORDER = 6;     const int SM_CXBORDER = 5;     const int SM_CYCAPTION = 4;      const int CS_DropSHADOW = 0x20000;     const int GCL_STYLE = (-26);      #endregion     #endregion      #region windows api      [DllImport("User32.dll")]     private static extern IntPtr GetWindowDC(IntPtr hwnd);     [DllImport("User32.dll")]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool GetWindowRect(IntPtr hwnd, ref Rectangle rect);     [DllImport("User32.dll")]     private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);      [DllImport("user32.dll", CharSet = CharSet.Auto)]     public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);     [DllImport("user32.dll", CharSet = CharSet.Auto)]     public static extern int GetClassLong(IntPtr hwnd, int nIndex);      #endregion      #region 构造函数     internal void OnHandleCreated(object sender, EventArgs e)     {         AssignHandle(((Form)sender).Handle);     }      internal void OnHandleDestroyed(object sender, EventArgs e)     {         ReleaseHandle();     }     #endregion      #region 属性      [Category("ControlBox")]     [Description("Close button image in control box.")]     [DisplayName("CloseButtonImage")]     [DesignOnly(true)]     public Image CloseButtonImage { get; set; }      [Category("ControlBox")]     [Description("Close button image pressed down in control box.")]     [DisplayName("CloseButtonPressDownImage")]     [DesignOnly(true)]     public Image CloseButtonPressDownImage { get; set; }      [Category("ControlBox")]     [Description("Close button image hover in control box.")]     [DisplayName("CloseButtonHoverImage")]     [DesignOnly(true)]     public Image CloseButtonHoverImage { get; set; }      [Category("ControlBox")]     [Description("Maximum button image in control box.")]     [DisplayName("MaximumButtonImage")]     [DesignOnly(true)]     public Image MaximumButtonImage { get; set; }      [Category("ControlBox")]     [Description("Maximum button hover image in control box.")]     [DisplayName("MaximumButtonHoverImage")]     [DesignOnly(true)]     public Image MaximumButtonHoverImage { get; set; }      [Category("ControlBox")]     [Description("Maximum button pressed down image in control box.")]     [DisplayName("MaximumButtonPressDownImage")]     [DesignOnly(true)]     public Image MaximumButtonPressDownImage { get; set; }      [Category("ControlBox")]     [Description("Maximum Normal button image in control box.")]     [DisplayName("MaximumNormalButtonImage")]     [DesignOnly(true)]     public Image MaximumNormalButtonImage { get; set; }      [Category("ControlBox")]     [Description("Maximum Normal button hover image in control box.")]     [DisplayName("MaximumNormalButtonHoverImage")]     [DesignOnly(true)]     public Image MaximumNormalButtonHoverImage { get; set; }      [Category("ControlBox")]     [Description("Maximum Normal button pressed down image in control box.")]     [DisplayName("MaximumNormalButtonPressDownImage")]     [DesignOnly(true)]     public Image MaximumNormalButtonPressDownImage { get; set; }      [Category("ControlBox")]     [Description("Minimum button image in control box.")]     [DisplayName("MinimumButtonImage")]     [DesignOnly(true)]     public Image MinimumButtonImage { get; set; }      [Category("ControlBox")]     [Description("Minimum button hover image in control box.")]     [DisplayName("MinimumButtonHoverImage")]     [DesignOnly(true)]     public Image MinimumButtonHoverImage { get; set; }      [Category("ControlBox")]     [Description("Minimum button pressed down image in control box.")]     [DisplayName("MinimumButtonPressDownImage")]     [DesignOnly(true)]     public Image MinimumButtonPressDownImage { get; set; }      [Category("ControlBox")]     [Description("Help button image in control box.")]     [DisplayName("HelpButtonImage")]     [DesignOnly(true)]     public Image HelpButtonImage { get; set; }      [Category("ControlBox")]     [Description("Help button hover image in control box.")]     [DisplayName("HelpButtonHoverImage")]     [DesignOnly(true)]     public Image HelpButtonHoverImage { get; set; }      [Category("ControlBox")]     [Description("Help button pressed down image in control box.")]     [DisplayName("HelpButtonPressDownImage")]     [DesignOnly(true)]     public Image HelpButtonPressDownImage { get; set; }      [Category("CaptionColor")]     [Description("The color of caption.")]     [DisplayName("CaptionColor")]     [DefaultValue(typeof(Color), "Black")]     [Browsable(true)]     public Color CaptionColor { get; set; }      [Category("CaptionColor")]     [Description("The color of caption.")]     [DisplayName("CaptionBackgroundColor")]     [DefaultValue(typeof(Color), "Black")]     [Browsable(true)]     public Color CaptionBackgroundColor { get; set; }      [DefaultValue("")]     [Browsable(true)]     [Category("ControlBox")]     public virtual ContextMenuStrip CaptionContextMenu { get; set; }     #endregion      #region 方法      private _NonClientSizeInfo GetNonClientInfo(IntPtr hwnd)     {         _NonClientSizeInfo info = new _NonClientSizeInfo();         info.CaptionButtonSize = SystemInformation.CaptionButtonSize;         info.CaptionHeight = SystemInformation.CaptionHeight;          switch (m_f.FormBorderStyle)         {             case System.Windows.Forms.FormBorderStyle.Fixed3D:                 info.BorderSize = SystemInformation.FixedFrameBorderSize;                 break;             case System.Windows.Forms.FormBorderStyle.FixedDialog:                 info.BorderSize = SystemInformation.FixedFrameBorderSize;                 break;             case System.Windows.Forms.FormBorderStyle.FixedSingle:                 info.BorderSize = SystemInformation.FixedFrameBorderSize;                 break;             case System.Windows.Forms.FormBorderStyle.FixedToolWindow:                 info.BorderSize = SystemInformation.FixedFrameBorderSize;                 info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;                 info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;                 break;             case System.Windows.Forms.FormBorderStyle.Sizable:                 info.BorderSize = SystemInformation.FrameBorderSize;                 break;             case System.Windows.Forms.FormBorderStyle.SizableToolWindow:                 info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;                 info.BorderSize = SystemInformation.FrameBorderSize;                 info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;                 break;             default:                 info.BorderSize = SystemInformation.BorderSize;                 break;         }          Rectangle areatRect = new Rectangle();         GetWindowRect(hwnd, ref areatRect);          int width = areatRect.Right - areatRect.Left;         int height = areatRect.Bottom - areatRect.Top;          info.Width = width;         info.Height = height;          Point xy = new Point(areatRect.Left, areatRect.Top);         xy.Offset(-areatRect.Left, -areatRect.Top);          info.CaptionRect = new Rectangle(xy.X, xy.Y + info.BorderSize.Height, width, info.CaptionHeight);         info.Rect = new Rectangle(xy.X, xy.Y, width, height);         info.ClientRect = new Rectangle(xy.X + info.BorderSize.Width,             xy.Y + info.CaptionHeight + info.BorderSize.Height,             width - info.BorderSize.Width * 2,             height - info.CaptionHeight - info.BorderSize.Height * 2);                  return info;     }      private void DrawTitle(Graphics g, _NonClientSizeInfo ncInfo, bool active)     {         try         {                  int titleX;          if (m_f.ShowIcon &&              m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&              m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)         {             Size iconSize = SystemInformation.SmallIconSize;             g.DrawIcon(m_f.Icon, new Rectangle(new Point(ncInfo.BorderSize.Width+5, ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - iconSize.Height) / 2+5), iconSize));             titleX = ncInfo.BorderSize.Width + iconSize.Width + ncInfo.BorderSize.Width+5;         }         else         {             titleX = ncInfo.BorderSize.Width;         }          SizeF captionTitleSize = g.MeasureString(m_f.Text, SystemFonts.CaptionFont);         g.DrawString(m_f.Text, SystemFonts.CaptionFont, new SolidBrush(CaptionColor),                 new RectangleF(titleX,                     (ncInfo.BorderSize.Height + ncInfo.CaptionHeight - captionTitleSize.Height) / 2+5,                     ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width * 2 - SystemInformation.MinimumWindowSize.Width,                     ncInfo.CaptionRect.Height), StringFormat.GenericTypographic);             }         catch(Exception ex)         {          }     }      private void DrawBorder(Graphics g, _NonClientSizeInfo ncInfo, Brush background, bool active,ref List<Rectangle> varBorders)     {                  int tmpHeight = m_f.Height;         int tmpWidth = m_f.Width;         if (ncInfo.Rect.Height != tmpHeight)         {             ncInfo.Rect.Height = tmpHeight + ncInfo.BorderSize.Height;         }         if (ncInfo.Rect.Width != tmpWidth)         {             ncInfo.Rect.Width = tmpWidth + ncInfo.BorderSize.Width;         }                   Rectangle borderTop = new Rectangle(ncInfo.Rect.Left,                 ncInfo.Rect.Top,                 ncInfo.Rect.Left + ncInfo.Rect.Width,                 ncInfo.Rect.Top + ncInfo.BorderSize.Height);         Rectangle borderLeft = new Rectangle(                 new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Location.Y + ncInfo.BorderSize.Height),                 new Size((int)(ncInfo.BorderSize.Width*2), ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height));         Rectangle borderRight = new Rectangle(ncInfo.Rect.Width- 3*ncInfo.BorderSize.Width,                 ncInfo.Rect.Top + ncInfo.BorderSize.Height,                 (int)(ncInfo.BorderSize.Width * 2),                 ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height);         Rectangle borderBottom = new Rectangle(ncInfo.Rect.Left + ncInfo.BorderSize.Width,                 ncInfo.Rect.Height - 3*ncInfo.BorderSize.Height,                 ncInfo.Rect.Width - ncInfo.BorderSize.Width ,                 (int)(ncInfo.BorderSize.Height * 2));         varBorders.Add(borderTop);         varBorders.Add(borderLeft);         varBorders.Add(borderRight);         varBorders.Add(borderBottom);                 g.FillRectangle(background, borderTop);         // left border         g.FillRectangle(background, borderLeft);         // right border         g.FillRectangle(background, borderRight);         // bottom border         g.FillRectangle(background, borderBottom);     }     private List<Rectangle> m_Borders = null;     private void DrawCaption(IntPtr hwnd, bool active)     {         m_Borders = new List<Rectangle>();         IntPtr dc;         Graphics g;         Size iconSize;         _NonClientSizeInfo ncInfo;         Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);         Brush foregroundColor = new SolidBrush(CaptionColor);          iconSize = SystemInformation.SmallIconSize;          dc = GetWindowDC(hwnd);         ncInfo = GetNonClientInfo(hwnd);         g = Graphics.FromHdc(dc);          Rectangle rc = ncInfo.CaptionRect;         rc.Height = (int)(rc.Height + ncInfo.BorderSize.Height);         g.FillRectangle(backgroundColor, rc);          DrawBorder(g, ncInfo, backgroundColor, active, ref m_Borders);         DrawTitle(g, ncInfo, active);         DrawControlBox(g, ncInfo, backgroundColor, m_f.ControlBox, m_f.MaximizeBox, m_f.MinimizeBox, m_f.HelpButton);         g.Dispose();         ReleaseDC(hwnd, dc);     }      private void DrawControlBox(Graphics g, _NonClientSizeInfo info, Brush background, bool closeBtn, bool maxBtn, bool minBtn, bool helpBtn)     {                  int tmpHeight = m_f.Height;         int tmpWidth = m_f.Width;         if (info.CaptionRect.Height > tmpHeight)         {             info.CaptionRect.Height = tmpHeight;         }         if (info.CaptionRect.Width > tmpWidth)         {             info.CaptionRect.Width = tmpWidth;         }         info.CaptionRect.Height = info.CaptionRect.Height * 2;                        if (m_f.ControlBox)         {             int closeBtnPosX =  info.CaptionRect.Width - info.BorderSize.Width - info.CaptionButtonSize.Width;             int maxBtnPosX = closeBtnPosX - info.CaptionButtonSize.Width;             int minBtnPosX = maxBtnPosX - info.CaptionButtonSize.Width;             int btnPosY = info.BorderSize.Height + (info.CaptionHeight - info.CaptionButtonSize.Height) / 2;              Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), info.CaptionButtonSize);             Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), info.CaptionButtonSize);             Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), info.CaptionButtonSize);              Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);              g.FillRectangle(backgroundColor, btnRect);             g.FillRectangle(backgroundColor, maxRect);             g.FillRectangle(backgroundColor, minRect);              g.DrawImage(CloseButtonImage, btnRect);              if (m_f.MaximizeBox || m_f.MinimizeBox)             {                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)                 {                     if (m_f.WindowState == FormWindowState.Maximized)                     {                         g.DrawImage(MaximumNormalButtonImage, maxRect);                     }                     else                     {                         g.DrawImage(MaximumButtonImage, maxRect);                     }                     g.DrawImage(MinimumButtonImage, minRect);                 }             }             else if (m_f.HelpButton)             {                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)                 {                     g.DrawImage(HelpButtonImage, maxRect);                 }             }         }      }      protected virtual void OnCaptionContextMenu(int x, int y)     {         if (this.CaptionContextMenu != null)             this.CaptionContextMenu.Show(x, y);     }      #endregion      #region 消息     private int m_IsDrawButton = 0;     private int LOBYTE(long p) { return (int)(p & 0x0000FFFF); }     private int HIBYTE(long p) { return (int)(p >> 16); }      [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]     protected override void WndProc(ref Message m)     {         try         {             if (m == null)              {                 return;             }              if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.None)             {                 switch (m.Msg)                 {                     case WM_NCPAINT:                          DrawCaption(m.HWnd, Form.ActiveForm == m_f);                         Console.WriteLine(1);                         if (m_Borders != null && m_Borders.Count > 0)                         {                             for (int i = 0; i < m_Borders.Count; i++)                             {                                 Console.WriteLine(m_Borders[i].Left + "--" + m_Borders[i].Right + "--" + m_Borders[i].Top + "--" + m_Borders[i].Bottom);                             }                         }                         Console.WriteLine("WM_NCPAINT");                         return;                     case WM_NCACTIVATE:                         Console.WriteLine("WM_NCACTIVATE");                         if (m.WParam.ToInt32() > 0)                         {                             DrawCaption(m.HWnd, m.WParam.ToInt32() > 0);                             Console.WriteLine(2);                             return;                         }                         else                         {                              break;                         }                     case WM_NCRBUTTONDOWN:                         {                             int posX, posY;                             int wp = m.WParam.ToInt32();                             long lp = m.LParam.ToInt64();                             posX = LOBYTE(lp);                             posY = HIBYTE(lp);                              if (wp == HTCAPTION)                             {                                 Point pt = m_f.PointToClient(new Point(posX, posY));                                 if (this.CaptionContextMenu != null)                                 {                                     this.CaptionContextMenu.Show(posX, posY);                                     return;                                 }                             }                             break;                         }                     case WM_SETCURSOR:                          if (m_f.ControlBox)                         {                              int posX, posY;                             int wp = m.WParam.ToInt32();                             long lp = m.LParam.ToInt64();                             posX = LOBYTE(lp);                             posY = HIBYTE(lp);                              Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);                             _NonClientSizeInfo ncInfo = GetNonClientInfo(m.HWnd);                              int tmpHeight = m_f.Height;                             int tmpWidth = m_f.Width;                             if (ncInfo.CaptionRect.Height > tmpHeight)                             {                                 ncInfo.CaptionRect.Height = tmpHeight;                             }                             if (ncInfo.CaptionRect.Width > tmpWidth)                             {                                 ncInfo.CaptionRect.Width = tmpWidth;                             }                              IntPtr dc = GetWindowDC(m.HWnd);                              Graphics g = Graphics.FromHdc(dc);                             int closeBtnPosX = ncInfo.CaptionRect.Left + ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width - ncInfo.CaptionButtonSize.Width;                             int maxBtnPosX, minBtnPosX;                             maxBtnPosX = closeBtnPosX - ncInfo.CaptionButtonSize.Width;                             minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;                              int btnPosY = ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - ncInfo.CaptionButtonSize.Height) / 2;                              Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                             Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                             Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                             if (posX != HTMAXBUTTON && posX != HTMINBUTTON && posX != HTCLOSE)                             {                                 Console.WriteLine("不在");                                 if (m_IsDrawButton <= 3)                                 {                                     m_IsDrawButton++;                                     Console.WriteLine("啊啊");                                     goto aa;                                 }                                 break;                             }                              m_IsDrawButton = 0;                             Console.WriteLine("在");                         aa:                             g.FillRectangle(backgroundColor, btnRect);                             g.FillRectangle(backgroundColor, maxRect);                             g.FillRectangle(backgroundColor, minRect);                               if (posX != HTCLOSE)                             {                                 g.DrawImage(CloseButtonImage, btnRect);                             }                             else if (System.Windows.Forms.Control.MouseButtons != System.Windows.Forms.MouseButtons.Left)                             {                                 g.DrawImage(CloseButtonHoverImage, btnRect);                             }                             else                             {                                 g.DrawImage(CloseButtonPressDownImage, btnRect);                             }                              if (m_f.MaximizeBox || m_f.MinimizeBox)                             {                                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&                                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)                                 {                                     if (m_f.WindowState == FormWindowState.Maximized)                                     {                                         if (m_f.MaximizeBox)                                         {                                             if (posX != HTMAXBUTTON)                                             {                                                 g.DrawImage(MaximumNormalButtonImage, maxRect);                                             }                                             else if (System.Windows.Forms.Control.MouseButtons != System.Windows.Forms.MouseButtons.Left)                                             {                                                 g.DrawImage(MaximumNormalButtonHoverImage, maxRect);                                             }                                             else                                             {                                                 g.DrawImage(MaximumNormalButtonPressDownImage, maxRect);                                             }                                         }                                         else                                         {                                             g.DrawImage(MaximumNormalButtonImage, maxRect);                                         }                                     }                                     else                                     {                                         if (m_f.MaximizeBox)                                         {                                             if (posX != HTMAXBUTTON)                                             {                                                 g.DrawImage(MaximumButtonImage, maxRect);                                             }                                             else if (System.Windows.Forms.Control.MouseButtons != System.Windows.Forms.MouseButtons.Left)                                             {                                                 g.DrawImage(MaximumButtonHoverImage, maxRect);                                             }                                             else                                             {                                                 g.DrawImage(MaximumButtonPressDownImage, maxRect);                                             }                                         }                                         else                                         {                                             g.DrawImage(MaximumButtonImage, maxRect);                                         }                                     }                                      if (m_f.MinimizeBox)                                     {                                         if (posX != HTMINBUTTON)                                         {                                             g.DrawImage(MinimumButtonImage, minRect);                                         }                                         else if (System.Windows.Forms.Control.MouseButtons != System.Windows.Forms.MouseButtons.Left)                                         {                                             g.DrawImage(MinimumButtonHoverImage, minRect);                                         }                                         else                                         {                                             g.DrawImage(MinimumButtonPressDownImage, minRect);                                         }                                     }                                     else                                     {                                         g.DrawImage(MinimumButtonImage, minRect);                                     }                                 }                             }                             else if (m_f.HelpButton)                             {                                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&                                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)                                 {                                     if (posX != HTHELP)                                     {                                         g.DrawImage(HelpButtonImage, maxRect);                                     }                                     else if (System.Windows.Forms.Control.MouseButtons != System.Windows.Forms.MouseButtons.Left)                                     {                                         g.DrawImage(HelpButtonHoverImage, maxRect);                                     }                                     else                                     {                                         g.DrawImage(HelpButtonPressDownImage, maxRect);                                     }                                 }                             }                             // Application.DoEvents();                             g.Dispose();                             ReleaseDC(m.HWnd, dc);                         }                         break;                     case WM_NCLBUTTONUP:                         {                             int wp = m.WParam.ToInt32();                             switch (wp)                             {                                 case HTCLOSE:                                     m.Msg = WM_SYSCOMMAND;                                     m.WParam = new IntPtr(SC_CLOSE);                                     break;                                 case HTMAXBUTTON:                                     if (m_f.MaximizeBox)                                     {                                         m.Msg = WM_SYSCOMMAND;                                         if (m_f.WindowState == FormWindowState.Maximized)                                         {                                             m.WParam = new IntPtr(SC_RESTORE);                                         }                                         else                                         {                                             m.WParam = new IntPtr(SC_MAXIMIZE);                                         }                                     }                                     break;                                 case HTMINBUTTON:                                     if (m_f.MinimizeBox)                                     {                                         m.Msg = WM_SYSCOMMAND;                                         m.WParam = new IntPtr(SC_MINIMIZE);                                     }                                     break;                                 case HTHELP:                                     m.Msg = WM_SYSCOMMAND;                                     m.WParam = new IntPtr(SC_CONTEXTHELP);                                     break;                                 default:                                     break;                             }                              break;                         }                      case WM_NCLBUTTONDOWN:                         if (m_f.ControlBox)                         {                             bool ret = false;                             int posX, posY;                             int wp = m.WParam.ToInt32();                             long lp = m.LParam.ToInt64();                             posX = LOBYTE(lp);                             posY = HIBYTE(lp);                              _NonClientSizeInfo ncInfo = GetNonClientInfo(m.HWnd);                             IntPtr dc = GetWindowDC(m.HWnd);                             Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);                              Graphics g = Graphics.FromHdc(dc);                             int closeBtnPosX = ncInfo.CaptionRect.Left + ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width - ncInfo.CaptionButtonSize.Width;                             int maxBtnPosX, minBtnPosX;                             int btnPosY = ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - ncInfo.CaptionButtonSize.Height) / 2;                             maxBtnPosX = closeBtnPosX - ncInfo.CaptionButtonSize.Width;                             minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;                              Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                             Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                             Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), ncInfo.CaptionButtonSize);                              if (wp != HTMAXBUTTON && wp != HTMINBUTTON && wp != HTCLOSE)                             {                                 break;                             }                              g.FillRectangle(backgroundColor, btnRect);                             g.FillRectangle(backgroundColor, maxRect);                             g.FillRectangle(backgroundColor, minRect);                              if (wp == HTCLOSE)                             {                                 g.DrawImage(CloseButtonPressDownImage, btnRect);                                 ret = true;                             }                             else                             {                                 g.DrawImage(CloseButtonImage, btnRect);                             }                              if (m_f.MaximizeBox || m_f.MinimizeBox)                             {                                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow &&                                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow)                                 {                                     if (m_f.WindowState == FormWindowState.Maximized)                                     {                                         if (wp == HTMAXBUTTON && m_f.MaximizeBox)                                         {                                             minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;                                             g.DrawImage(MaximumNormalButtonPressDownImage, maxRect);                                             ret = true;                                         }                                         else                                         {                                             g.DrawImage(MaximumNormalButtonImage, maxRect);                                         }                                     }                                     else                                     {                                         if (wp == HTMAXBUTTON && m_f.MaximizeBox)                                         {                                             minBtnPosX = maxBtnPosX - ncInfo.CaptionButtonSize.Width;                                             g.DrawImage(MaximumButtonPressDownImage, maxRect);                                             ret = true;                                         }                                         else                                         {                                             g.DrawImage(MaximumButtonImage, maxRect);                                         }                                     }                                     if (wp == HTMINBUTTON && m_f.MinimizeBox)                                     {                                         g.DrawImage(MinimumButtonPressDownImage, minRect);                                         ret = true;                                     }                                     else                                     {                                         g.DrawImage(MinimumButtonImage, minRect);                                     }                                 }                             }                             else if (m_f.HelpButton)                             {                                 if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&                                     m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)                                 {                                     if (wp == HTHELP)                                     {                                         g.DrawImage(HelpButtonPressDownImage, maxRect);                                         ret = true;                                     }                                     else                                     {                                         g.DrawImage(HelpButtonImage, maxRect);                                     }                                 }                             }                              g.Dispose();                             ReleaseDC(m.HWnd, dc);                              if (ret)                                 return;                         }                         break;                 }             }             try             {                 base.WndProc(ref m);             }             catch (Exception ex)             { }              if (m.Msg == WM_NCACTIVATE && m_f.FormBorderStyle != FormBorderStyle.None)             {                 if (m.WParam.ToInt32() <= 0)                 {                     DrawCaption(m.HWnd, m.WParam.ToInt32() > 0);                 }             }         }         catch (Exception ex)         {             MessageBox.Show(ex.Message);         }     }      #endregion   } }
View Code

新建一个项目,这个项目是皮肤文件。

namespace SkinFile { public class Skin { private Color _CaptionColor=Color.Blue;     public Color CaptionColor     {         get { return _CaptionColor; }         set { _CaptionColor = value; }     }      private Color _CaptionBackgroundColor=Color.Green;      public Color CaptionBackgroundColor     {         get { return _CaptionBackgroundColor; }         set { _CaptionBackgroundColor = value; }     }   } }

主要提供了窗体非客户区背景色和标题文字颜色。我们可以做个皮肤编辑工具,将用户选择的颜色按上面的命名空间和类生成dll文件。

下面进行测试:
将皮肤文件项目编译,生成dll文件放在debug目录下面的Skin文件夹下。

image.png

在窗体的构造函数中,调用

LySkinEngine SkinEngine = new LySkinEngine(); SkinEngine.SetSkin("SkinFile");


SetSkin方法的参数是我们皮肤dll文件的名称,我们可以新建多个皮肤文件,在此处动态切换。

运行效果如下

image.png

我们修改调用的皮肤名称

LySkinEngine SkinEngine = new LySkinEngine(); SkinEngine.SetSkin("SkinFile1");


效果如下:

image.png

基本效果已实现,还需要继续完善。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!