C# WinForm 中在窗口标题栏上加按钮
实现主要是通过重写窗口过程(WndProc),处理一些非客户区消息(WM_NCxxxx);
1
[DllImport("User32.dll")]
2
private static extern IntPtr GetWindowDC(IntPtr hwnd);
3
[DllImport("User32.dll")]
4
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
5
[DllImport("Kernel32.dll")]
6
private static extern int GetLastError();
7
//标题栏按钮的矩形区域。
8
Rectangle m_rect = new Rectangle(100, 6, 120, 20);
9
protected override void WndProc(ref Message m)
10
{
11
base.WndProc(ref m);
12
switch (m.Msg)
13
{
14
case 0x86://WM_NCACTIVATE
15
goto case 0x85;
16
case 0x85://WM_NCPAINT
17
{
18
IntPtr hDC = GetWindowDC(m.HWnd);
19
//把DC转换为.NET的Graphics就可以很方便地使用Framework提供的绘图功能了
20
Graphics gs = Graphics.FromHdc(hDC);
21
gs.FillRectangle(new LinearGradientBrush(m_rect, Color.Pink, Color.Purple, LinearGradientMode.BackwardDiagonal), m_rect);
22
StringFormat strFmt = new StringFormat();
23
strFmt.Alignment = StringAlignment.Center;
24
strFmt.LineAlignment = StringAlignment.Center;
25
gs.DrawString("√", this.Font, Brushes.BlanchedAlmond, m_rect, strFmt);
26
gs.Dispose();
27
//释放GDI资源
28
ReleaseDC(m.HWnd, hDC);
29
break;
30
}
31
case 0xA1://WM_NCLBUTTONDOWN
32
{
33
Point mousePoint = new Point((int)m.LParam);
34
mousePoint.Offset(-this.Left, -this.Top);
35
if (m_rect.Contains(mousePoint))
36
{
37
MessageBox.Show("hello");
38
}
39
break;
40
}
41
}
42
}
[DllImport("User32.dll")]2
private static extern IntPtr GetWindowDC(IntPtr hwnd);3
[DllImport("User32.dll")]4
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);5
[DllImport("Kernel32.dll")]6
private static extern int GetLastError();7
//标题栏按钮的矩形区域。 8
Rectangle m_rect = new Rectangle(100, 6, 120, 20);9
protected override void WndProc(ref Message m)10
{11
base.WndProc(ref m);12
switch (m.Msg)13
{14
case 0x86://WM_NCACTIVATE 15
goto case 0x85;16
case 0x85://WM_NCPAINT 17
{18
IntPtr hDC = GetWindowDC(m.HWnd);19
//把DC转换为.NET的Graphics就可以很方便地使用Framework提供的绘图功能了 20
Graphics gs = Graphics.FromHdc(hDC);21
gs.FillRectangle(new LinearGradientBrush(m_rect, Color.Pink, Color.Purple, LinearGradientMode.BackwardDiagonal), m_rect);22
StringFormat strFmt = new StringFormat();23
strFmt.Alignment = StringAlignment.Center;24
strFmt.LineAlignment = StringAlignment.Center;25
gs.DrawString("√", this.Font, Brushes.BlanchedAlmond, m_rect, strFmt);26
gs.Dispose();27
//释放GDI资源28
ReleaseDC(m.HWnd, hDC);29
break;30
}31
case 0xA1://WM_NCLBUTTONDOWN 32
{33
Point mousePoint = new Point((int)m.LParam);34
mousePoint.Offset(-this.Left, -this.Top);35
if (m_rect.Contains(mousePoint))36
{37
MessageBox.Show("hello");38
}39
break;40
}41
}42
}
1)、C#中重写窗口过程不用再调用SetWindowLong API了,直接overide一个WndProc就可以了。
2)、Windows API中的HDC可以通过Graphics.FromHdc()转换为(创建出)System.Drawing.Graphics,然后就可以用.NET Framework (GID ??)提供的绘图功能方便地进行画图了。终于可以抛开讨厌的GDI API了(说实在话,在C#中调用Windows API真的太麻烦了).


浙公网安备 33010602011771号