拖动windows窗口,采用自己编写WM_LButtonDown, WM_MOUSEMOVE, WM_LButtonUp来进行窗口拖动,非常麻烦也很容易出现问题。
Windows系统本身就自带了这些消息,只是需要找到这些消息,然后发送就可以了。
一般的Button控件是将WM_LBUTTONDOWN和WM_MOUSEMOVE以及WM_LBUTTONUP消息转换为对应的NC消息,即Non-Client消息,分别为:
WM_NCLBUTTONDOWN, WM_NCMOUSEMOVE, WM_NCLBUTTONUP,NC部分有很多,拖动是在标题部分,因此第二个参数为HTCAPTION。系统在进行NC消息处理的时候,首先会发送WM_NCHITTEST消息,来查找当前是那个NC部分。具体代码如下(CDragButton派生自CButton):
1
2 void CDragButton::OnLButtonDown(UINT nFlags, CPoint point)
3 {
4 // TODO: Add your message handler code here and/or call default
5
6 SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
7
8 // CButton::OnLButtonDown(nFlags, point);
9 }
10
11 void CDragButton::OnMouseMove(UINT nFlags, CPoint point)
12 {
13 // TODO: Add your message handler code here and/or call default
14 SendMessage( WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(point.x, point.y));
15
16 // CButton::OnMouseMove(nFlags, point);
17 }
18
19 void CDragButton::OnLButtonUp(UINT nFlags, CPoint point)
20 {
21 // TODO: Add your message handler code here and/or call default
22 SendMessage( WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(point.x, point.y));
23 CButton::OnLButtonUp(nFlags, point);
24 }
25
2 void CDragButton::OnLButtonDown(UINT nFlags, CPoint point)
3 {
4 // TODO: Add your message handler code here and/or call default
5
6 SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
7
8 // CButton::OnLButtonDown(nFlags, point);
9 }
10
11 void CDragButton::OnMouseMove(UINT nFlags, CPoint point)
12 {
13 // TODO: Add your message handler code here and/or call default
14 SendMessage( WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(point.x, point.y));
15
16 // CButton::OnMouseMove(nFlags, point);
17 }
18
19 void CDragButton::OnLButtonUp(UINT nFlags, CPoint point)
20 {
21 // TODO: Add your message handler code here and/or call default
22 SendMessage( WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(point.x, point.y));
23 CButton::OnLButtonUp(nFlags, point);
24 }
25
但对于CStatic控件,进行上述消息发送的时候,系统并不会进行窗口拖动,CStatic毫无反应,据说是系统内部对Static控件做了一些特殊的屏蔽处理,但可以通过特殊的消息进行拖动,比上面的还要简洁些:
1 void CDragStatic::OnLButtonDown(UINT nFlags, CPoint point)
2 {
3 // TODO: Add your message handler code here and/or call default
4 SendMessage( WM_SYSCOMMAND, 0xF012, 0);
5 //SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
6 // CStatic::OnLButtonDown(nFlags, point);
7 }
2 {
3 // TODO: Add your message handler code here and/or call default
4 SendMessage( WM_SYSCOMMAND, 0xF012, 0);
5 //SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
6 // CStatic::OnLButtonDown(nFlags, point);
7 }
直接向系统发送WM_SYSCOMMAND, 0xF012消息,就可以准确运行了。
要在控件中进行相关的消息处理,必须要选中控件的Notify属性。