當我們鼠標左鍵單擊標題欄的時候可以移動整個窗體的,但如何鼠標左擊窗體任何一個地方都可以移動整個窗體呢。可以這樣做
void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SendMessage(WM_SYSCOMMAND,0xF012,0); 方式1
// PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y)); 方式2
CDialog::OnLButtonDown(nFlags, point);
}
上述兩種方式都能達到效果,那是爲何了,特別是方式1中“0xF012”代表什麼意思,這兩種方式爲什麼可以達到想要的效果,來分析一下。
一、SendMessage(WM_SYSCOMMAND,0xF012,0)
首先查究一下0xF012代表什麼意思。它是消息WM_SYSCOMMAND的WPARAM參數其可能值也列在其中。搜索頭文件,得到WINUSER.H中有
#define SC_SIZE 0xF000
#define SC_MOVE 0xF010
#define SC_MINIMIZE 0xF020
#define SC_MAXIMIZE 0xF030
#define SC_NEXTWINDOW 0xF040
#define SC_PREVWINDOW 0xF050
#define SC_CLOSE 0xF060
#define SC_VSCROLL 0xF070
#define SC_HSCROLL 0xF080
#define SC_MOUSEMENU 0xF090
#define SC_KEYMENU 0xF100
#define SC_ARRANGE 0xF110
#define SC_RESTORE 0xF120
#define SC_TASKLIST 0xF130
#define SC_SCREENSAVE 0xF140
#define SC_HOTKEY 0xF150
#if(WINVER >= 0x0400)
#define SC_DEFAULT 0xF160
#define SC_MONITORPOWER 0xF170
#define SC_CONTEXTHELP 0xF180
#define SC_SEPARATOR 0xF00F
發現0xF012與SC_MOVE可能有關(感覺也應該是),可又不是完全一樣0xF012與0xF010(SC_MOVE)最後4bit不一樣。再查WM_SYSCOMMAND對應的處理函數OnSysCommand(UINT nID, LPARAM lParam),一般是這樣的:
void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
從CDialog::OnSysCommand(nID, lParam)可以追溯到(待續)
二、PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y))
當用戶在窗口客戶區按下鼠標左鍵時,使Windows認爲鼠標是在標題條上, 即在處理WM_LBUTTONDOWN消息的處理函數OnLButtonDown中發送一個wParam參數爲HTCAPTION,lParam爲當前座標的WM_NCLBUTTONDOWN消息。如此達到單擊窗體任何一個地方拖動整個窗口的效果