zoukankan      html  css  js  c++  java
  • VC++学习笔记之MFC消息映射机制

    1、MFC消息映射机制的具体实现方法是:在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,即消息映射表。在消息映射表中,消息与对应的消息函数指针是成对出现的。某个类能处理的所有消息及其对应的消息处理函数的地址都列在这个类所对应的静态表中。当有消息需要处理时,程序只要搜索该消息静态表,查看表中是否含有该消息,就可知道该类能否处理此消息。如果能处理该消息,则同样依照静态表能很容易找到并调用对应的消息处理函数。

    2、MFC消息映射机制处理有三处相关信息:函数原型、函数实现,以及用来关联消息和消息响应函数的宏。其中,函数原型是在类的头文件中,在注释宏之间;函数实现在类的源文件处,是消息响应函数的实现代码;消息映射宏在类的源文件处,在两个AFX_MSG_MAP注释宏之间,通过这个宏把消息与消息响应函数关联起来。

    3、代码实例

    第一部分“DrawView.h”头文件,“函数原型声明”
    //DrawView.h : interface of the CDrawView class
    //
    ////////////////////////////////////////////////////////////

    class CDrawView : public CView
    {
            protected: //  create from serialization only
                  CDrawView();
                  DECLARE_DYNCREATE()
            ...................................
           
            //Generated message map funtions
            protected:
                   //{{AFX_MSG(CDrawView)
                        afx_msg  void OnLButtonDown(UINT  nFlags , CPoint  point);  //函数原型声明
                   //}}AFX_MSG
                   DECLARE_MESSAGE_MAP()
    }

    第二部分“DrawView.cpp”中的“消息映射宏”和“消息响应函数”
    //DrawView.cpp :  implementation of the CDrawView class

    IMPLEMENT_DYNCREATE(CDrawView, CView)

    BEGIN_MESSAGE_MAP(CDrawView , CView)
         //{{AFX_MSG_MAP(CDrawView)
         ON_WM_LBUTTONDOWN()  //消息映射宏
        //}}AFX_MSG_MAP

         //Standard printing commands
         ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)
    END_MESSAGE_MAP()

    //CDrawView message handlers
    void CDrawView : : OnLButtonDown(UINT nFlags , CPoint point)   //消息响应函数的实现
    {
           //   TODO: Add your message handler code here and/or call default
           MessageBox("View Clicked!");
           CView::OnLButtonDown(nFlags,point);
    }

    4、MFC消息映射机制的实际实现过程
         (1)MFC在后台维护了一个窗口句柄与对应的C++对象指针的对照表。窗口有一个句柄,该句柄与CDrawView对象的一个指针(即 CDrawVew*)存在着一一对应关系,在C++对象对照表中维护了这种对应关系。当收到消息,消息的第一个参数就是句柄参数。获取窗口句柄后,根据对照表找到与之相关的C++对象指针。然后将指针传递给应用程序框架窗口类的基类,改基类会调用一个名为WindowProc的函数。
         (2)其实WindowProc函数只是一个虚函数。在它内部调用了一个OnWndMsg函数,该函数完成了真正的消息路由,也就是真正的完成了消息映射。该函数位于WinCore.cpp文件中。
         (3)OnWndMsg函数的处理过程:
                   首先判断消息是否有消息响应函数。判断方法是根据窗口子类指针,在子类的头文件中查找看看DECLARE_MESSAGE_MAP()宏之上,两个AFX_MSG注释之间是否具有相应的响应函数原型的声明;再到子类的源文件中,看看BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()这两个宏之间是否有相应的消息映射宏。如果通过消息映射宏找到了消息响应函数,那么就调用该响应函数,对消息进行处理。如果没有找到,则由基类处理。

     本片文章参考了《VC++深入理解》(孙鑫老师)

    朋友,如果您有什么真知灼见,可以加“新浪微博”/MSN哦,starrycheng@live.com,我们大家一起讨论,一起研究。

    最后,帮忙加一分吧,想整个空间系统。

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/ssol/p/2260152.html
Copyright © 2011-2022 走看看