- 1.IsDialogMessage函数
- 2.GetMessage函数
- 3.DispatchMessage函数
- 4.窗口过程函数模型
- 5.作者答疑
#define WM_INITDIALOG 0x0110
#define WM_COMMAND 0x0111
#define WM_MOUSEMOVE 0x0200
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
#define WM_MOVE 0x0003
#define WM_SIZE 0x0005
#define WM_PAINT 0x000F
#define WM_CLOSE 0x0010
#define WM_SHOWWINDOW 0x0018
#define SPI_SETGRADIENTCAPTIONS 0x1009
如果需要Hook窗口消息,这些函数必须有一定程序的了解。
1.IsDialogMessage函数函数功能:该函数决定一个消息是否指定给指定的对话框,如果是,则处理消息。 函数原型:BOOL IsDialogMessage(HWND hDlg,LPMSG IpMsg); hDlg:标识对话框。 IpMsg:指向一个含有将被检测的消息的MSG结构。 返回值:如果消息被处理,则返回值为非零值;如果消息没有被处理,则返回值为零。 检测该消息是否是对应句柄的对话框消息,如果是,则交个user32.dll模块对齐进行处理,实际上user32.dll模块将其转发给对话框所属的窗口函数了,在对话框所属的窗口函数里面对消息进行判断,最终调用消息对应的函数,而消息对应的函数是我们之前映射好的,已经存在于对话框消息映射表了。
while(GetMessage(&stMsg,NULL,0,0))
{
if(!IsDialogMessage(hDlg,&stMsg))
{
TranslateMessage(&stMsg);
DispatchMessage(&stMsg);
}
}
MSG 消息结构 在 Windows 程序中,消息是由 MSG 结构体来表示的。 结构原型:
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG, *LPMSG;
获取参数,然后转发。
2.GetMessage函数在创建窗口、显示窗口、更新窗口后,我们需要编写一个消息循环,不断地从消息队列中取出消息,并进行响应。要从消息队列中取出消息,我们需要调用GetMessage()函数,该函数的原型声明如下:
BOOL GetMessage(
LPMSG lpMsg, // address of structure with message
HWND hWnd, // handle of window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message
);
参数lpMsg指向一个消息(MSG)结构体。GetMessage从线程的消息队列中取出的消息信息将保存在该结构体对象中。 参数hWnd指定接收属于哪一个窗口的消息。通常我们将其设置为NULL,用于接收属于调用线程的所有窗口的窗口消息。 参数wMsgFilterMin指定要获取的消息的最小值,通常设置为0。 参数wMsgFilterMax指定要获取的消息的最大值。如果wMsgFilterMin和wMsgFilter Max都设置为0,则接收所有消息。 GetMessage函数接收到除WM_QUIT外的消息均返回非零值。对于WM_QUIT消息,该函数返回零。如果出现了错误,该函数返回-1,例如,当参数hWnd是无效的窗口句柄或lpMsg是无效的指针时。
3.DispatchMessage函数WINUSERAPI
LRESULT
WINAPI
DispatchMessageA(
_In_ CONST MSG *lpMsg);
函数原型:LONG DispatchMessage(CONST MSG*lpmsg); 参数:lpmsg:指向含有消息的MSG结构的指针。 返回值:返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。
4.窗口过程函数模型LONG OldWndProc = 0;
LRESULT CALLBACK WindowProc2( HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
if (uMsg == WM_KEYDOWN)
{
if (wParam == VK_F6)
{
AfxMessageBox(L"您按下了F6键");
}
}
return CallWindowProc((WNDPROC)OldWndProc,hwnd,uMsg,wParam,lParam);
}
void CttDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
OldWndProc = ::SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)WindowProc2);
}
5.作者答疑
如有疑问,敬请留言。