【MFC】07.MFC第三大机制:消息映射-笔记

本专栏上两篇文章分别介绍了【MFC】05.MFC第一大机制:程序启动机制【MFC】06.MFC第二大机制:窗口创建机制,这篇文章来为大家介绍MFC的第三大机制:消息映射

  • typfd要实现消息映射,必须满足的三个条件:

    类必须继承于CmdTargert

    类必须声明重定义 DECLARE_MESSAGE_MAP

    类外必须实现DEGIN_MESSINGE_MAP()

    END_MESSAGE_MAP()

    c_cpp 复制代码
    自己的窗口类{
      LERESULT onCreate(WPARAM wParam,LPARAM lParam){
      AfxMessageBox("WM_CREATE");
      }
      
      //定义宏:
      DECLARE_MESSAGE_MAP()
    }
    
    //类外实现消息映射:
    BEGIN_MESSAGE_MAP(cMyFrameWnd,CFrameWnd)
      ON_MESSAGE(WM_CREATE,onCreate);
    END_MESSAGE_MAP()
  • 在Win32程序中封装消息:

    我们定义一张映射表,当进入WndProc的时候,通过查找这张表的映射关系,来执行对应的函数:

    c_cpp 复制代码
    typedef struct MESSAGE_ENTRY{
      int message;
      int (*pFun)(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
    }
    struct MESSAGE_ENTRY MessageMap[]{
      映射容器:
      WM_PAINT,函数地址
    }

MFC的消息映射机制:

  • 宏展开:

    c_cpp 复制代码
    DECLARE_MESSAGE_MAP(){
      //静态函数
      static const AFX_MSGMAP* PASCAL GetThisMessageMap();
      //虚函数
        virtual const AFX_MSGMAP* GetMessageMap() const;
    }
    
    实现宏展开:
    DECLARE_MESSAGE_MAP(){
      //静态函数
      static const AFX_MSGMAP* PASCAL GetThisMessageMap();
      //虚函数
    	virtual const AFX_MSGMAP* GetMessageMap() const;
    }
    
    BEGIN_MESSAGE_MAP(CMFCApplication1App, CWinApp){
        //这里是实现虚函数,
      	const AFX_MSGMAP* theClass::GetMessageMap() const 
      		{ 
      		  return GetThisMessageMap();
      		} 
      		
      	const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
      	{ \
      		typedef theClass ThisClass;
      		typedef baseClass TheBaseClass;
      		static const AFX_MSGMAP_ENTRY _messageEntries[] = 
      		{
        		{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
      	 }; 
      		static const AFX_MSGMAP messageMap = 
      		{ &TheBaseClass::GetThisMessageMap,//我们的弗雷德静态函数地址
      		&_messageEntries[0] };//本类消息结构体的数组首地址
      		return &messageMap;
      	}			
    }

我们来看看struct AFXmMSGMAP_ENTRY结构体:

c_cpp 复制代码
struct AFX_MSGMAP_ENTRY
{
    UINT nMessage;   //消息ID
    UINT nCode;      //win32通知码 
    UINT nID;        //命令ID WM_COMMAND 菜单 按钮 快捷键 加速键  1000
    UINT nLastID;    //最后ID                                       1004
    UINT_PTR nSig;   //处理消息的类型
    AFX_PMSG pfn;    //我们的处理消息的函数地址
};

消息回调:

c_cpp 复制代码
LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
    CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
    AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
    {
         pWnd->WindowProc(nMsg, wParam, lParam)
         {
            OnWndMsg(message, wParam, lParam, &lResult)
            {
                //函数签名 里面有函数指针
                union MessageMapFunctions mmf;
                //返回链表头节点
                const AFX_MSGMAP* pMessageMap; pMessageMap = this->GetMessageMap();
                
                const AFX_MSGMAP_ENTRY* lpEntry;
                
                for (/* pMessageMap already init'ed */; 
                        pMessageMap->pfnGetBaseMap != NULL;        //判断节点等不等于空
                        pMessageMap = (*pMessageMap->pfnGetBaseMap)()//找下一个节点
                    )
                {
                        lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,message, 0, 0)) != NULL)    
                        //消息函数的地址
                        mmf.pfn = lpEntry->pfn;
                        switch (lpEntry->nSig)
                        {
                            lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam);
                        }
                }
            } 
         }
    }
}
相关推荐
好大哥呀2 分钟前
C++ IDE
开发语言·c++·ide
WW_千谷山4_sch14 分钟前
MYOJ_10599:CSP初赛题单10:计算机网络
c++·计算机网络·算法
代码游侠1 小时前
学习笔记——HC-SR04 超声波测距传感器
开发语言·笔记·嵌入式硬件·学习
梵尔纳多1 小时前
绘制一个矩形
c++·图形渲染·opengl
橘颂TA1 小时前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹1 小时前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
liulilittle1 小时前
OPENPPP2 网络驱动模式
开发语言·网络·c++·网络协议·信息与通信·通信
mjhcsp1 小时前
C++ AC 自动机:原理、实现与应用全解析
java·开发语言·c++·ac 自动机
爱吃生蚝的于勒1 小时前
【Linux】进程间通信之匿名管道
linux·运维·服务器·c语言·数据结构·c++·vim
Abbylolo2 小时前
《Obsidian Excalidraw插件配置与使用指南》
笔记