GroupPanel美化扩展----------WinForm控件开发系列

 该控件是继承于 Control 基类开发的。主要添加做标题栏,标题栏包括图标和文本,目前边框不可以调整,如果你有需要动态调整边框,你可以继续完善这个控件。

该控件的标题和边框是属于非工作区绘制的。

非工作区的绘制主要是靠拦截 Window 消息完成如下

 1         protected override void WndProc(ref Message m)
 2         {
 3             switch (m.Msg)
 4             {
 5                 case WM_NCCALCSIZE:
 6                     {
 7                         if (m.WParam != IntPtr.Zero)
 8                         {
 9                             NCCALCSIZE_PARAMS ncsize = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
10                             ncsize.ncOldClientRectangle.Top = ncsize.ncNewRectangle.Top += this.titleHeight;
11                             ncsize.ncOldClientRectangle.Left = ncsize.ncNewRectangle.Left += this.border;
12                             ncsize.ncOldClientRectangle.Right = ncsize.ncNewRectangle.Right -= this.border;
13                             ncsize.ncOldClientRectangle.Bottom = ncsize.ncNewRectangle.Bottom -= this.border;
14                             Marshal.StructureToPtr(ncsize, m.LParam, false);
15                         }
16                         else
17                         {
18                             RECT ncsize = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
19                             ncsize.Top += this.titleHeight;
20                             ncsize.Left += this.border;
21                             ncsize.Right -= this.border;
22                             ncsize.Bottom -= this.border;
23                             Marshal.StructureToPtr(ncsize, m.LParam, false);
24                         }
25 
26                         this.Send_WM_NCPAINT_Message();
27                         return;
28                     }
29                 case WM_NCPAINT:
30                 case WM_NCACTIVATE:
31                     {
32                         this.NCInvalidate();
33                         return;
34                     }
35             }
36             base.WndProc(ref m);
37         }

再定义重绘非工作区 如下

 1         /// <summary>
 2         /// 绘制非工作区域
 3         /// </summary>
 4         protected virtual void OnNCPaint(PaintEventArgs e)
 5         {
 6             Graphics g = e.Graphics;
 7 
 8             #region 边框
 9             if (this.border > 0)
10             {
11                 Pen border_pen = new Pen(this.BorderColor, this.border);
12                 g.DrawLine(border_pen, new PointF(g.VisibleClipBounds.X, g.VisibleClipBounds.Bottom - this.border / 2), new PointF(g.VisibleClipBounds.Right, g.VisibleClipBounds.Bottom - this.border / 2));
13                 g.DrawLine(border_pen, new PointF(g.VisibleClipBounds.X + this.border / 2, g.VisibleClipBounds.Y + this.titleHeight), new PointF(g.VisibleClipBounds.X + this.border / 2, g.VisibleClipBounds.Bottom));
14                 g.DrawLine(border_pen, new PointF(g.VisibleClipBounds.Right - this.border / 2, g.VisibleClipBounds.Y+this.titleHeight), new PointF(g.VisibleClipBounds.Right - this.border / 2, g.VisibleClipBounds.Bottom));
15                 border_pen.Dispose();
16             }
17             #endregion
18 
19             #region 标题
20             SolidBrush title_back_sb = new SolidBrush(this.TitleBackColor);
21             RectangleF title_rect = new RectangleF(g.VisibleClipBounds.X, g.VisibleClipBounds.Y, g.VisibleClipBounds.Width, this.titleHeight);
22             g.FillRectangle(title_back_sb, title_rect);
23             title_back_sb.Dispose();
24 
25             #region 标题图标
26             if (this.TitleImage != null)
27             {
28                 int image_w = this.TitleImage.Width;
29                 int image_h = this.TitleImage.Height;
30                 g.DrawImage(this.TitleImage, new RectangleF(g.VisibleClipBounds.X + this.border, g.VisibleClipBounds.Y + (this.titleHeight - image_h) / 2, image_w, image_h));
31             }
32             #endregion
33 
34             #region 标题文本
35             if (!String.IsNullOrWhiteSpace(Title))
36             {
37                 SolidBrush title_text_sb = new SolidBrush(this.TitleTextColor);
38                 SizeF text_size = g.MeasureString(this.Title, this.TitleFont);
39                 RectangleF text_rect = RectangleF.Empty;
40                 if (this.TitleAlign == TitleAligns.Left)
41                 {
42                     int image_w = this.TitleImage == null ? 0 : this.TitleImage.Width;
43                     text_rect = new RectangleF(g.VisibleClipBounds.X + this.border + image_w + 5, g.VisibleClipBounds.Y + (this.titleHeight - text_size.Height) / 2f, text_size.Width, text_size.Height);
44                 }
45                 else if (this.TitleAlign == TitleAligns.Center)
46                 {
47                     text_rect = new RectangleF(g.VisibleClipBounds.X + (g.VisibleClipBounds.Width - text_size.Width) / 2f, g.VisibleClipBounds.Y + (this.titleHeight - text_size.Height) / 2f, text_size.Width, text_size.Height);
48                 }
49                 else
50                 {
51                     text_rect = new RectangleF(g.VisibleClipBounds.Right - text_size.Width - this.border, g.VisibleClipBounds.Y + (this.titleHeight - text_size.Height) / 2f, text_size.Width, text_size.Height);
52                 }
53                 g.DrawString(this.Title, this.TitleFont, title_text_sb, text_rect);
54                 title_text_sb.Dispose();
55             }
56             #endregion
57 
58             #endregion
59 
60         }
61 
62 
63         /// <summary>
64         /// 重新绘制非工作区
65         /// </summary>
66         private void NCInvalidate()
67         {
68             IntPtr hDC = GetWindowDC(this.Handle);
69             Graphics g = Graphics.FromHdc(hDC);
70             this.OnNCPaint(new PaintEventArgs(g, new Rectangle(0, 0, this.Width, this.Height)));
71             g.Dispose();
72             ReleaseDC(this.Handle, hDC);
73         }
74 
75         /// <summary>
76         /// 发送非工作区绘制信息
77         /// </summary>
78         private void Send_WM_NCPAINT_Message()
79         {
80             SendMessage(this.Handle, WM_NCPAINT, (IntPtr)1, (IntPtr)0);
81         }

 新增属性如下

控件库的源码已整体发布到gitee,下载地址:(花木兰控件库)https://gitee.com/tlmbem/hml

posted @ 2020-07-07 22:54  唧唧复唧唧木兰当户织  阅读(2505)  评论(0编辑  收藏  举报