美文网首页
Windows消息的查找和匹配

Windows消息的查找和匹配

作者: 小染灬 | 来源:发表于2019-10-12 11:43 被阅读0次

CWnd或者派生类的对象调用OnWndMsg搜索本对象或者基类的消息映射数组,寻找当前消息的消息处理函数。如果当前对象或者基类处理了当前消息,则必定在其中一个类的消息映射数组中匹配到当前消息的处理函数。

消息匹配是一个比较耗时的任务,为了提高效率,MFC设计了一个消息缓冲池,把要处理的消息和匹配到的消息映射条目(条目包含了消息处理函数的地址)以及进行消息处理的当前类等信息构成一条缓冲信息,放到缓冲池中。如果以后又有同样的消息需要同一个类处理,则直接从缓冲池查找到对应的消息映射条目就可以了。

MFC用哈希查找来查询消息映射缓冲池。消息缓冲池相当于一个哈希表,它是应用程序的一个全局变量,可以放512条最新用到的消息映射条目的缓冲信息,每一条缓冲信息是哈希表的一个入口。

采用AFX_MSG_CACHE结构描述每条缓冲信息,其定义如下:

struct AFX_MSG_CACHE

{

UINT nMsg;

const AFX_MSGMAP_ENTRY* lpEntry;

const AFX_MSGMAP* pMessageMap;

};

nMsg存放消息ID,每个哈希表入口有不同的nMsg。

lpEnty存放和消息ID匹配的消息映射条目的地址,它可能是this所指对象的类的映射条目,也可能是这个类的某个基类的映射条目,也可能是空。

pMessageMap存放消息处理函数匹配成功时进行消息处理的当前类(this所指对象的类)的静态成员变量messageMap的地址,它唯一的标识了一个类(每个类的messageMap变量都不一样)。

this所指对象是一个CWnd或其派生类的实例,是正在处理消息的MFC窗口对象。

哈希查找:使用消息ID的值作为关键值进行哈希查找,如果成功,即可从lpEntry获得消息映射条目的地址,从而得到消息处理函数及其原型。

如何判断是否成功匹配呢?有两条标准:

第一,当前要处理的消息message在哈希表(缓冲池)中有入口;第二,当前窗口对象(this所指对象)的类的静态变量messageMap的地址应该等于本条缓冲信息的pMessagMap。MFC通过虚拟函数GetMessagMap得到messageMap的地址。

如果在消息缓冲池中没有找到匹配,则搜索当前对象的消息映射数组,看是否有合适的消息处理函数。

如果匹配到一个消息处理函数,则把匹配结果加入到消息缓冲池中,即填写该条消息对应的哈希表入口:

nMsg=message;

pMessageMap=this->GetMessageMap;

lpEntry=查找结果

然后,调用匹配到的消息处理函数。否则(没有找到),使用_GetBaseMessageMap得到基类的消息映射数组,查找和匹配;直到匹配成功或搜寻了所有的基类(到CCmdTarget)为止。

如果最后没有找到,则也把该条消息的匹配结果加入到缓冲池中。和匹配成功不同的是:指定lpEntry为空。这样OnWndMsg返回,把控制权返还给AfxCallWndProc函数,AfxCallWndProc将继续调用DefWndProc进行缺省处理。

消息映射数组的搜索在CCmdTarget::OnCmdMsg函数中也用到了,而且算法相同。为了提高速度,MFC把和消息映射数组条目逐一比较、匹配的函数AfxFindMessageEntry用汇编书写。

const AFX_MSGMAP_ENTRY* AFXAPI

AfxFindMessageEntry(const AFX_MSGMAP_ENTRY* lpEntry,

UINT nMsg, UINT nCode, UINT nID)

第一个参数是要搜索的映射数组的入口;第二个参数是Windows消息标识;第三个参数是控制通知消息标识;第四个参数是命令消息标识。

对Windows消息来说,nMsg是每条消息不同的,nID和nCode为0。

对命令消息来说,nMsg固定为WM_COMMAND,nID是每条消息不同,nCode都是CN_COMMAND(定义为0)。

对控制通知消息来说,nMsg固定为WM_COMMAND或者WM_NOTIFY,nID和nCode是每条消息不同。

对于Register消息,nMsg指定为0XC000,nID和nCode为0。在使用函数AfxFindMessageEntry得到匹配结果之后,还必须判断nSig是否等于message,只有相等才调用对应的消息处理函数。

相关文章

  • Windows消息的查找和匹配

    CWnd或者派生类的对象调用OnWndMsg搜索本对象或者基类的消息映射数组,寻找当前消息的消息处理函数。如果当前...

  • KMP算法文章合集

    字符串的查找:朴素查找算法和KMP算法 暴力匹配算法与KMP算法(串的匹配) 字符串查找算法BF和KMP 字符串匹...

  • 精确匹配查找和模糊查找

    1.精确匹配查找 按下快捷键Ctrl+F弹出【查找和替换】对话框,在【查找】选项卡中勾选【单元格匹配】,就可以实现...

  • Excel第三讲:查找,替换及定位

    一:查找和替换 1.按值查找查找和选择-查找和替换-替换-选项 -单元格匹配 2.按格式查找查找和选择-查找和替换...

  • Intent 的查找和匹配

    Intent 的查找和匹配 App 信息表的构建 系统启动之后就会注册各种系统服务,如 WindowManage...

  • 按文件名或文件内容搜索

    windows下调用使用cmd命令搜索文件名模糊匹配//在目录E:/workspace中递归遍历查找已.c结尾的文...

  • 备忘录

    Windows工作目录Windows查找DLL文件和EXE的工作目录没有任何关系。DLL在系统查找目录或者当前目录...

  • 全匹配和模糊匹配查找句柄

    标题全匹配情况下查找窗口句柄 Hwnd = Plugin.Window.Find(0, "东觉的浏览器")Mess...

  • Excel 查找与引用函数

    一、VlLOOKUP函数 VLOOKUP(查找的内容,查找区域,查找区域内第几列数据,匹配模式) 匹配模式:0/F...

  • iOS 消息查找和消息转发

    1. 消息慢速查找流程 1.1 forward_imp探索 输出: 源码: 当对象在调用方法时,会先去cls里的c...

网友评论

      本文标题:Windows消息的查找和匹配

      本文链接:https://www.haomeiwen.com/subject/rdhqmctx.html