在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作。
比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应。

一、什么是消息?
   窗口消息一般由三个部分组成:1、一个无符号整数,是消息值;2、消息附带的WPARAM类型的参数;3、消
息附带的LPARAM类型的参数。其实,我们一般所说的消息是侠义上的消息值,也就是一个无符号整数,经常被定义为宏。

二、什么是消息映射机制?
   MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射
表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,
然后由消息处理函数进行相应的处理。

三、Windows消息分类
   Windows消息分为系统消息和用户自定义消息。Windows系统消息有三种:
   1、标准Windows消息。除WM_COMMAND以外WM_开头的消息是标准消息。例如,WM_CREATE、WM_CLOSE。
   2、命令消息。消息名为WM_COMMAND,消息中附带了标识符ID来区分是来自哪个菜单、工具栏按钮或加速键的消息。
   3、通知消息。通知消息一般由列表框等子窗口发送给父窗口,消息名称也是WM_COMMAND,其中附带了控件通知码
来区分控件。
   CWnd的派生类都可以接收到标准Windows消息、通知消息和命令消息。命令消息还可以由文档类等接收。
 用户自定义消息实际上就是用户定义一个宏作为消息,此宏的值应该大于等于WM_USER,然后此宏就可以跟系统消息
一样使用,窗口类中可以定义它的处理函数。

四、消息映射表
   除了一些没有基类的类或CObject的直接派生类外,其他的类都可以自动生成消息映射表。下面的讲解都以CMainFrame
为例。消息映射表如下:
C++代码:
 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_WM_CREATE()
    ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
  
    ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame:OnToolbarCreateNew)
    ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
    ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
    ON_WM_SETTINGCHANGE()
 END_MESSAGE_MAP()
   在BEGIN_MESSAGE_MAG和END_MESSAGE_MAP之间的内容成为消息映射入口项。消息映射除了在CMainFrame的实线文件中
添加消息映射表外,在类的定义文件MainFrame.h中还会添加一个宏调用:
   DECLARE_MESSAGE_MAP()
一般这个宏调用写在类定义的结尾处。

五、添加消息处理函数
   不管是自动添加还是手动添加都有三个步骤:
   1、在类定义中加入消息处理函数的函数声明,注意要以afx_msg打头。例如MainFrame.h中WM_CREATE的消息处理函数
声明:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
   2、在类的消息映射表中添加该消息的消息映射入口项。例如WM_CREATE的消息映射入口项:ON_WM_CREATE()。
   3、在类的实现中添加消息处理函数的函数实现。例如,MainFrm.cpp中WM_CREATE的消息处理函数的实现:
   int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
   {
      ......
   }
   通过以上三个步骤以后,WM_CREATE等消息就可以在窗口类中被消息处理函数处理了。

六、各种Windows消息的消息处理函数
   标准Windows消息的消息处理函数都与WM_CREATE消息类似。
   命令消息的消息映射入口项形式如:ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize),消息为
ID_VIEW_CUSTOMIZE,消息处理函数为OnViewCustomize。
   如果想要使用某个处理函数批量处理某些命令消息,则可以像CMainFrame消息映射表中的ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000,
ID_VIEW_APPLOOK_WINDWOS_7, &CMainFrame::OnApplicationLook)一样添加消息映射入口项,这样值在ID_VIEW_APPLOOK_WIN_2000到ID_VIEW_
APPLOOK_WINDOWS_7之间的菜单项等的命令消息都由CMainFrame的OnApplicationLook函数处理。函数原型为afx_msg void OnApplicationLook
(UINT id);参数id为用户操作的菜单项等的ID。
   在操作列表框等控件时往往会给父窗口发送WM_NOTIFY通知消息。WM_NOTIFY消息的wParam参数为发送通知消息的控件的ID,lParam参数指向
一个结构体,可能是NMHDR结构体,也可能是第一个元素为NMHDR结构体变量的其他结构体。NMHDR结构体的定义如下(仅作了解):
   Typedef struct tagNMHDR
   {
      HWND hwndFrom;
      UINT idFrom;
      UINT code;
   } NMHDR;
 hwndFrom为发送通知消息控件的句柄,idFrom为控件ID,code为要处理的通知消息的通知码,例如NM_CLICk。
 通知消息的消息映射入口项形式如:
   ON_NOTIFY(wNotifyCode, id, memberFxn)
 wNotifyCode为要处理的消息通知码,例如:NM_CLICK。id为控件标识ID。memberFxn为此消息的处理函数。
 通知消息的处理函数的原型为:
   afx_msg void memberFxn(NMHDR * pNotifyStruct, LRESULT *result);
 如果需要使用用户自定义消息,首先要定义消息宏,如:#define WM_UPDATE_WND(WM_USER+1),再到消息映射表中添加消息映射入口项:
  ON_MESSAGE(WM_UPDATE_WND, &CMainFrame::OnUpdateWnd),然后在MainFrm,h中添加消息处理函数的函数声明:afx_msg LRESULT OnUpdateWnd(
WPARAM wParam, LPARAM lParam);最后在MainFrm.cpp中实现此函数。
   本节对MFC消息映射机制只是做了比较简单的讲解,让大家对它有一定的认识,编程入门这不必强求完全掌握。在以后的教程中会经常涉及
到消息的使用,大家会逐渐熟悉MFC的消息映射机制。

MFC编程入门之五(MFC消息映射机制概述)的更多相关文章

  1. VS2010/MFC编程入门之五(MFC消息映射机制概述)

    VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...

  2. VS2010-MFC(MFC消息映射机制概述)

    转自:http://www.jizhuomi.com/software/147.html 前面已经说过,Windows应用程序是消息驱动的.在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息 ...

  3. VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen)

    上一节中鸡啄米讲了CDC类及其屏幕绘图函数,本节的主要内容是GDI对象之画笔CPen. GDI对象 在MFC中,CGdiObject类是GDI对象的基类,通过查阅MSDN我们可以看到,CGdiObje ...

  4. 图解MFC基本框架(深入消息映射机制)

    首先,先看整体的消息流向图: 上图解释: 起点是消息循环,在winmain函数中(mfc中winmain函数是隐含的调用的,在app全局对象构造完后紧接着调用winmain函数),while循环中不断 ...

  5. VS2010/MFC编程入门之五十二(Ribbon界面开发:创建Ribbon样式的应用程序框架)

    上一节中鸡啄米讲了GDI对象之画刷CBrush,至此图形图像的入门知识就讲完了.从本节开始鸡啄米将为大家带来Ribbon界面开发的有关内容.本文先来说说如何创建Ribbon样式的应用程序框架. Rib ...

  6. VS2010/MFC编程入门之五十一(图形图像:GDI对象之画刷CBrush)

    上一节中鸡啄米主要讲的是画笔CPen的用法,前面也说了,GDI对象中最常用的就是画笔和画刷,本节就讲讲画刷CBrush. 鸡啄米依然是通过实例的方式来说明画刷的用法.此实例要实现的功能是,对话框上有一 ...

  7. VS2010/MFC编程入门之五十三(Ribbon界面开发:为Ribbon Bar添加控件)

    前面一节中鸡啄米为大家简单介绍了如何创建Ribbon样式的应用程序框架,本节教程就来初步讲讲怎样为Ribbon Bar添加Ribbon控件. VS2010为Ribbon界面开发提供了Ribbon De ...

  8. VS2010/MFC编程入门之五十四(Ribbon界面开发:使用更多控件并为控件添加消息处理函数)

    上一节中鸡啄米讲了为Ribbon Bar添加控件的方法.本节教程鸡啄米将继续完善前面的实例,讲解一些稍复杂的控件的添加方法,及如何为它们添加消息处理函数. 一.为Ribbon Bar添加更多Ribbo ...

  9. VS2010/MFC编程入门教程之目录和总结

    鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...

随机推荐

  1. preparedStatement和Statement 有什么不一样

    1. PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象.    2.作 ...

  2. Linux/Unix里,ln -s

    这是硬/软链接的命令ln -s 是创建软链接ln 是创建硬链接 你可以理解为:相当于windows下创建快捷方式一样,所以就不用太多解释了吧. ln -s /usr/lib/libX11.3 libX ...

  3. IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法

    IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法 IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrl ...

  4. N-gram介绍

    在实际应用中,我们经常需要解决这样一类问题:如何计算一个句子的概率?如: 机器翻译:P(high winds tonite) > P(large winds tonite) 拼写纠错:P(abo ...

  5. Android Context完全解析

    Context类型 我们知道,Android应用都是使用Java语言来编写的,那么大家可以思考一下,一个Android程序和一个Java程序,他们最大的区别在哪里?划分界限又是什么呢?其实简单点分析, ...

  6. [转]人人网首页拖拽上传详解(HTML5 Drag&Drop、FileReader API、formdata)

    人人网首页拖拽上传详解(HTML5 Drag&Drop.FileReader API.formdata) 2011年12月11日 | 彬Go 上一篇:给力的 Google HTML5 训练营( ...

  7. android 入门 002 (拨打电话,发送短信)

    一.拨打电话 1.首先做好界面,代码如下: layout =>activity_main.xml 中 <LinearLayout xmlns:android="http://sc ...

  8. SqlSever基础 right函数 从右边开始,截取字符串

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  9. (转)C# Winform应用程序占用内存较大解决方法整理

    背景: 微软的 .NET FRAMEWORK 现在可谓如火如荼了.但是,.NET 一直所为人诟病的就是“胃口太大”,狂吃内存,虽然微软声称 GC 的功能和智能化都很高,但是内存的回收问题,一直存在困扰 ...

  10. CentOS系统下各文件夹的作用

    linux下的文件结构,看看每个文件夹都是干吗用的 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的 ...