Winapi 如果存在';队列中已经有东西了,不管过滤器是什么?

Winapi 如果存在';队列中已经有东西了,不管过滤器是什么?,winapi,timer,message,Winapi,Timer,Message,我知道WM_TIMER消息是通过Get和Peek动态生成的,基于某个标志,该标志表示“计时器已过,当您准备发布计时器消息时” 从: WM_定时器消息是低优先级消息。GetMessage和 PeekMessage函数仅在没有其他功能时发布此消息 优先级较高的消息位于线程的消息队列中 这是否意味着如果我将PeekMessage与以下筛选器一起使用,它将返回False(即无消息): messageFound = PeekMessage(&msg, hwnd, WM_TIMER, WM_TIME

我知道
WM_TIMER
消息是通过
Get
Peek
动态生成的,基于某个标志,该标志表示“计时器已过,当您准备发布计时器消息时”

从:

WM_定时器消息是低优先级消息。GetMessage和 PeekMessage函数仅在没有其他功能时发布此消息 优先级较高的消息位于线程的消息队列中

这是否意味着如果我将
PeekMessage
与以下筛选器一起使用,它将返回
False
(即无消息):

messageFound = PeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)
队列中是否有优先级较高的消息即使是与过滤器不匹配的过滤器?因此,由于存在(不匹配的)高优先级消息,这两个队列都将返回false

WM_NOTIFY                        or        WM_NOTIFY
--Flag to autogenerate timer--             WM_TIMER
WM\u系统计时器
是否会产生影响,因为它位于as
WM\u计时器

或者这仅仅意味着,如果我没有过滤器,那么如果队列中有其他消息,则不会创建新的自动生成的
WM_TIMER
消息,但是已经存在的任何消息(比如Peek+PM_NOREMOVE)将像正常消息一样工作?(即Peek现在只返回最先发布的内容)


vs


如果筛选器范围中存在高优先级的消息,则不会生成WM_定时器消息。但是,如果队列中存在高优先级消息,但它们被GetMessage或PeekMessage的wMsgFilterMin和wMsgFilterMax参数过滤掉,则仍将生成WM_计时器消息

换句话说,此程序将生成调试输出:

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;
}
int-apitery-wWinMain,
_在当前情况下,
_在LPWSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
SetTimer(空、101500、空);
自动启动=GetTickCount();
while(GetTickCount()-start<4000){
味精;
PostMessage(NULL,WM_NOTIFY,0,0);
GetMessage(&msg,NULL,WM\u定时器,WM\u定时器);
if(msg.message==WM\u定时器)
OutputDebugStringA(“WM_定时器\n”);
}
返回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;
}
int-apitery-wWinMain,
_在当前情况下,
_在LPWSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
SetTimer(空、101500、空);
自动启动=GetTickCount();
while(GetTickCount()-start<4000){
味精;
PostMessage(NULL,WM_NOTIFY,0,0);
GetMessage(&msg,NULL,WM\u NOTIFY,WM\u TIMER);
if(msg.message==WM\u定时器)
OutputDebugStringA(“WM_定时器\n”);
}
返回0;
}

Raymond Chen在他的博客文章中谈到了这个问题。@RemyLebeau是的,我读了很多Raymond Chen关于计时器消息的文章,但它们没有帮助解决这个特殊的困惑“如果消息请求将要说“不,没有匹配的消息”,窗口管理器会进行最后一次检查:“是否有自动生成的消息可以满足此请求?”如果是,那么它会生成消息,嘿,看,这是一条消息!“谢谢,这很清楚。不过,只有一点:如果在第二个示例中,您手动发布WM_计时器,然后WM_NOTIFY-是否还有机制可以忽略计时器消息“低优先级”,或者一旦创建,它的行为是否与任何其他消息类似?(即,将有调试输出)如果手动发布WM_定时器消息,它的行为与队列中的任何其他类型的消息类似。特殊行为只与由于调用SetTimer而发生的WM_定时器消息的自动生成有关。
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;
}
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;
}