Windows消息分类
Windows中,消息被分为以下三类:
第一类:标准消息
除了WM_COMMAND之外,所有的WM_开头的消息都是标准消息。从CWnd派生的类,都可以接收这类消息。例如WM_CHAR、WM_CLOSE,其对应的消息映射宏分别是ON_WM_CHAR()、ON_WM_CLOSE();
第二类:命令消息
来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND形式呈现。在MFC中,通过菜单项的ID来区分不同的命令消息,从CCmdTarget派生的类,都可以接收这类消息,其消息映射宏形式如下:ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
第三类:通告消息
由控件产生的消息,例如按钮的单击、列表框的选择等都会产生这类消息,目的是为了向其父窗口(通常是对话框)通知事件的产生。这类消息也是以WM_COMMAND形式呈现的。从CCmdTarget派生的类,都可以接收这类消息。通告消息的命名规律:
列表框:LBN_****
组合框:CBN_****
TAB框:TBN_****
按钮 : BN_****
Edit : EN_****
其消息映射宏形式如下:
ON_LBN_DBLCLK(<id>, <memberFxn> ) ON_CBN_KILLFOCUS(<id>, <memberFxn> ) ON_BN_DOUBLECLICKED( <id>,<memberFxn> )
OnCommand路由函数
当用户从菜单选中一个命令项目、当一个控件发送通知消息给去父窗口或者按下一个快捷键将发送 WM_COMMAND 消息,并由OnCommand函数完成消息的路由,其函数声明如下:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
该函数的两个参数,总结如下:
我们可以利用OnCommand函数完成消息的截获:
我们在"菜单命令消息路由过程分析"中已经知道消息的响应顺序是:视类->文档类->框架类->应用程序类。
下面举例给出框架类如何截获视类的消息响应过程:
第一步:添加视类消息响应函数
我们在菜单栏中添加"Test"菜单,并添加消息响应函数,该消息响应函数如下:
void CMenu2View::OnTest() { // TODO: 在此添加命令处理程序代码 MessageBox("View Test"); }运行效果:
第二步:添加框架类的OnCommand函数
我们利用MFC提供的向导在CMainFrame中重写OnCommand函数,这时视类就不会再响应消息了,其代码如下:
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 int MenuCmdID = LOWORD(wParam); CMenu2View*pView = (CMenu2View*)GetActiveView(); //仅截获Test菜单响应 if (MenuCmdID == IDM_TEST) { MessageBox("mainframe receive cmd"); //路由结束 return TRUE; } return CFrameWnd::OnCommand(wParam, lParam); }运行效果: