今天看了下 深入浅出MFC 的第一章,写的还真不错
什么都不用说,以前还多东西看文字看得我晕晕的,还没搞明白
今天看另一一下上面的图解,真柳暗花明啊!
编译于连接的图解:
消息发送与处理图解:
函数与资源的连接调用:
函数代码的优化:
其实也没什么好说的,看代码比什么文字描述都强
下面那段就是优化后的代码
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
...
}
//--------------------------------------------------
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
...
return (RegisterClass(&wc));
}
//--------------------------------------------------
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
_hWnd = CreateWindow(...);
...
}
消息映射的邹行(Message Map):
有没有可能把窗口函数的內容设计得更模块化、更一般化些?下面是一种作法。请注意,
以下作法是MFC「消息映射表格」的邹形,所采用的结构名称和变量名称,
都于 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[ ] 两个阵列中加上新元素,并针对新消息撰写新
的处理常式即可。