MFC 的消息处理

mfc消息处理和消息映射的概念   关键词: MFC                                               1、消息处理和消息映射的概念    2、消息种类    3、常用消息    4、消息处理函数    5、消息映射    所有windows应用程序都是消息驱动的,消息处理是所有windows应用程序的核心部分。当用户单击鼠标或改变窗口大小时,都将给适当的窗口发送消息。每个消 阅读详情
 何谓消息、消息处理函数、消息映射?
消息简单的说就是指通过输入设备向程序发出指令要执行某个操作。具体的某个操作是你的一系列代码。称为消息处理函数。在SDK中消息其实非常容易理解,当窗口建立后便会有一个函数(窗口处理函数)开始执行一个消息循环,我们还可以清楚的看到消息处理的脉络。一个switch case语句就可以搞定,消息循环直到遇到WM_QUIT消息才会结束,其余的消息均被拦截后调用相应的处理函数。但在封装了API的MFC中,消息似乎变的有些复杂了,我们看不到熟悉的switch case语句了,取而代之的是一个叫消息映射的东西。为什么MFC要引入消息映射机制,你可以想象一下,在现在的程序开发活动中,你的一个程序是否拥有多个窗体,主窗口就算只有一个,那菜单、工具条、控件这些都是子窗口,那我们需要写多少个switch case,并且还要为每个消息分配一个消息处理函数,这样做是多么的复杂呀。因此MFC采用了一种新的机制。利用一个数组,将窗口消息和相对应的消息处理函数进行映射,你可以理解成这是一个表。这种机制就是消息映射。这张表在窗口基类CWnd定义,派生类的消息映射表如果你没有动作它是空的,也就是说如果你不手工的增加消息处理函数,则当派生窗口接受一个消息时会执行父类的消息处理函数。这样做显然是高效的。
MFC提供的消息结构
同时MFC定义了下面的两个主要结构:
AFX_MSGMAP_ENTRY
struct AFX_MSGMAP_ENTRY{
UINT nMessage;   // Windows消息的ID号
UINT nCode;  // 控制消息的通知
UINT nID;    // Windows控制消息的ID
UINT nLastID;   //表示是一个指定范围的消息被映射的范围
UINT nSig;  //表示消息的动作标识
AFX_PMSG pfn;    // 指向消息处理函数的指针
};
AFX_MSGMAP
struct AFX_MSGMAP{
#ifdef _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
};
///AFX_MSGMAP可以得到基类的消息映射入口地址和得到本身的消息映射入口地址。

MFC下一个消息的处理过程是一般是这样的。
1、_AfxCbtFilterHook截获消息(这是一个钩子函数)
2、_AfxCbtFilterHook把窗口过程设定为AfxWndProc。
3、函数AfxWndProc接收Windows操作系统发送的消息。
4、函数AfxWndProc调用函数AfxCallWndProc进行消息处理。
5、函数AfxCallWndProc调用CWnd类的方法WindowProc进行消息处理。

如何添加自己的消息?
我们已经了解了WINDOW的消息机制,如何加入我们自己的消息呢?好我们来看
一个标准的消息处理程序是这个样子的
在 CWnd 类中预定义了标准 Windows 消息 (WM_XXXX  WM是WINDOW MESSAGE的缩写) 的默认处理程序。类库基于消息名命名这些处理程序。例如,WM_PAINT 消息的处理程序在 CWnd 中被声明为:
afx_msg void OnPaint();
afx_msg 关键字通过使这些处理程序区别于其他 CWnd 成员函数来表明 C++ virtual 关键字的作用。但是请注意,这些函数实际上并不是虚拟的,而是通过消息映射实现的。我们在本文的一开始便说明了为什么要这样做。
所有能够进行消息处理的类都是基于CCmdTarget类的,也就是说CCmdTarget类是所有可以进行消息处理类的父类。CCmdTarget类是MFC处理命令消息的基础和核心。

若要重写基类中定义的处理程序,只需在派生类中定义一个具有相同原型的函数,并创建此处理程序的消息映射项。我们通过ClassWizard可以建立大多数窗口消息或自定义的消息,通过ClassWizard可以自动建立消息映射,和消息处理函数的框架,我们只需要把我们要做的事情填空,添加你要做的事情到处理函数。这个非常简单,就不细说了。但是也许我们需要添加一些ClassWizard不支持的窗口消息或自定义消息,那么就需要我们亲自动手建立消息映射和消息处理的框架,通常步骤如下:
第一步:定义消息。Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。
#define WM_MYMESSAGE (WM_USER + 100)

第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。
LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息,填空就是要填到这里。
return 0;
}
第三步:在类头文件的AFX_MSG块中说明消息处理函数:
// {{AFX_MSG(CMainFrame)
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。
ON_MESSAGE( WM_MYMESSAGE, OnMyMessage )

可以看出,用户自定义的消息和我们通过ClassWizard添加的消息一样,都是利用了ON_MESSAGE宏,建立的消息映射。

其实消息类别可以分成多种,上面说的只是其中之一。有三种主要的消息类别:(以下部分摘自MSDN)
1、Windows 消息
此类消息主要包括以前缀 WM_ 开头的消息,WM_COMMAND 除外。Windows 消息由窗口和视图处理。此类消息往往带有用于确定如何处理消息的参数。
2、控件通知
此类消息包括从控件和其他子窗口发送到其父窗口的 WM_COMMAND 通知消息。例如,当用户在编辑控件 (Edit Control) 中执行可能更改文本的操作后,该编辑控件 (Edit Control) 将向其父级发送包含 EN_CHANGE 控件通知代码的 WM_COMMAND 消息。该消息的窗口处理程序以某种适当的方式响应此通知消息,例如在控件中检索该文本。
框架像传送其他 WM_ 消息一样传送控件通知消息。但是有一个例外的情况,即当用户单击按钮时由按钮发送的 BN_CLICKED 控件通知消息。该消息被作为命令消息特别处理,并像其他命令一样传送。
3、命令消息
此类消息包括用户界面对象(菜单、工具栏按钮和快捷键)发出的 WM_COMMAND 通知消息。框架处理命令的方式与处理其他消息不同,可以使用更多种类的对象处理命令。
Windows 消息和控件通知消息由窗口来处理(窗口是从 CWnd 类派生的类的对象)。包括 CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView、CDialog 以及从这些基类派生的您自己的类。这些对象封装了 HWND——Windows 窗口的句柄。
命令消息可以由范围更广的对象(文档、文档模板以及应用程序对象本身)处理,而不仅仅由窗口和视图处理。当某一命令直接影响到某个特定对象时,应当让该对象处理此命令。例如,“文件”菜单中的“打开”命令在逻辑上与应用程序相关联:该应用程序接收到此命令时会打开指定的文档。因此“打开”命令的处理程序是应用程序类的成员函数。

命令消息我们比较常见的便是菜单项和工具条了,大家可以看到他的消息映射宏和窗口消息不太一样,一般的形式是这样的
ON_COMMAND(id,memberFxn)
第一个参数是命令ID,一个ID号对应一个消息处理,当然你可以让多个ID共用一个处理函数。常见的应用例如:菜单项打开文档的ID和工具条按钮打开文档的ID同时使用一个处理函数,或者直接将它们的ID设成相同的。

还有一种消息叫通知消息。例如树型控件的等一些复杂的控件在单击后需要传递更多的信息,例如光标的位置和当前项的一个结构,所以MFC为控件的每个通知消息也定义了一个宏,它长成了这个样子:
ON_CONTROL(EN_CHANGE,id,memberFxn)

还有很多种消息存在于MFC,宏定义有区别,大家可以触类旁通。

窗口消息有上百个。你可以从MSDN上查到WM_开头的,或者查看CWnd的成员函数,会给你列出很多,别忘了还有很多非窗口消息。雷神无法一一列出,也没有必要。大家查一下就行了。不过对一些常用的、新的控件消息和特殊的通知消息我还是把他们列出几个表,大家做个参考吧。
MFC消息处理学习总结 Windows消息机制概述 http://www.cppblog.com/suiaiguo/archive/2009/07/18/90412.html 消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉。一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用程序某个事情发生了。例如,单击鼠标 阅读详情

相关推荐

MFC消息机制

MFC消息机制

weixin_47328424的博客 1223

MFC原理与方法(二)

MFC原理与方法(二)一、前言二.类向导的使用三、MFC消息管理(1).MFC消息映射机制(3).消息处理 一、前言 时间过得好快啊,又是一个星期过去了! 二.类向导的使用 类向导是一个很好的工具,我们可以通过类向导来快速添加生成消息处理函数。但是,你可能会在第一次使用类向导的时候会报错。错误如下。 这是因为文件的缺失导致的,只需要把C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin目录下的RcDll.Dll文件复制到C:\Program Fil

a2748786010的博客 2032

windows消息机制(MFC

windows消息机制(MFC) 消息分类与消息队列 Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型, 而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样。 time表示产生消息的时间,pt表示产生消息时鼠标的位置。 按照类型,Windows将消息分为: (0) 消息ID范围 系统定...

u011555996的博客 1162

MFC的消息机制

今天重新整理MFC的消息机制,最终的结果应该是利用win32程序模拟一个MFC的消息链。 1.标准消息  除WM_COMMAND之外,所有以WM_开头的消息。 从CWnd派生的类,都可以接收到这类消息。  2.命令消息  来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。 CCmdTarget派生的类,都可以接收到这类消息。  3.通告消息 由控件产生的消息,例

luhouxiang的专栏 9711

MFC】消息机制

1.Windows消息机制 Windows应用程序是通过消息驱动的,在MFC软件开发时,进行界面操作经常要用到消息,通过消息对应的处理函数来实现响应的操作。比如,用户操作窗口,就会产生消息,送给对应的消息处理函数进行处理,对用户的操作做出一些反应。 2.MFC消息映射 MFC使用消息映射机制来处理消息,具体表现就是消息和消息处理函数一一对应的消息映射表,以及消息处理函数的声明和是实现。当窗口收到消息时,会在消息映射表中寻找对应的处理函数,然后由消息处理函数做出相应的处理。 3.自定义消息的方法 M

summersneverdie的博客 2453

MFC中的消息处理函数

1、在Windows API编程中,直接在消息处理函数中编写WM_PAINT处理代码。 2、在MFC中,CFrameWnd的消息处理过程在哪里呢?MFC时如何将消息处理函数和窗口关联起来的。   在CFrameWnd::CreateEx中,调用PreCreateWindows来注册窗口。   AfxDefRegisterClass(AFX_WNDFRAMEORVIEW_REG):注册一个固定...

u011555996的博客 1875

MFC消息处理

MFC消息讲解

keyouan2008的专栏 826

MFCMFC消息处理和映射

00. 目录 文章目录00. 目录01. 概述02. 框架中的消息和命令2.1 消息2.2 消息处理程序2.3 消息类别2.4 映射消息2.5 命令ID2.6 标准命令2.7 命令目标03. 框架如何调用处理程序3.1 消息发送和接收3.2 非命令消息如何到达其处理程序3.3 命令路由3.4 命令路由示例3.5 OnCmdMsg 处理程序3.6 重写标准命令传送04. 框架如何搜索消息映射4.1 消息映射的位置4.2 派生消息映射05. 声明消息处理程序函数5.1 标准 Windows 消息的处理程序5.2

C/C++软件工程师、嵌入式软件工程师、物联网研发工程师、C/C++讲师、物联网讲师、嵌入式讲师、鸿蒙讲师---欢迎大家一起交流(私信添加博主微信) 2047

MFC消息处理流程概述

Win32下的消息流程清晰明了,但在MFC下,由于封装的缘故,隐藏的有点深,对一般的开发人员而言,就不甚明了喽。本文试图粗略展示出MFC消息处理的基本流程。 一、先看一下Win32下的消息处理流程 每一个线程都对应有一个消息队列,利用API函数GetMessage从消息队列中获取消息,然后利用TranslateMessage翻译消息(主要是一些键盘消息),再利用Dispatc

Hisin Wang的专栏 1万+

MFC 新增消息处理函数

     在MFC中添加一个消息处理函数的方法有(比如在CxxxView类中):1.在CxxxView类上点右键,选择add windows message handler, 选择消息类型,点Add Handler,然后点击Edit Exiting 。2.在菜单栏,查看,建立类向导,选择项目名,类名,消息类型,点“Add Function”,"Edit code"。 这两种方法

张国鹏的专栏 1142

MFC消息处理的封装

1`、采用MFC的宏将消息映射到C++成员函数的方式中以避免产生宏大的虚拟函数分配表2、MFC应用程序框架含有一个从CWINAPP派生的应用程序类对象,成员函数RUN()被隐含调用(1)这个CWINAPP派生的应用程序类类对象调用的CWINTRHEAD类成员函数RUN()方法完成同WINMAIN()类似的消息循环处理(2)CWINTRHEAD类成员函数RUN()的RUN方法调用了Get

深未来技术 705

MFC消息处理与消息映射机制

MFC中,框架类(CFrameWnd)代表着Windows中一个窗口,它负责窗口的注册和创建,并可以将控件包括按钮、菜单、工具栏等都可以挂载在CFrameWnd中。它功能非常强大,管理着窗口的一切。本文将通过pFrame来详细研究MFC是如何进行消息处理的。

qq_43725310的博客 3491

MFC程序的消息处理顺序

MFC应用程序中处理消息的顺序       1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc       2.AfxCallWndProc()        该函数负责保存消息(保存的内容主要是消息

W Blog 1066

MFC消息处理函数

MFC消息处理函数 1.AfxWndProc()       该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc()   该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,然后调用WindowProc()函数 3.WindowProc()       该函数负责发送消息到OnWndMsg()函数

weicomm的专栏 1088

MFC中添加消息处理函数的步骤

如何在MFC中添加消息处理函数呢,不管是手动还是自动添加,大体上有下面三个步骤。 1、在类应用中添加消息处理函数的声明,以基于对话框的应用为例,在XXXDlg.h(XXX是工程的名字)文件中添加类似如下的声明: afx_msg  void  OnPaint(); //可以有参数也可以有返回值,这个视需求而定。当然,这里的OnPaint()是内置的绘图函数,没有返回值也没有参数。 2、在类的

liqiming100的专栏 5075

MFC消息处理函数

1.AfxWndProc() 该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc() 该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,然后调用WindowProc()函数 3.WindowProc() 该函数负责发送消息到OnWndMsg()函数,如果未被处理,则调用DefWindowProc()函数 4.OnWndMsg() 该函数的功能首先按字节对消息进行排序,对于WM_COMMAND

远在远方的风比远方更远 1052

添加消息处理函数或重载MFC

目标在类中,添加一个消息处理函数或者重载一个M F C成员函数。策略首先,用Class Wi z a r d自动地添加一个消息处理函数或重载成员函数;然后,讨论当需要的处理函数或重载函数在Class Wi z a r d指令系统的外面时,怎样手工完成该工作。步骤1. 利用Class Wi z a r d添加消息处理函数或重载类1) 单击Developer Studio的View/Class W

water-king fly的专栏 2933
上一篇: 如何使用SendMessage自定义消息函数(VC实例)
下一篇: 用CreateThread()创建线程
wesleyluo
博客等级 码龄19年 292粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值