• 26、深入浅出MFC学习笔记,消息映射与命令传递


    Message Mapping and Command Routing

    1MFC把消息三大类:

    1)命令消息(WM_COMMAND):凡由UI 对象产生的消息都是这种命令消息,可能来自菜单或加速键或工具栏SDK程序主要靠消息的wParam 辨识之,MFC程序则主要靠菜单项目的识别码(menu ID)辨识之,两者其实是相同的。

        凡衍生自CCmdTarget 的类别,皆有资格接收改类型消息。几乎构造应用程序的最重要的几个类别都衍生自CCmdTarget

    2)标准消息:除WM_COMMAND 之外,任何以WM_ 开头的都算是这一类。任何衍生自CWnd 之类别,均可接收此消息。

    3Control Notification:这种消息由控制组件产生,为的是向其父窗口通知某种情况。如当你在ListBox上选择其中一个项目,ListBox就会产生LBN_SELCHANGE 传送给父窗口;这类消息也是以WM_COMMAND形式呈现[]

    注:以前的控件是发WM_COMMAND消息,而新的控件发WM_NOTIFY消息。

    2DECLARE_MESSAGE_MAP()

    相当于声明了这样的数据结构:

    wps_clip_image-928

        其中,pBaseBap 指向“基类的消息映射表”的指针。派生类自动继承基类所能处理的消息的能力。

    宏展开示例[1,P415]

    BEGIN_MESSAGE_MAP(CMyView, CView)
    ON_WM_CREATE()
    ON_WM_PAINT()
    END_MESSAGE_MAP()
    宏开后,成为:
    const AFX_MSGMAP* CMyView::GetMessageMap() const
    { return &CMyView::messageMap; }
    AFX_DATADEF const AFX_MSGMAP CMyView::messageMap =
    { &CView::messageMap, &CMyView::_messageEntries[0] };
    const AFX_MSGMAP_ENTRY CMyView::_messageEntries[] =
    {
    { WM_CREATE, 0, 0, 0, AfxSig_is, \
    (AFX_PMSG)(AFX_PMSGW)(int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT))OnCreate },
    { WM_PAINT, 0, 0, 0, AfxSig_vv, \
    (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))OnPaint },
    {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
    };
    

    3MFC消息传递网

    wps_clip_image-24342

    Message Map 既可说是一套宏,也可以说是宏展开后所代表的一套数据结构;甚至也可以说Message Map 是一种动作,寻找与消息相吻合的项目(处理函数),从而获得消息的处理例程的函数指针。

    4、为什么消息处理的流程不用虚函数实现,而要选用这种机制?

    你产生一个与窗口有关的C++ 类别,然后为此窗口所可能接收的任何消息都提供一个对应的虚拟函数。这的确散发着C++ 的味道和对象导向的精神,为什么不呢?

    要知道,虚拟函数必须经由一个虚拟函数表(virtual function tablevtable)实作出来,每一个子类别必须有它自己的虚拟函数表,其内至少有父类别之虚拟函数表的内容复本。虚拟函数表中的每一个项目都是一个函数指针,价值4 字节,如果基础类别的虚拟函数表有100个项目,经过10层继承,开枝散叶,总共需耗费多少内存在其中?最终,系统会被巨大的额外负担(overhead)拖垮!

    5、通常消息都是停留在消息队列中等待被所隶属之窗口抓取,如果设立hook,就可以更早一步抓取消息,并且可以抓取不属于你的消息,送往你设定的一个所谓「滤网函数(filter)」。

    DispatchMessage推送消息的实际流程:

    wps_clip_image-12374

    6、注意两样东西:MessageMapFunctions AfxSig_AfxSig_ 定义于AFXMSG_.H ;MessageMapFunctions 定义于 WINCORE.CPP 档。

    7、所有UI 对象状态的维护可以依赖所谓的UPDATE_COMMAND_UI 消息。,每当菜单被拉下并尚未显示之前,其命令项(以及对应之工具栏按钮)都会收到UPDATE_COMMAND_UI 消息,这个消息和WM_COMMAND 有一样的绕行路线,我们(程序员)只要在适当的类别中放置其处理函数,并在函数中做某些判断,便可决定如何显示命令项。

    参考

    [1] 深入浅出MFC

    [2] MFC Technical Notes

    http://msdn.microsoft.com/en-us/library/h6h0eact%28VS.80%29.aspx

    [3] http://blog.163.com/zhoumhan_0351/blog/static/3995422720103821847339/

    [4] http://www.cnblogs.com/mydomain/archive/2010/09/27/1837103.html

    [5] http://kaweh.candy.blog.163.com/blog/static/36818772200862904354131/

    [6] http://www.cnblogs.com/chinazhangjie/archive/2010/08/19/1803149.html

  • 相关阅读:
    虚拟化VMware之虚拟机备份(1)
    虚拟化VMware之虚拟机备份(1)
    柯塔娜大合唱,互联网安全观
    柯塔娜大合唱,互联网安全观
    如何在虚拟机上Centos系统安装Nginx服务
    给已验证登录的用户添加访问限制
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    login_required装饰器(1)
    Oracle 18c 新特性:动态 Container Map 增强 Application Container 灵活性
    如果登录不成功,跳转到登录页面
  • 原文地址:https://www.cnblogs.com/mydomain/p/1966863.html
Copyright © 2020-2023  润新知