发个以前的东西。
http://forum.jiurl.com/
[1] 介绍
每个 GUI thread 都有两个消息队列。不是 GUI thread 就没有消息队列。
GUI thread 的两个消息队列,分别是,Input queue 和 PostMessage queue。
Input queue 又叫做 application queue。
所有键盘和鼠标产生的消息,都被放入 Input queue 中。也只有键盘和鼠标产生的消息会被放入 Input queue 中。
PostMessage queue 又叫做 system queue。程序调用 PostMessage() 产生的消息都被放入 PostMessage queue 中。
这两种队列,虽然叫做 queue,实际上,他们是一个 QMSG 结构的双向链表。顺着链走,走到空,表明链结束了。
一个消息对应一个 QMSG 结构。
MLIST.pqmsgRead 指向这个 QMSG 链上的第一个 QMSG 的地址,也就是链头。
MLIST.pqmsgWriteLast 指向这个 QMSG 链上的最后一个 QMSG 的地址,也就是链尾。
MLIST.cMsgs 是这个链上的 QMSG 个数。
这两种队列中,消息的个数是没有限制的(实际上,在 AllocQEntry() 中有个限制,会链表中项的个数不超过 10000,实际中不可能达到这么大的数字)。
Input queue 位于,THREADINFO 结构的 PQ结构 pq 中的 mlInput,是个 MLIST 结构。
PostMessage queue 位于,THREADINFO 结构的 mlPost,是个 MLIST 结构。
$ 每个 GUI thread 都有自己的 Input queue 和 PostMessage queue
PostMessage queue 不必多说。
Input queue 可以见图 “每个 GUI thread 都有自己的 Input queue 的例子”。
$ Input queue 中可能出现的消息
Input queue 中只可能有下面的消息出现。
#define WM_KEYDOWN 0x0100
#define WM_KEYUP 0x0101
#define WM_SYSKEYDOWN 0x0104
#define WM_SYSKEYUP 0x0105
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
#define WM_RBUTTONDOWN 0x0204
#define WM_RBUTTONUP 0x0205
#define WM_MBUTTONDOWN 0x0207
#define WM_MBUTTONUP 0x0208
#define WM_MOUSEWHEEL 0x020A
这些 input 消息被处理(被 DefWindowProc() 处理,也可能被程序处理),从而产生各种其他的消息。
比如,在一个窗口的关闭按钮上,按鼠标左键,产生 WM_LBUTTONDOWN,WM_LBUTTONUP,这两个消息被 DefWindowProc() 处理,根据鼠标的当前位置,
发现在窗口的关闭按钮上,就会产生 WM_DESTROY 消息。
程序收到的其他各种消息,都是由程序(DefWindowProc(),也有可能是用户自己的代码)处理这些 input 消息,然后产生的(SendMessage 或者 PostMessage)。
$ INITIAL_POSTMESSAGE_LIMIT
在 AllocQEntry() 中,检查 win32k!gUserPostMessageLimit。
win32k!gUserPostMessageLimit 初始值为 INITIAL_POSTMESSAGE_LIMIT。
#define INITIAL_POSTMESSAGE_LIMIT 10000
#define MINIMUM_POSTMESSAGE_LIMIT 4000
$ 有用的 Windbg 命令
!userkdx.dmq
帮助见 !userkdx.help
dumps all queues
!dq -a
http://forum.jiurl.com/
消息队列
最新推荐文章于 2023-12-25 09:40:40 发布