MFC 消息映射(Message Map)的雏形

在面向过程的窗口消息处理函数WndProc中,我们要使用大量的 switch+case 来判断处理消息,这使得代码变得杂乱。若在项目开发中,每个人都要使用消息处理机制,这使得代码不易管理。而在MFC中提供了一种消息映射机制,这种机制使得窗口接收消息和处理消息的函数分开来写,使得在面向对象设计中消息处理的过程明朗化。那么它是如何实现的呢?

首先,定义一个MSGMAP_ENTRY 结构和一个dim 宏:

struct MSGMAP_ENTRY {

UINT nMessage;

LONG (*pfn)(HWND, UINT, WPARAM, LPARAM);

};

#define dim(x) (sizeof(x) / sizeof(x[0]))

MSGMAP_ENTRY 的第二元素pfn 是一个函数指针,此函数处理nMessage 消息。

接下来组织两个数组_messageEntries[ ] 和_commandEntries[ ],把程序中欲处理的消息以及消息处理例程的关联性建立起来:

// 消息与处理例程之对照表格
struct MSGMAP_ENTRY _messageEntries[] =
{
WM_CREATE, OnCreate,
WM_PAINT, OnPaint,
WM_SIZE, OnSize,
WM_COMMAND, OnCommand,
WM_SETFOCUS, OnSetFocus,
WM_CLOSE, OnClose,
WM_DESTROY, OnDestroy,
} ;    ↑            ↑
这是消息    这是消息处理例程
// Command-ID 与处理例程之对照表格
struct MSGMAP_ENTRY _commandEntries =
{
IDM_ABOUT, OnAbout,
IDM_FILEOPEN, OnFileOpen,
IDM_SAVEAS, OnSaveAs, 
} ;    ↑                ↑  
WM_COMMAND 命令项         这是命令处理例程

窗口函数可以这么设计

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int i;
for(i=0; i < dim(_messageEntries); i++) { // 
if (message == _messageEntries[i].nMessage)
return((*_messageEntries[i].pfn)(hWnd, message, wParam, lParam));
}
return(DefWindowProc(hWnd, message, wParam, lParam));
}
//---------------------------------------------------------------------- 
// OnCommand -- 专门处理WM_COMMAND
//----------------------------------------------------------------------
LONG OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int i;
for(i=0; i < dim(_commandEntries); i++) {  // 
if (LOWORD(wParam) == _commandEntries[i].nMessage)
return((*_commandEntries[i].pfn)(hWnd, message, wParam, lParam));
}
return(DefWindowProc(hWnd, message, wParam, lParam));
}
//----------------------------------------------------------------------
LONG OnCreate(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
...
}
//----------------------------------------------------------------------
LONG OnAbout(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
...
}
//----------------------------------------------------------------------

这么一来,WndProc 和OnCommand 永远不必改变,每有新要处理的消息,只要在_messageEntries[ ] 和_commandEntries[ ] 两个数组中加上新元素,并针对新消息撰写新的处理例程即可。

这种观念以及作法就是MFC 的Message Map 的雏形。MFC 把其中的动作包装得更好更精致(当然因此也就更复杂得多),成为一张庞大的消息地图;程序一旦获得消息,就可以按图上溯,直到被处理为止。

赞(0) 打赏
取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

    暂无评论...