16、深入浅出MFC学习笔记,事件与消息

简介: 一、基本概念 1、Windows程序的本质是基于消息的事件驱动。 Windows程序分为程序代码和UI资源两大部分。如图所示,资源的实际内容是二进制代码,借助各种工具产生。 在32位操作系统中不再有small/medium/large等内存模式之分。

一、基本概念

1Windows程序的本质是基于消息的事件驱动。

Windows程序分为程序代码和UI资源两大部分。如图所示,资源的实际内容是二进制代码,借助各种工具产生。

wps_clip_image-30469

32位操作系统中不再有small/medium/large等内存模式之分。LIBC.LIBC Runtime函数库的静态链接版本,MSVCRT.LIBC RunTime函数库动态链接版本的import函数库。

Windows消息分为两类(按输入):由硬件装置所产生的消息(如鼠标按下),放在系统队列(System Queue)中,以及由Windows系统或其它Windows程序传送过来的消息,放在程序队列(application queue)中。通过调用GetMessage API来取得消息,程序的生命靠它来推动。接受并处理消息的主角是窗口,每一个窗口都应当有一个窗口函数来负责处理消息。

wps_clip_image-30472

2、消息映射的雏形示例

    把窗口函数的内容设计得更模块化、更一般化的作法:

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

struct MSGMAP_ENTRY {
UINT nMessage;
LONG (*pfn)(HWND, UINT, WPARAM, LPARAM);
};
#define dim(x) (sizeof(x) / sizeof(x[0]))
    【注意 : pfn 是一个函数指针,我准备以此指针所指之函数处理 nMessage 消息。这正是对象导向观念中把「资料」和「处理资料的方法」封装起来的一种具体实现,只不过用的不是 C++ 语言。】

    接下来,组织两个数组_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 把其中的动作包装得更好更精致(当然因此也就更复杂得多),成为一张庞大的消息地图;程序一旦获得消息,就可以按图上溯,直到被处理为止。

3、对话框的运行

wps_clip_image-8325

wps_clip_image-2575

wps_clip_image-20443

参考

[1] 深入浅出MFC

[2] http://msdn.microsoft.com/en-us/library/0x0cx6b1%28VS.80%29.aspx

目录
相关文章
|
6月前
Qt第二课 核心机制信号槽
Qt第二课 核心机制信号槽
69 1
|
3月前
|
存储 前端开发 JavaScript
PixiJS源码分析系列:第四章 响应 Pointer 交互事件(上篇)
PixiJS源码分析系列:第四章 响应 Pointer 交互事件(上篇)
|
4月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
117 0
|
API
27 QT -消息机制与事件总结
27 QT -消息机制与事件总结
117 0
|
JavaScript
WebApi入门第三章(事件介绍及注册事件 )
WebApi入门第三章(事件介绍及注册事件 )
129 0
WebApi入门第三章(事件介绍及注册事件 )
|
API
9、QT基础——Qt消息机制和事件
9、QT基础——Qt消息机制和事件
437 0
9、QT基础——Qt消息机制和事件
怎样使用阿里云消息服务?
阿里云消息服务(Message Service)是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。 消息服务同时支持各种类型消息推送,其中和短信前后端的无缝整合更高效的为用户提供了大批量短信发送能力。