如果队列中已经有内容,PeekMessage 是否永远不会生成新的 WM_TIMER 消息,而不管过滤器如何?

Does PeekMessage never generate new WM_TIMER messages if there's something in the queue already, regardless of filters?

我了解 WM_TIMER 消息是由 GetPeek 即时生成的,基于一些标志 "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_SYS­TIMER 会产生影响吗,因为它在 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;
}