相關消息:WM_NCHITTEST
MSDN描述:The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.
當鼠標移動、或者點擊/釋放按鈕時,發出WM_NCHITTEST消息給對應窗口。
相關消息宏:ON_WM_NCHITTEST()
相關處理函數:LRESULT OnNcHitTest(CPoint)
MSDN描述:The framework calls this member function for the CWnd object that contains the cursor (or the CWnd object that used the SetCapture member function to capture the mouse input) every time the mouse is moved.
當鼠標移動時, MFC框架總是調用這個屬於CWnd對象的成員函數,這個對象包含了鼠標指針的狀態、或者說是這個對象使用了SetCapture這個成員函數捕獲了鼠標的輸入。
每當鼠標在窗口移動的時候,總會產生WM_NCHITTEST消息,這個消息被成員函數OnNcHitTest(CPoint)處理。成員函數OnNcHitTest將返回鼠標點擊測試枚舉值(即、鼠標位置)。要實現非標題欄拖動窗口,這種思路是通過改變鼠標點擊測試值、使鼠標在窗口上拖動的事件改變爲在標題欄拖動的事件。這種實現方式的基礎在於、MFC將鼠標點擊事件處理和獲取鼠標座標分開執行。一方面,鼠標移動不斷產生WM_NCHITTEST消息,這個消息不斷更新鼠標在窗口的位置;另一方面,鼠標點擊時,使用WM_NCHITTEST消息處理程序更新的鼠標位置來做對應處理。這樣,當鼠標位置值爲HTCLIENT時,將其修改爲HTCAPTION,即可讓鼠標在窗口非標題欄拖動事件改爲標題欄拖動事件。
但是這樣的做法並不合理,因爲標題欄如果有其他的左鍵單擊/擊、右鍵單/雙擊、甚至滾動事件處理,那麼這些動作在非標題欄上也會響應。
這只是提供一個思路,很有意思。
附:
鼠標點擊測試枚舉值如下:
-
HTBORDER In the border of a window that does not have a sizing border. //在不具有可變大小邊框的窗口的邊框上
-
HTBOTTOM In the lower horizontal border of the window. //在窗口的水平邊框的底部
-
HTBOTTOMLEFT In the lower-left corner of the window border. //在窗口邊框的左下角
-
HTBOTTOMRIGHT In the lower-right corner of the window border. //在窗口邊框的右下角
-
HTCAPTION In a title-bar area. //在標題欄區域內
-
HTCLIENT In a client area. //在客戶區內
-
HTERROR On the screen background or on a dividing line between windows (same as HTNOWHERE except that the DefWndProc Windows function produces a system beep to indicate an error). //在屏幕背景或窗口之間的分隔線上(與HTNOWHERE相同,除了Windows的DefWndProc函數產生一個系統響聲以指明錯誤)
-
HTGROWBOX In a size box. //在尺寸框中
-
HTHSCROLL In the horizontal scroll bar. //在水平滾動條中
-
HTLEFT In the left border of the window. //在窗口左邊框上
-
HTMAXBUTTON In a Maximize button. //在最大化按鈕上
-
HTMENU In a menu area. //在菜單區上
-
HTMINBUTTON In a Minimize button. //在最小化按鈕上
-
HTNOWHERE On the screen background or on a dividing line between windows. //在屏幕背景或者窗口分割線上
-
HTREDUCE In a Minimize button. //在最小化按鈕上
-
HTRIGHT In the right border of the window. //在窗口右邊框上
-
HTSIZE In a size box (same as HTGROWBOX). //在尺寸框中
-
HTSYSMENU In a Control menu or in a Close button in a child window. //在控制菜單上或子窗口關閉按鈕上
-
HTTOP In the upper horizontal border of the window. //在窗口水平框頂端
-
HTTOPLEFT In the upper-left corner of the window border. //在窗口左上角
-
HTTOPRIGHT In the upper-right corner of the window border. //在窗口右上角
-
HTTRANSPARENT In a window currently covered by another window. //在一個被其他窗口覆蓋的窗口中
-
HTVSCROLL In the vertical scroll bar. //在垂直滾動條上
-
HTZOOM In a Maximize button. //在最大化按鈕上