众所周知(bushi),Windows的所有程序都是由消息驱动的,每个程序都有自己的消息队列,通过处理各种各样的消息来完成一系列操作,从消息队列中抓取消息的常用函数有两个,分别是GetMessage()与PeekMessage ,窗口必须属于当前线程,若此值为0则抓取当前线程内所有窗口的消息 wMsgFilterMin为抓取的最小消息id wMsgFilterMax为抓取的最大消息id,若Min与Max皆为0则抓取所有消息 PeekMessage 而PeekMessage不管有没有消息都会返回一个值,线程不会进入阻塞状态,应用程序可以不受影响执行其他指令 总结 通过上述对比不难看出,PeekMessage明显要比GetMessage更加灵活,可以在不影响线程的情况下抓取消息 如果在抓取窗口消息的同时又不想让程序进入阻塞状态,就应该使用PeekMessage。 如果把二者类比为人,那GetMessage就是死心眼儿,不抓到消息绝不返回(异常情况除外)。 而PeekMessage则相当机灵,针对两种情况都有不同的处理方式(有点像是侦察兵)。 当然二者都有各自的应用场景,并不是说PeekMessage就一定比GetMessage更好用。
将第二、三、四个参数设定为NULL或0时,表明我们想让PeekMessage传回程序中所有窗口的所有消息。 当消息队列中有一个消息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage传回FALSE(0)。 此参数可取下列值之一: PM_NOREMOVE:PeekMessage处理后,消息不从队列里除掉。 PM_REMOVE:PeekMessage处理后,消息从队列里除掉。 如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。 PeekMessage通常不从队列里清除WM_PANT消息。该消息将保留在队列里直到处理完毕。
方法弊端: 程序不能很快的绘制随机矩形,必须等待每个WM_TIMER消息,会依赖于系统时钟的精度 新函数: PeekMessage(&msg,NULL,0,0,PM_REMOVE);这个函数允许一个程序检查程序队列中的下一个消息 msg); DispatchMessage(&msg); } } 替换后的循环消息: while(TRUE) { if(PeekMessage 因为正常的GetMessage返回值是false(0),但是PeekMessage的返回值是队列中有没有消息,因此检查wm_quit是必要的。 源文件代码: // peekmessage.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "peekmessage.h" #include <Windows.h> #include <stdlib.h> LRESULT CALLBACK
字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 函数功能 PeekMessage是一个Windows API函数。 此参数可取下列值之一: 值 意义 PM_NOREMOVE PeekMessage处理后,消息不从队列里除掉。 PM_REMOVE PeekMessage处理后,消息从队列里除掉。 如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。 PeekMessage通常不从队列里清除WM_PAINT消息。该消息将保留在队列里直到处理完毕。但如果WM_PAINT消息不指向无效区,PeekMessage将能够从队列里清除WM_PAINT消息。
PeekMessage和GetMessage函数的主要区别有: GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视 也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为PM_REMOVE,消息则被取出并从消息队列中删除;如果设置为PM_NOREMOVE 如果GetMessage从消息队列中取不到消息,则线程就会被操作系统挂起,等到OS重新调度该线程时,两者的性质不同:使用GetMessage线程仍会被挂起,使用PeekMessage线程会得到CPU的控制权 GetMessage每次都会等待消息,直到取到消息才返回;而PeekMessage只是查询消息队列,没有消息就立即返回,从返回值判断是否取到了消息 PeekMessage是一个具有线程异步行为的函数, 另外:PumpMessage起到消息泵的作用,其原理就是使用GetMessage或PeekMessage函数从消息队列中逐个读取消息,然后进行必要处理之后再发送出去。
PeekMessage和GetMessage函数的主要区别有: GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视 也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为PM_REMOVE,消息则被取出并从消息队列中删除;如果设置为PM_NOREMOVE GetMessage每次都会等待消息,直到取到消息才返回;而PeekMessage只是查询消息队列,没有消息就立即返回,从返回值判断是否取到了消息 PeekMessage是一个具有线程异步行为的函数, 另外:PumpMessage起到消息泵的作用,其原理就是使用GetMessage或PeekMessage函数从消息队列中逐个读取消息,然后进行必要处理之后再发送出去。 字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 TranslateMessage函数不修改由参数lpMsg指向的消息。
此参数可取下列值之一: PM_NOREMOVE:PeekMessage处理后,消息不从队列里除掉。 PM_REMOVE:PeekMessage处理后,消息从队列里除掉。 如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。 PeekMessage通常不从队列里清除WM_PANT消息。该消息将保留在队列里直到处理完毕。 可以通过调用PeekMessage强 制系统创建一个message queue。 &GetMessage PeekMessage与GetMessage的对比 相同点: PeekMessage函数与GetMessage函数都用于查看应用程序消息队列,有消息时将队列中的消息派发出去
,QS_ALLINPUT);if(有消息){PeekMessage(&msg,...);//取一条DispatchMessage(&msg);//处理一条}}老张:问题就在这里! 老张:必须清空队列:展开代码语言:C++AI代码解释if(有消息){while(PeekMessage(&msg,...)) 情况四:过滤器的副作用老张:你用PeekMessage时设置过滤器了吗?小王:有时会过滤特定消息。老张:危险! 情况六:GetMessage的阻塞陷阱小王:我见过有人用GetMessage代替PeekMessage。老张:大忌! 系统告诉你"有PAINT消息",但实际调用PeekMessage时,可能取不到完整消息!情况八:线程消息的隐蔽性小王:线程消息有什么区别?
字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 . 参数: lpMsg 指向一个含有用GetMessage或PeekMessage函数从调用线程的消息队列中取得消息信息的MSG结构的指针。 . TranslateMessage函数只能用于转换由GetMessage或PeekMessage函数接收到的消息。 DispatchMessage函数 函数功能:该函数调度一个消息给窗口程序。
PeekMessage和GetMessage的区别: GetMessage在没有消息的时候等待消息,cpu当然低 PeekMessage没有消息的时候立刻返回,所以cpu占用率高。 因为游戏不能靠windows消息驱动,所以要用PeekMessage(); PretranslateMessage 的实现,不得不谈到MFC消息循环的实现。
Function Pointer) 回调函数===窗口过程函数 注册窗口类 LRESULT & CALLBACK详解 消息循环 PostMessage 和 SendMessage GetMessage 和 PeekMessage GetMessage 和 PeekMessage 前面讲到 GetMessage 会堵塞执行直到消息队列中有新的消息插入。 为了解决这个问题,游戏程序中一般使用 PeekMessage 函数替代 GetMessage 函数,二者的功能几乎一致,唯一的差别是 PeekMessage 不管消息队列中有没有消息都会立刻返回,也就解决了刚刚提到的更新不及时和不更新卡顿假死问题 PeekMessage 函数和 GetMessage 函数的唯一差别是多了一个控制消息处理方式的参数 wRemoveMsg: BOOL WINAPI PeekMessage( _Out_ PM_REMOVE,该值会导致调用 PeekMessage 后将消息从消息队列中移除。 PM_NOYIELD,该值使系统不释放等待调用程序空闲的线程。可以和前两个值组合使用。
SetWindowsHookEx 设置好全局键盘钩子后 一定要 使用 PeekMessage 或 GetMessage 来处理信息,不然程序会 卡死 ,或者 键盘失灵,反正就是 不执行 钩子例程 2 网上多数看到 设置全局键盘钩子 而没有 PeekMessage 或 GetMessage 处理消息 过程 是因为 他们使用 MFC 编程, MFC中 自带 消息处理过程,而这里直接 空程序 走起则需要自己处理消息
done){ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) PeekMessage PeekMessage 则不阻塞,立即返回。 PeekMessage有一个标志参数,这个标志参数指定了如果队列中如果有消息的话,PeekMessage 的行为。 如果该标志中含有 PM_REMOVE,则 PeekMessage 会把新消息返回到 MSG 结构中,正如 GetMessage 的行为那样。
能够使用以下的语句片段: MSG msg;
//消耗掉消息队列中的全部消息
while(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))<br
我们可以使用PeekMessage()而不是GetMessage()来解决这个问题。 PeekMessage()可以检索像GetMessage()那样的消息,但是当没有消息等待时,PeekMessage()会立即返回而不是阻塞。 然后我们可以花时间做一些渲染。 使用PeekMessage()的修改后的消息循环如下所示: MSG msg = {0}; while( WM_QUIT ! = msg.message ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
当下一次线程调用函数 GetMessage 或 PeekMessage 时被读出。
接收线程等到调用GetMessage(或PeekMessage, WaitMessage)时先检查本线程的唤醒标志是否为QS_SENDMESSAGE,若是则将本线程中的发送消息队列中的消息取出,一直处理完发送消息队列中的所有消息 message types ); //线程的消息队列的状态存放在THREADINFO结构的唤醒标志成员中,用户可以联合指定属性,函数的高字返回指定属性的一个子集,低字返回自上一次调用GetMessage/PeekMessage LPARAM lParam; DWORD time; //消息存放在队列中的时间 POINT pt; //消息产生时鼠标的位置 } MSG, *PMSG; BOOL PeekMessage wMsgFilterMax, // last message UINT wRemoveMsg // removal options ); //若是消息队列中没有投递消息则函数立即返回 PeekMessage
= WM_QUIT) { if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(& HandleWindowMsg), result); } void HandleWindowMsg(int32_t result) { MSG uMsg; if (PeekMessage
2.2 TranslateMessage //BOOL TranslateMessage(CONST MSG *lpMsg); 参数:lpMsg 指向一个含有用GetMessage或PeekMessage 字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 TranslateMessage函数不修改由参数lpMsg指向的消息。
Win32中经典的PeekMessage()、DispatchMessage()和TranslateMessage()。这些东西在程序中注册的回调函数中被调用,用来处理和解析消息。 msg = d->queuedSocketEvents.takeFirst(); } else { haveMessage = PeekMessage