如果MFC的消息映射表需要排序

这是今天下班前和同事讨论的问题。
MFC的消息映射通过几个简单的宏,对Windows的消息机制做了非常好的面向对象封装,一时为无数C++程序员所模仿(当然,MFC可能也是模仿别人的)。熟悉MFC消息映射机制的人都知道,其本质无非就是把消息和其处理函数放到一个数组当中,当程序接收到某消息时,就会遍历该数组,查找对应的消息ID,找到了就调用其处理函数,找不到就往其基类的数组当中去找。

步骤/方法

  • 01

    对,是线性查找!那么为什么MFC没有将消息数组排序,然后用二分查找,把复杂度从O(n)提高到O(lg n)呢?原因我想可能是没有必要,可以想像,一个类中的消息处理函数的个数是十分有限的,假设有100个消息,最坏情况也就是比较100个整数,其效率影响也是非常小的。而为了这不必要的效率在Framework级别加入排序与二分查找的算法,无疑增加了不必要的代码复杂度。

  • 02

    那么假设现在让你实现对消息映射表的排序,该如何来做呢? 因为消息映射表是全局变量,在Winmain之前就已经建好了,所以可以在Winmain的最开始做这个排序动作;但是MFC是封装了Winmain的,你无从修改,所以应该放在CWinApp::InitInstance()中;但是我们好像无法在这么一个统一的地方,访问到所有的MFC类的消息映射表并对其进行排序 - CRuntimeClass应该也无法完成这个任务,而且在非serialize的MFC程序中,其CRuntimeClass是没有连在一个链表中的,所以连访问CRuntimeClass都有问题。

  • 03

    另外一个想法是在接收到一个消息之后,但在dispatch之前对消息映射表进行排序,这个地点就是CCmdTarget::OnCmdMsg,这是个好方法,只需对用到的那个类进行排序,有点lazy evaluation的味道。 但是我们不能每次调用都排序一遍,那就势必需要一个static的变量来标志该消息映射表是否有序,可以这么做,在message map的宏实现中,额外插入一个初始值为false的static bool变量,和一个Sort的虚函数用来对消息映射表进行排序(调用一个公用的排序函数),并设置标志位,这样在CCmdTarget::OnCmdMsg调用该Sort虚函数就完成了排序。但这样有个缺点,就是每个类都多了一个额外的虚函数,对size和performance都有些影响。其实我们还可以复用消息映射表来存储这个标志位 - 因为每个类都会对应一个消息映射表,所以只要在每个类的消息映射表的第一项插入是否有序的标志,在CCmdTarget::OnCmdMsg中直接通过GetMessageMap虚函数拿到当前类的消息映射表,检验第一项标志位是否为排序,如果为否则排序,否则继续,句号。当然,这里有一点要注意的是把消息映射表的第一项挪做他用了,Framework的其他地方不会误解而当做普通项来使用。

(0)

相关推荐

  • MFC消息映射机制

    摘要:关于MFC消息映射机制的深入研究. 步骤/方法 01 预备工作: 定义消息描绘结构: struct AFX_MSGMAP { AFX_MSGMAP* pBaseMessageMap; AFX_M ...

  • MFC的消息实现机制

    我们可以看到,在MFC的框架结构下,可以进行消息处理的类的头文件里面都会含有DECLARE_MESSAGE_MAP()宏,这里主要进行消息映射和消息处理函数的声明.可以进行消息处理的类的实现文件里一般 ...

  • 路由器设置中的arp映射表是干什么用的深入探讨

    本文来和大家一起来探讨路由器设置中的arp映射表是干什么用的? 通过ARP映射表来观察网络中计算机的MAC地址和IP地址的映射关系,并可选定欲控制的计算机条目进行配置。 arp绑定设置可以防止ARP攻 ...

  • XP系统下安装字符映射表的方法

    字符映射表是一种特殊的表格,使用字符映射表可以将特殊的字符插入文档中。比如word文档、CAD图纸、CAD程序等。特殊字符包括高级数学运算符、科学计数法、货币符号以及其他语言中的字符,它在键盘上是找不 ...

  • Win8系统字符映射表在哪里?

    Win8系统字符映射表在哪里?

  • 路由器设置中的arp映射表作用是什么

    一.ARP的意思 ARP是Address Resolution Protocol的英文缩写,也就是地址解析协议的简称,是一种将IP地址转化为物理地址的协议. 二.arp映射表作用 通过ARP映射表来观 ...

  • excel表怎么排序,升序,降序,自动义排序

    为了让数值按由高到低或是由低到高的顺序进行排列,让数据显得更加清晰,就会用到excel表格的排序功能,排序分为三种方式,一是升序,二是降序,三是自定义.其中升序和降序的设置方法一样,自定义排序与升序和 ...

  • Execl 映射表 轻松搞定多对多账户映射

    公司有ERP、办公自动化、即时通信、报表查询、零件设计等五大应用系统,上述应用系统,在业务上相互独立、权限上又相互交叉,比如,张三只有ERP、零件设计两套系统权限,而李四却有除零件设计系统外所有系统的 ...

  • Execl映射表轻松搞定多对多账户映射

    首先,通过Execl新建一名为“映射表”的工作薄,设计好“用户映射表”的结构,导入所有员工姓名(图1)。其次,将从各应用系统数据库中导出的账号表保存为Execl表格,并导入至“映射表”工作簿中,并统一 ...