如果队列中已经有内容,PeekMessage 是否永远不会生成新的 WM_TIMER 消息,而不管过滤器如何?
Does PeekMessage never generate new WM_TIMER messages if there's something in the queue already, regardless of filters?
我了解 WM_TIMER
消息是由 Get
和 Peek
即时生成的,基于一些标志 "a timer has elapsed, when you're ready post a timer message"。
来自docs:
The WM_TIMER message is a low-priority message. The GetMessage and
PeekMessage functions post this message only when no other
higher-priority messages are in the thread's message queue.
这是否意味着如果我将它与过滤器一起使用,PeekMessage
将 return False
(即没有消息):
messageFound = PeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)
如果队列中有任意条优先级较高的消息; 甚至那些不符合过滤器的?因此,由于存在(不匹配的)高优先级消息
,这两个队列都将 return 为假
WM_NOTIFY or WM_NOTIFY
--Flag to autogenerate timer-- WM_TIMER
WM_SYSTIMER
会产生影响吗,因为它在 same group 中作为 WM_TIMER
或者它只是意味着如果我没有过滤器,那么如果队列中有其他消息,则不会创建 新的自动生成的 WM_TIMER
消息,但是已经存在(来自 Peek + PM_NOREMOVE)的任何消息都将像普通消息一样运行吗? (即 Peek 现在只是 returns,以先发布者为准)
If highPriorityMessagesExist() Then
Return anyOfThemMatchTheFilter()
Else
If !lowPriorityMessagesExist()
tryGenerateSomeFromFlags()
If lowPriorityMessagesExist()
Return anyOfThemMatchTheFilter()
Else
Return False
对
If anyMessagesMatchTheFilter()
Return True
Else
tryGenerateSomeFromFlags()
Return anyMessagesMatchTheFilter()
WM_TIMER 如果过滤器范围内有高优先级的消息,则不会生成消息。但是如果队列中有高优先级的消息,但是被GetMessage或PeekMessage的wMsgFilterMin和wMsgFilterMax参数过滤掉了,仍然会产生WM_TIMER条消息。
换句话说这个程序将生成调试输出:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
SetTimer(NULL, 101, 500, NULL);
auto start = GetTickCount();
while (GetTickCount() - start < 4000) {
MSG msg;
PostMessage(NULL, WM_NOTIFY, 0, 0);
GetMessage(&msg, NULL, WM_TIMER, WM_TIMER);
if (msg.message == WM_TIMER)
OutputDebugStringA("WM_TIMER\n");
}
return 0;
}
但是下面的程序不会生成调试输出,因为 WM_NOTIFY 现在在过滤范围内:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
SetTimer(NULL, 101, 500, NULL);
auto start = GetTickCount();
while (GetTickCount() - start < 4000) {
MSG msg;
PostMessage(NULL, WM_NOTIFY, 0, 0);
GetMessage(&msg, NULL, WM_NOTIFY, WM_TIMER);
if (msg.message == WM_TIMER)
OutputDebugStringA("WM_TIMER\n");
}
return 0;
}
我了解 WM_TIMER
消息是由 Get
和 Peek
即时生成的,基于一些标志 "a timer has elapsed, when you're ready post a timer message"。
来自docs:
The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue.
这是否意味着如果我将它与过滤器一起使用,PeekMessage
将 return False
(即没有消息):
messageFound = PeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)
如果队列中有任意条优先级较高的消息; 甚至那些不符合过滤器的?因此,由于存在(不匹配的)高优先级消息
,这两个队列都将 return 为假WM_NOTIFY or WM_NOTIFY
--Flag to autogenerate timer-- WM_TIMER
WM_SYSTIMER
会产生影响吗,因为它在 same group 中作为 WM_TIMER
或者它只是意味着如果我没有过滤器,那么如果队列中有其他消息,则不会创建 新的自动生成的 WM_TIMER
消息,但是已经存在(来自 Peek + PM_NOREMOVE)的任何消息都将像普通消息一样运行吗? (即 Peek 现在只是 returns,以先发布者为准)
If highPriorityMessagesExist() Then
Return anyOfThemMatchTheFilter()
Else
If !lowPriorityMessagesExist()
tryGenerateSomeFromFlags()
If lowPriorityMessagesExist()
Return anyOfThemMatchTheFilter()
Else
Return False
对
If anyMessagesMatchTheFilter()
Return True
Else
tryGenerateSomeFromFlags()
Return anyMessagesMatchTheFilter()
WM_TIMER 如果过滤器范围内有高优先级的消息,则不会生成消息。但是如果队列中有高优先级的消息,但是被GetMessage或PeekMessage的wMsgFilterMin和wMsgFilterMax参数过滤掉了,仍然会产生WM_TIMER条消息。
换句话说这个程序将生成调试输出:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
SetTimer(NULL, 101, 500, NULL);
auto start = GetTickCount();
while (GetTickCount() - start < 4000) {
MSG msg;
PostMessage(NULL, WM_NOTIFY, 0, 0);
GetMessage(&msg, NULL, WM_TIMER, WM_TIMER);
if (msg.message == WM_TIMER)
OutputDebugStringA("WM_TIMER\n");
}
return 0;
}
但是下面的程序不会生成调试输出,因为 WM_NOTIFY 现在在过滤范围内:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
SetTimer(NULL, 101, 500, NULL);
auto start = GetTickCount();
while (GetTickCount() - start < 4000) {
MSG msg;
PostMessage(NULL, WM_NOTIFY, 0, 0);
GetMessage(&msg, NULL, WM_NOTIFY, WM_TIMER);
if (msg.message == WM_TIMER)
OutputDebugStringA("WM_TIMER\n");
}
return 0;
}