故事的开端有些平淡,眼红于XXX小程序,认为写完该程序就有了和心仪的妹子多相处的机会,必须搞,必须酷,按钮不能有,界面得隐藏,这就想到了全局快捷键。

注册调用RegisterHotKey(m_hWnd, 300, MOD_ALT, 'K');

定义消息处理函数 afx_msg long OnHotKey(WPARAM wparam, LPARAM lparam);

消息关联处理程序ON_MESSAGE(WM_HOTKEY, OnHotKey)

定义消息处理函数 ,switch(wparam)调用对应的函数处理。

测试了一下,一切OK,开始搜索其他API,埋头苦整,一番恶战终于搞定其他功能,开始登记其他快捷键并调用处理过程。OH SHIT!快捷键没效果了?难道是登记的快捷键冲突了?检查了RegisterHotKey的返回值,是正确的,那么登记快捷键肯定没问题!该怎么办呢?去查WIN32消息处理机制来解决问题吧

MFC总共有三种类型的消息:窗口、命令、控件通知,嗯,找找窗口消息是怎么处理的。

登记全局快捷键的原理解释是:某键被按下时,系统在所有的热键列表中寻找匹配者,匹配成功将WM_HOTKEY消息发送给登记了该热键的线程的消息处理队列。挠了挠脑袋,我认定WM_HOTKEY已经发送给指定的消息队列。

-----补充知识点,发送消息有两种形式:发送消息,即时到达并立马调用目标窗口的进程,目标窗口必须为调用函数返回一个结果才能继续;寄送消息,将消息加入目标进程的消息队列,应用程序有空闲时就会搜索消息队列,从消息队列中删除消息并将消息发送给指定窗口,通信可能延迟。鼠标和键盘消息由于其特殊性,采用寄送的方式处理,其他所有消息都是发送的方式。

到这里就有点悟了,敢情我定义的全局快捷键处理函数OnHotKey并不会直接被调用,大胆猜测一下:窗口进程从消息队列中取出寄送来的WM_HOTKEY消息后首先交给了窗口,而窗口线程收到WM_HOTKEY消息并没有按照我的意愿调用OhHotKey。再找一下窗口处理消息的机制。

寄送消息在被消息泵弹出之前会一直保留在消息队列中,直到应用程序调用GetMessage函数从消息队列中将之取出,取出后会调用PreTranslateMessage和TranslateMessage两个函数进行消息翻译,翻译后的消息通过DispatchMessage调用该消息预期的目标窗口进程。看到这里,不由得笑了,这可是大有玄机啊,GO ON!

PreTranslateMessage有点眼熟,果然从代码里找到这个知其然、不知其所以然的预处理函数。埋头继续查:绝大多数本窗口的消息都要经过PreTranslateMessage处理,如果想在MFC之前处理某消息,可以重载该函数,重点来了,只有经过消息队列的消息才会经过PreTranslateMessage处理,即时发送的消息或其他不经过消息队列的消息不会理睬该函数,联系前面的寄送消息方式,各位小看官都应该懂了,快捷键消息到了这里被截下来没有发送给预期的窗口处理函数。挖,还得挖,这个坑有点苗头了。

PretranslateMessage的定义和返回值仔细的看:是否调用TranslateMessage和DispatchMessage消息向指定窗口发送消息由PreTranslateMessage的返回值决定,当返回值为TRUE的时候,不回把消息发送给对应的窗口函数处理,这难道是真相?预处理消息的时候挖坑把WM_HOTKEY消息给埋起来了?修改代码,拦截到指定的消息后返回FALSE果然解决了问题。

随着真相的浮出水面,我又一次期待着想象中的其乐融融,加油,我会做一个颇具高手风范的tool。

离奇失踪的WM_HOTKEY消息--浅析WIN32消息队列的更多相关文章

  1. Win32消息机制

    1. 消息机制     过程驱动:程序是按照我们预先定义好的顺序执行,每执行一步,下一步都已经按照预定的顺序继续执行,直到程序结束.       事件驱动:程序的执行顺序是无序的.某个时间点所执行的代 ...

  2. win32 消息说明

    WM_NULL = $0000; WM_CREATE = $0001; 应用程序创建一个窗口 WM_DESTROY = $0002; 一个窗口被销毁 WM_MOVE = $0003; 移动一个窗口 W ...

  3. Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

  4. Wpf发送接收 win32消息

    #region WPF发送和接收win32消息 public const int WM_GETTEXT = 0x0D; public const int WM_SETTEXT = 0x0C; publ ...

  5. 收藏:Win32消息机制

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

  6. Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)

    注:以下内容为学习笔记,多数是从书本.资料中得来,只为加深印象,及日后参考.然而本人表达能力较差,写的不好.因非翻译.非转载,只好选原创,但多数乃摘抄,实为惭愧.但若能帮助一二访客,幸甚! 以下内容主 ...

  7. 【C#】分享一个可携带附加消息的增强消息框MessageBoxEx

    --------------201507160917更新--------------- 无意中发现标准消息框在Windows7是有声音的,只是在Windows server 2008(R2)无声,而我 ...

  8. 深入探讨MFC消息循环和消息泵

    首先,应该清楚MFC的消息循环(::GetMessage,::PeekMessage),消息泵(CWinThread::PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情.在MFC ...

  9. java微信开发API解析(二)-获取消息和回复消息

    java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...

随机推荐

  1. node-webkit 主页面和 iframe 页通讯

    <html lang="en-US"> <head> <title>Hello World!</title> <style&g ...

  2. python解压,压缩,以及存数据库的相关操作

    zipfile实现压缩整个目录和子目录 import os,shutil,zipfile,glob def dfs_get_zip_file(input_path,result): # files = ...

  3. hdu_4707

    算是水题一道吧,我也没有建树,看别人又用vector,又用bfs,dfs的,对vector不熟,所以就模拟了一下 #include<iostream> #include<string ...

  4. 创建一个web user control

    1.创建文件 添加,然后选择web user control 2.添加控件 在工具栏搜索button,然后拖动三个button上去 <%@ Control Language="C#&q ...

  5. hpuoj--1122-- HH的随机数(数据去重)

    1122: HH的随机数 时间限制: 1 Sec  内存限制: 128 MB 提交: 476  解决: 75 [提交][状态][讨论版] 题目描述 HH想在学校中请一些同学一起做一项问卷调查,为了实验 ...

  6. [jzoj 5178] [NOIP2017提高组模拟6.28] So many prefix? 解题报告(KMP+DP)

    题目链接: https://jzoj.net/senior/#main/show/5178 题目: 题解: 我们定义$f[pos]$表示以位置pos为后缀的字符串对答案的贡献,答案就是$\sum_{i ...

  7. POJ 1990 线段树

    题意: 思路: 线段树 (一棵就够啦 不像树状数组,还得用两棵) 先对v从小到大排序.每回插入的时候当前的v是最大的,只需要统计它到各个坐标的距离就好了. 里面存两个东西: 这个坐标左边的坐标个数和这 ...

  8. Kettle的四大不同环境工具

    不多说,直接上干货! kettle里有不同工具,分别用于ETL的不同阶段. 初学者,建议送Spoon开始.高手,是四大工具都会用. Sqoop: 图形界面工具,快速设计和维护复杂的ETL工作流.集成开 ...

  9. python的import与from…import的区别

    [转]http://blog.csdn.net/windone0109/article/details/8996184 在python中用import或者from-import来导入相应的模块.模块其 ...

  10. Ubuntu系统下安装Eclipse

    第一步:查看操作系统位数. 打开终端,输入file /sbin/init 可以看到笔者Ubuntu系统为32位,读者可以使用该命令获取自己机器上的操作系统位数. 这一步是最至关重要的一步,笔者机器处理 ...