• MFC 消息映射表 及 相关宏定义


    MFC相关技术说明:<可参阅MSDN MFC TNO 5>
    MFC 中通过通过不同于SDK的switch的方法来处理WINDOWS消息,
    由消息映射表(Message Map)和虚函数多态来处理指定的窗体消息
     
    1 声明一个消息映射表(Message Map)
    在能处理消息的类中中添加宏
    DECLARE_MESSAGE_MAP()
     
    注 深入浅出MFC中有更详尽系统的概述 这里只介绍几个宏定义
    这个宏实现了3个功能:
    1 私有数据成员声明  AFX_MESSAGEMAP_ENTRY _messageEntries;数组
    2 保护数据成员声明  AFX_MESSAGE_MAP _messageMap指向_messageEntrie数组
    3声明并定义虚保护成员函数 GetMessageMap()用于得到 _messageMap的地址 
    宏的实现及相关的成员变量
     
    注意 具有消息处理得类必须从CCmdTarget派生而来
    CCmdTarget派生的类至少可以处理WM_COMMAND消息而只有消息的派发可以参看
    CMDTARG.CPP中的函数实现 AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg()派发消息的函数)
    类具有处理窗体的消息必须要从CWnd类中派生
    以下是CWnd及其派生类处理并派发消息的成员函数
    CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
     
    2实现一个消息映射表
    在类的实现文件中添加消息映射表
    表头宏 BEGIN_MESSAGE_MAP(CMyClass, CBaseClass)
     
    表未宏 END_MESSAGE_MAP()
     
    在表中添加相关的宏可以实现过滤 拦截处理消息 否则消息会顺着消息映射表在类的派生结构中流向基类
     
     
    2.1处理标准WINDOW消息宏
    (AfxMsg_.h的头文件中找到相关宏定义)
    在消息映射表中添加 ON_WM_xxx(xxx为消息名称)
    ie:
    如在一个窗体中处理WM_PAINT消息
    BEGIN_MESSAGE_MAP(CMyWnd, CBaseWnd)
    ON_WM_PAINT()
    END_MESSAGE_MAP()
    还需添加一个对应的处理WM_PAINT的成员函数在CMyWnd中
    标准Windows消息处理ON_WM_XXX对应的成员函数类型可以在
     
    注意:该功能可以通过class winzard来完成
     
    2.2处理COMMAND消息的消息映射表宏
    (AfxMsg_.h的头文件中找到相关宏定义)
    COMMAND消息一般是由菜单命令和加速健按下产生的
    2.2.1 ON_COMMAND
    ON_COMMAND(CMD_ID OnCmdFunc)
    afx_msg void OnCmdFunc();
    注意:可以由class winzard完成
     
    2.2.2 ON_COMMAND_UI
    ON_COMMAND_UI (CMD_ID, OnUpdateCmdUIFunc)
    afx_msg void OnUpdateCmdUIFunc(CCmdUI* pCmdUI);
    注意:可以由class winzard完成
     
    2.2.3 ON_COMMAND_RANGE
    ON_COMMAND_RANGE(START_ID, END_ID, OnCmdRangeFunc)
    afx_msg void OnCmdRangeFunc (int ID)
    注意:不可以由class winzard完成
     
    2.2.4 ON_COMMAND_UI_RANGE
    ON_COMMAND_UI_RANGE (START_ID, END_ID, OnUpdateCmdUIFunc)
    afx_msg void OnUpdateCmdUIFunc(CCmdUI* pCmdUI);
    注意:不可以由class winzard完成
     
    2.2.5 ON_COMMAND_EX
    ON_COMMAND_EX (ID, OnCmd)
    BOOL OnCmd()返回TURE表示消息得到处理, 否则消息会在消息路由中继续流动
    类似于异常的再次抛出
    注意:不可以由class winzard完成
     
    2.3       处理用户自定义消息
    ON_MESSAGE(WM_USERDEFINED, OnMsg)
    HRESULT OnMsg(WPARAM , LPARAM);
    用户定义的消息的值可以定义WM_USER - 0x7fff之间
     
    2.4       处理注册消息(系统级)
    ::RegisterWindowMessage()
    通过这个API可以在系统中注册一个消息并保证在系统内部是唯一的
    处理这样的消息的宏
    ON_REGISTERED_MESSAGE(WM_REGISTERED_MSG, OnMsg)
    afx_msg HRESULT OnMsg(WPARAM, LPARAM);
     
    2.5       处理控件消息
    控件发送给父窗体的通知消息父窗体可以在这时改变一些空间的状态或做出响应 WM_NOTIFY的消息
    ON_NOTIFY( wNotifyCode, id, memberFxn )
    afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
    ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
    可以用于处理一些标准的空间通知消息
     
    当要处理用户自己定义的控件消息时必须用宏
    ON_CONTROL(wNotifyCode, id, memberFxn)
    ON_CONTROL_RANGE( wNotifyCode, id1, id2, memberFxn ) 
     
     
    3相关宏的定义
    /////////////////////////////////////////////////////////////////////////////
    // Window message map handling
     
    struct AFX_MSGMAP_ENTRY;       // declared below after CWnd
     
    struct AFX_MSGMAP
    {
    #ifdef _AFXDLL
        const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
    #else
        const AFX_MSGMAP* pBaseMap;
    #endif
        const AFX_MSGMAP_ENTRY* lpEntries;
    };
     
    #ifdef _AFXDLL
    #define DECLARE_MESSAGE_MAP() /
    private: /
        static const AFX_MSGMAP_ENTRY _messageEntries[]; /
    protected: /
        static AFX_DATA const AFX_MSGMAP messageMap; /
        static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); /
        virtual const AFX_MSGMAP* GetMessageMap() const; /
     
    #else
    #define DECLARE_MESSAGE_MAP() /
    private: /
        static const AFX_MSGMAP_ENTRY _messageEntries[]; /
    protected: /
        static AFX_DATA const AFX_MSGMAP messageMap; /
        virtual const AFX_MSGMAP* GetMessageMap() const; /
     
    #endif
     
    #ifdef _AFXDLL
    #define BEGIN_MESSAGE_MAP(theClass, baseClass) /
        const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() /
            { return &baseClass::messageMap; } /
        const AFX_MSGMAP* theClass::GetMessageMap() const /
            { return &theClass::messageMap; } /
        AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /
        { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; /
        AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /
        { /
     
    #else
    #define BEGIN_MESSAGE_MAP(theClass, baseClass) /
        const AFX_MSGMAP* theClass::GetMessageMap() const /
            { return &theClass::messageMap; } /
        AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /
        { &baseClass::messageMap, &theClass::_messageEntries[0] }; /
        AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /
        { /
     
    #endif
     
    #define END_MESSAGE_MAP() /
            {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } /
        }; /
  • 相关阅读:
    【IT笔试面试题整理】把n个骰子扔在地上,所有骰子朝上一面的点数之和为S概率转
    面试题位操作
    微软面试题 寻找数组中出现的唯一重复的一个数
    【IT笔试面试题整理】给定二叉树先序中序,建立二叉树的递归算法
    【IT笔试面试题整理】 二叉树任意两个节点间最大距离
    面试题堆栈和队列
    LRU cache实现 Java 转
    【IT笔试面试题整理】有序数组生成最小高度二叉树
    Unity3d Asset Store下载的资源在哪?
    Xcode 6 如何将 模拟器(simulator) for iphone/ipad 转变成 simulator for iphone
  • 原文地址:https://www.cnblogs.com/lidabo/p/3047998.html
Copyright © 2020-2023  润新知