无边框窗体是无法向其他普通窗体一样用鼠标拖动边框来改变其大小的,一方面因为窗体样式中没有了WS_ThickFrame,另一方面就是因为窗体没有边框来施行拖动操作。
通过 SPY++ 的监视,终于发现了解决途径,我们要解决2方面的问题:
1、模拟出窗体边框,让Windows知道我们的Form中哪部分是客户区,哪部分是边框(可以通过在客户区内计算来区分)。
2、在我们模拟的边框范围内,截取 WM_NCHITTEST 消息,将其返回值做修改,返回拖动类型(上、下、左、右、左上、右上、左下、右下)
代码示例:
1
protected override void WndProc(ref Message m)
2
{
3
const int WM_NCHITTEST = 0x0084;
4![]()
5![]()
6
int HTCLIENT = 1;
7
int HTLEFT = 10;
8
int HTRIGHT = 11;
9
int HTTOP = 12;
10
int HTTOPLEFT = 13;
11
int HTTOPRIGHT = 14;
12
int HTBOTTOM = 15;
13
int HTBOTTOMLEFT = 16;
14
int HTBOTTOMRIGHT = 17;
15![]()
16
int offset = 3;
17
switch (m.Msg)
18
{
19
case WM_NCHITTEST:
20
int px = Form.MousePosition.X - this.Left ;
21
int py = Form.MousePosition.Y - this.Top;
22![]()
23
int temp;
24![]()
25
if (px >= this.Width - offset)
26
{
27
if (py <= offset) temp = HTTOPRIGHT;
28
else if (py >= this.Height - offset) temp = HTBOTTOMRIGHT;
29
else temp = HTRIGHT;
30
}
31
else if (px <= offset)
32
{
33
if (py <= offset) temp = HTTOPLEFT;
34
else if (py >= this.Height - offset) temp = HTBOTTOMLEFT;
35
else temp = HTLEFT;
36
}
37
else
38
{
39
if (py <= offset) temp = HTTOP;
40
else if (py >= this.Height - offset) temp = HTBOTTOM;
41
else temp = HTCLIENT;
42
}
43![]()
44
m.Result = (IntPtr)temp;
45
break;
46
default:
47
base.WndProc(ref m);
48
break;
49
}
50
}
protected override void WndProc(ref Message m)2
{3
const int WM_NCHITTEST = 0x0084;4

5

6
int HTCLIENT = 1;7
int HTLEFT = 10;8
int HTRIGHT = 11;9
int HTTOP = 12;10
int HTTOPLEFT = 13;11
int HTTOPRIGHT = 14;12
int HTBOTTOM = 15;13
int HTBOTTOMLEFT = 16;14
int HTBOTTOMRIGHT = 17;15

16
int offset = 3;17
switch (m.Msg)18
{19
case WM_NCHITTEST:20
int px = Form.MousePosition.X - this.Left ;21
int py = Form.MousePosition.Y - this.Top;22

23
int temp;24

25
if (px >= this.Width - offset)26
{27
if (py <= offset) temp = HTTOPRIGHT;28
else if (py >= this.Height - offset) temp = HTBOTTOMRIGHT;29
else temp = HTRIGHT;30
}31
else if (px <= offset)32
{33
if (py <= offset) temp = HTTOPLEFT;34
else if (py >= this.Height - offset) temp = HTBOTTOMLEFT;35
else temp = HTLEFT;36
}37
else38
{39
if (py <= offset) temp = HTTOP;40
else if (py >= this.Height - offset) temp = HTBOTTOM;41
else temp = HTCLIENT;42
}43

44
m.Result = (IntPtr)temp;45
break;46
default:47
base.WndProc(ref m);48
break;49
}50
}=================================
2006-7-5 --
今天发现以上方法在窗体拥有 WS_SYSMENU 样式的时候不起作用了,于是试着给窗体加上 WS_ThickFrame,加上以后窗体可以拖动,但是在窗体周围却出现了难看的 windows 凹凸边框,本想把扩展样式 EX_WindowEDGE 去掉,却发现去不掉,郁闷。
最后只好用笨办法,在拖动的时候把 WS_SYSMENU 去掉,拖动完成后又把 WS_SYSMENU 加回来....


浙公网安备 33010602011771号