SDK代码的优化和消息机制的进一步学习

来源:互联网 发布:mysql授权远程访问 编辑:程序博客网 时间:2024/06/06 00:55

今天看了下 深入浅出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[ ] 两个阵列新元素,并针对新消息撰写新

的处理常式即可。