TranslateMessage ,GetMessage, DispatchMessage分析

雪夜
发布: 2025-09-02 08:59:48
原创
469人浏览过

大家好,又见面了,我是你们的朋友全栈君。

TranslateMessage(&msg);

TranslateMessage函数用于将快捷键消息转换为字符消息,并将转换后的新消息发送到调用线程的消息队列中。

由于Windows对所有键盘编码都采用虚拟键的定义,因此按键按下时不会直接产生字符消息,需要通过键盘映射将其转换为字符消息。这些字符消息随后会被发送到调用线程的消息队列中,并在下一次调用GetMessage函数时被取出。

LONG DispatchMessage(CONST MSG* lpmsg);

该函数的作用是将一个消息分发给窗口程序。它将消息推送到afxwndproc,最后流向pwnd->windowproc。DispatchMessage是在cwinapp::run中通过调用pumpmessage实现的,而pumpmessage又会调用DispatchMessage。通常,消息是从GetMessage函数中获取或通过TranslateMessage函数传递的。消息被分发到回调函数(过程函数),其作用是将消息传递给操作系统,然后操作系统调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息。

在MFC2.5时代(九十年代),所有窗口类共享同一个窗口函数(即afxwndproc)。

但现在使用的是钩子技术(即hook),因此需要与hook章节一起查看。

hook操作在每一个cwnd派生类对象产生时发生。

因此,DispatchMessage将消息推送到hook技术中的afxwndproc。

TranslateMessage ,GetMessage, DispatchMessage分析HOOK(钩子,挂钩)是一种实现Windows平台下类似于中断的机制。HOOK机制允许应用程序拦截并处理Windows消息或指定事件。当指定的消息发出后,HOOK程序可以在消息到达目标窗口之前将其捕获,从而获得对消息的控制权,并可以对该消息进行处理或修改,加入我们所需的功能。

定义钩子函数

钩子函数是一种特殊的回调函数。当钩子监视的特定事件发生后,系统会调用钩子函数进行处理。不同事件的钩子函数形式各不相同。下面以鼠标钩子函数为例说明钩子函数的原型:

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)

参数wParam和lParam包含所钩消息的信息,例如鼠标位置、状态,键盘按键等。

安装钩子

在程序初始化时,调用函数SetWindowsHookEx安装钩子。其函数原型为:

HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, INSTANCE hMod, DWORD dwThreadId)

参数idHook表示钩子类型,它与钩子函数类型一一对应。例如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等。

卸载钩子

当不再使用钩子时,必须及时卸载。只需简单地调用函数:

析稿Ai写作
析稿Ai写作

科研人的高效工具:AI论文自动生成,十分钟万字,无限大纲规划写作思路。

析稿Ai写作 97
查看详情 析稿Ai写作

BOOL UnhookWindowsHookEx(HHOOK hhk)即可。

PeekMessage和GetMessage函数的主要区别有:

GetMessage的主要功能是从消息队列中“取出”消息,消息被取出后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。也可以使用PeekMessage从消息队列中取出消息,这需要使用它的一个参数(UINT wRemoveMsg)。如果设置为PM_REMOVE,消息将被取出并从消息队列中删除;如果设置为PM_NOREMOVE,消息不会从消息队列中取出。如果GetMessage从消息队列中取不到消息,则线程会被操作系统挂起,等到OS重新调度该线程时,两者的性质不同:使用GetMessage的线程仍会被挂起,使用PeekMessage的线程会得到CPU的控制权,运行一段时间。GetMessage每次都会等待消息,直到取到消息才返回;而PeekMessage只是查询消息队列,没有消息就立即返回,从返回值判断是否取到了消息。PeekMessage是一个具有线程异步行为的函数,不管消息队列中是否有消息,函数都会立即返回。而GetMessage则是一个具有线程同步行为的函数,如果消息队列中没有消息的话,函数就会一直等待,直到消息队列中至少有一条消息时才返回。另外:PumpMessage起到消息泵的作用,其原理就是使用GetMessage或PeekMessage函数从消息队列中逐个读取消息,然后进行必要处理之后再发送出去。我们可以使用PumpMessage默认处理过程,当然也可以自己修改消息处理的方式。通常我们在设计窗口时也会自己设计消息循环方式。即PumpMessage函数会调用GetMessage、TranslateMessage、DispatchMessage。

一般wm_xx消息

TranslateMessage ,GetMessage, DispatchMessage分析wm_command

TranslateMessage ,GetMessage, DispatchMessage分析 /*********************

1.windows消息循环 if (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); //消息转化 DispatchMessage(&msg); //消息派遣. 把TranslateMessage转换的消息发送到窗口的消息处理函数,此函数在窗口注册时已经指定 }

执行过程:

消息循环调用GetMessage()从消息队列中查找消息进行处理,如果消息队列为空,程序将停止执行并等待(程序阻塞)。事件发生时导致一个消息加入到消息队列(例如系统注册了一个鼠标点击事件),GetMessage()将返回一个正值,这表明有消息需要被处理,并且消息已经填充到传入的MSG参数中;当传入WM_QUIT消息时返回0;如果返回值为负表明发生了错误。取出消息(在Msg变量中)并将其传递给TranslateMessage()函数,这个函数做一些额外的处理:将虚拟键值信息转换为字符信息。这一步实际上是可选的,但有些地方需要用到这一步。DispatchMessage()函数将消息分发到消息的目标窗口,并且查找目标窗口过程函数,给窗口过程函数传递窗口句柄、消息、wParam、lParam等参数然后调用该函数。在窗口过程函数中,检查消息和其他参数,你可以用它来实现你想要的操作。如果不想处理某些特殊的消息,你应该总是调用DefWindowProc()函数,系统将按默认的方式处理这些消息(通常认为是不做任何操作)。一旦一个消息处理完成,窗口过程函数返回,DispatchMessage()函数返回,继续循环处理下一个消息。

  1. 函数定义

2.1 GetMessage BOOL WINAPI GetMessage( Out LPMSG lpMsg, _Inopt HWND hWnd, In UINT wMsgFilterMin, In UINT wMsgFilterMax );

GetMessage函数的作用是从当前线程的消息队列里获取一个消息并填入MSG结构中。该函数只能获取调用线程的消息,不能获得其他线程的消息。成功获取消息后,线程将从消息队列中删除该消息。使用GetMessage函数,如果消息队列为空,函数会一直等待直到有消息到来才有返回值。

2.2 TranslateMessage //BOOL TranslateMessage(CONST MSG *lpMsg); 1 参数:lpMsg 指向一个含有用GetMessage或PeekMessage函数从调用线程的消息队列中取得消息信息的MSG结构的指针 函数功能描述: 将虚拟键消息转换为字符消息。字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 TranslateMessage函数不修改由参数lpMsg指向的消息。

2.3 DispatchMessage 函数原型:LONG DispatchMessage(CONST MSG* lpmsg); 1 参数: lpmsg:指向含有消息的MSG结构的指针。

返回值: 返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。

备注: MSG结构必须包含有效的消息值。如果参数lpmsg指向一个WM_TIMER消息,并且WM_TIMER消息的参数IParam不为NULL,则调用IPa1ram指向的函数,而不是调用窗口程序。

  1. 程序实例

如果处理时间大于定时器时间,按照处理时间循环。如果处理时间小于定时器时间,按照定时器时间。

pragma comment(lib,”user32″) #include <stdio.h> #include <time.h> #include #include <windows.h> char datestr[16]; char timestr[16]; char mss[4]; void log(char s) { struct tm now; struct timeb tb; ftime(&tb); now = localtime(&tb.time); sprintf(datestr, “%04d-%02d-%02d”, now->tm_year + 1900, now->tm_mon + 1, now->tm_mday); sprintf(timestr, “%02d:%02d:%02d”, now->tm_hour, now->tm_min, now->tm_sec); sprintf(mss, “%03d”, tb.millitm); printf(“%s %s.%s %s”, datestr, timestr, mss, s); } VOID CALLBACK myTimerProc1( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time) { log(“In myTimerProc1\n”); } VOID CALLBACK myTimerProc2( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time) { log(“In myTimerProc2\n”); }

int main() { MSG msg; SetTimer(NULL, 0, 4000, myTimerProc1); SetTimer(NULL, 1, 2000, myTimerProc2); for (int i = 0; i

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://www.php.cn/link/f512288bb4d64bba2c024bc73646808d

以上就是TranslateMessage ,GetMessage, DispatchMessage分析的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号