这里简述一下关于window消息处理,主要在实际应用中;
在一个Windows程序中,一个程序的的消息是通过一个大循环来实现接收处理的;
这个可以查看win32程序的编写,具体可以详细查找相关资料;
在Windows编程中,尤其是MFC程序中,关于窗口消息是非常重要的;
窗口过程函数(接收处理窗口消息的函数),函数的主要实现在CWnd中:
LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// OnWndMsg does most of the work, except for DefWindowProc call
LRESULT lResult = 0;
if (!OnWndMsg(message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}
有上述代码可以看出,WindowProc接收到窗口的消息,首先给OnWndMsg处理,然后判断是否给DefWindowProc处理;
关于:
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
从上面的代码可以看出,所有被窗口过程函数WindowProc接收的消息,首先给OnWndMsg处理;
OnWndMsg函数同城处理的就是在窗口中添加的消息函数
下面给出应用的示例:
添加对话框OnWndMsg虚函数实现;
添加对话框DefWindowProc虚函数实现;
添加对话框OnLButtonDown想要消息函数;
BOOL CtmfcDlg::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: 在此添加专用代码和/或调用基类
switch( message )
{
case WM_LBUTTONDOWN:
MessageBox(L"OnWndMsg");//return 1;
break;
}
return CDialogEx::OnWndMsg(message, wParam, lParam, pResult);
}
LRESULT CtmfcDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
switch( message )
{
case WM_LBUTTONDOWN:
MessageBox(L"DefWindowProc");
break;
}
return CDialogEx::DefWindowProc(message, wParam, lParam);
}
void CtmfcDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
MessageBox(L"OnLButtonDown");
CDialogEx::OnLButtonDown(nFlags, point);
}
然后鼠标右键单击对话框,会依次弹出:
OnWndMsg
OnLButtonDown
DefWindowProc
通过这个函数可以看出,OnWndMsg会将相关的消息通过消息表分发给相关的消息实现函数;
如果取消CDialogEx::OnLButtonDown(nFlags, point);这句话,则DefWindowProc不显示;
或者,在OnWndMsg中的相应消息后,return 1; 表示消息已经处理过了,不在向下传递;
自定义消息:
一般的自定义消息,可以通过模仿onbuttonclick消息的方法实现:
一般实现过程是:
定义 自定义消息
在头文件添加afx 函数,参数为wparm和lparm;
在cpp文件中的窗口的消息表BEGIN_MESSAGE_MAP中添加消息关联,
在cpp文件中实现函数;
但是这个过程有点麻烦,而且破坏了MFC的向导生成的代码,在VC6以后没有影响,只是不好看而已;
通过文章前面的描述,可以知道OnWndMsg虚函数接收处理所有的窗口消息,所以可以通过重载OnWndMsg函数,然后判断,如果消息等于自定义消息就直接处理;
这样程序会简明很多;
当然OnWndMsg中可以处理所有的Windows窗口消息,但是如果是Windows窗口消息,如果没有特殊处理,一般还是建议用添加消息函数的方法添加处理,就是在类的属性中添加相应的消息函数,不用将所有的消息处理放到OnWndMsg中;