前言
众所周知(bushi),Windows的所有程序都是由消息驱动的,每个程序都有自己的消息队列,通过处理各种各样的消息来完成一系列操作,从消息队列中抓取消息的常用函数有两个,分别是GetMessage()
与PeekMessage()
,单从字面意思其实并不容易看出这两个函数的区别,今天刚好有空就来记录一下。
函数原型
GetMessage
代码语言:javascript复制BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);
lpMsg
为接收消息信息的MSG结构的指针,负责存储抓到的消息。hWnd
为抓取消息的窗口句柄,窗口必须属于当前线程,若此值为0则抓取当前线程内所有窗口的消息wMsgFilterMin
为抓取的最小消息idwMsgFilterMax
为抓取的最大消息id,若Min
与Max
皆为0
则抓取所有消息
PeekMessage
代码语言:javascript复制BOOL PeekMessageA(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
lpMsg
为接收消息信息的MSG结构的指针,负责存储抓到的消息。hWnd
为抓取消息的窗口句柄,窗口必须属于当前线程,若此值为0
则抓取当前线程内所有窗口的消息wMsgFilterMin
为抓取的最小消息idwMsgFilterMax
为抓取的最大消息id,若Min
与Max
皆为0
则抓取所有消息- 处理消息的方式,例如移除(
PM_REMOVE
)或不移除(PM_REMOVE
)
返回值
GetMessage:
- 当有消息,且消息不为
WM_QUIT
时,返回1
- 当有消息,且消息为
WM_QUIT
时,返回0
- 当出现异常时,返回
-1
,例如hWnd
或lpMsg
无效(bool居然可以返回-1,好神奇)
因为GetMessage
有三种返回值,所以应尽量避免if(GetMessage())
的写法
PeekMessage:
- 当有消息时,返回
TRUE
- 当没有消息时,返回
FALSE
异同分析
相同点
二者都可以将消息抓出来并存储到lpMsg
中
不同点
GetMessage
只有在有消息时才会返回真值,若当前程序消息队列中没有消息,则GetMessage
会一直等待,此时线程处于阻塞状态,应用程序将无法执行任何指令。
而PeekMessage
不管有没有消息都会返回一个值,线程不会进入阻塞状态,应用程序可以不受影响执行其他指令
总结
通过上述对比不难看出,PeekMessage
明显要比GetMessage
更加灵活,可以在不影响线程的情况下抓取消息。如果在抓取窗口消息的同时又不想让程序进入阻塞状态,就应该使用PeekMessage
。
如果把二者类比为人,那GetMessage
就是死心眼儿,不抓到消息绝不返回(异常情况除外)。而PeekMessage
则相当机灵,针对两种情况都有不同的处理方式(有点像是侦察兵)。
当然二者都有各自的应用场景,并不是说PeekMessage
就一定比GetMessage
更好用。而且除了我说的几方面外也有其他细节的差异,个人水平有限就先不赘述了
参考文章:https://blog.csdn.net/m0_43458204/article/details/107979435