拖動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
但對於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 }
直接向系統發送WM_SYSCOMMAND, 0xF012訊息,就可以準確運行了。
要在控制項中進行相關的訊息處理,必須要選中控制項的Notify屬性。