以下摘自侯捷《深入浅出MFC》
MFC 把消息主要分为三大类,Message Map 机制中对于消息与函数间的对映关系也明定
以下三种:
■ 标准Windows 消息(WM_xxx)的对映规则:
宏名称 对映消息 消息处理函数(名称已由系统预设)
ON_WM_CHAR
WM_CHAR On
ON_WM_CLOSE
WM_CLOSE On
ON_WM_CREATE
WM_CREATE On
ON_WM_DESTROY
WM_DESTROY On
ON_WM_LBUTTONDOWN
WM_LBUTTONDOWN On
ON_WM_LBUTTONUP
WM_LBUTTONUP On
ON_WM_MOUSEMOVE
WM_MOUSEMOVE On
ON_WM_PAINT
WM_PAINT On
■ 命令消息(WM_COMMAND)的一般性对映规则是:
ON_COMMAND(<id>,<memberFxn>)
例如:
ON_COMMAND(IDM_ABOUT, On
ON_COMMAND(IDM_FILENEW, On
ON_COMMAND(IDM_FILEOPEN, On
ON_COMMAND(IDM_FILESAVE, On
■ 「Notification 消息」(由控制组件产生,例如BN_xxx)的对映机制的宏分
为好几种(因为控制组件本就分为好几种),以下各举一例做代表:
控制组件 宏名称 消息处理函数
Button ON_BN_CLICKED(<id>,<memberFxn>) memberFxn
ComboBox ON_CBN_DBLCLK(<id>,<memberFxn>) memberFxn
Edit ON_EN_SETFOCUS(<id>,<memberFxn>) memberFxn
ListBox ON_LBN_DBLCLK(<id>,<memberFxn>) memberFxn
程序的诞生:
■ Application object 产生,内存于是获得配置,初值亦设立了。
■ Afx WinMain 执行AfxWinInit,后者又调用AfxInitThread,把消息队列尽量加大到96。
■ Afx WinMain 执行InitApplication。这是CWinApp 的虚拟函数,但我们通常不改写它。
■ AfxWinMain 执行InitInstance。这是CWinApp 的虚拟函数,我们必须改写它。
■ CMyWinApp::InitInstance 'new' 了一个CMyFrameWnd 对象。
■ CMyFrameWnd 构造式调用Create,产生主窗口。我们在Create 参数中指定的
窗口类别是NULL, 于是MFC 根据窗口种类, 自行为我们注册一个名为
"AfxFrameOrView42d" 的窗口类别。
■ 回到InitInstance 中继续执行ShowWindow,显示窗口。
■ 执行UpdateWindow,于是发出WM_PAINT。
■ 回到AfxWinMain,执行Run,进入消息循环。
程序开始运作:
■ 程序获得WM_PAINT 消息(藉由CWinApp::Run 中的::GetMessage 循环)。
■ WM_PAINT 经由::DispatchMessage 送到窗口函数CWnd::DefWindowProc 中。
■ CWnd::DefWindowProc 将消息绕行过消息映射表格(Message Map)。
■ 绕行过程中发现有吻合项目,于是调用项目中对应的函数。此函数是应用程序
利用BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间的宏设立起来的。
■ 标准消息的处理例程亦有标准命名,例如WM_PAINT 必然由On
以下是程序的死亡:
■ 使用者选按【File/Close】,于是发出WM_CLOSE。
■ CMyFrameWnd 并没有设置WM_CLOSE 处理例程,于是交给预设之处理例程。
■ 预设函数对于WM_CLOSE 的处理方式是调用::DestroyWindow, 并因而发出
WM_DESTROY。
■ 预设之WM_DESTROY 处理方式是调用::PostQuitMessage,因此发出WM_QUIT。
■ CWinApp::Run 收到WM_QUIT 后会结束其内部之消息循环, 然后调用
ExitInstance,这是CWinApp 的一个虚拟函数。
■ 如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所调用的就是
CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance。
■ 最后回到AfxWinMain,执行AfxWinTerm,结束程序。
评论