当我们鼠标左键单击标题栏的时候可以移动整个窗体的,但如何鼠标左击窗体任何一个地方都可以移动整个窗体呢。可以这样做
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消息。如此达到单击窗体任何一个地方拖动整个窗口的效果