C 使用“PostQuitMessage”和只处理所有消息之间有区别吗?

C 使用“PostQuitMessage”和只处理所有消息之间有区别吗?,c,windows,winapi,C,Windows,Winapi,我想知道这两个片段之间是否有区别: 一: 二: 抱歉,我想不出较短的片段 我的问题是调用PostQuitMessage并使用GetMessage处理所有消息是否等同于使用PeekMessage处理所有消息,直到返回FALSE ,WM_QUIT是“仅在消息队列为空时生成的”,因此这两种方法看起来应该是相同的,但可能有细微的区别。雷蒙德的博文说: 因为系统试图不在“坏”位置注入WM_退出消息 时间”;相反,它会等待事情“稳定下来”,然后再生成 WM_退出消息,从而减少程序 可能处于由A触发的多步过程

我想知道这两个片段之间是否有区别:

一: 二: 抱歉,我想不出较短的片段

我的问题是调用
PostQuitMessage
并使用
GetMessage
处理所有消息是否等同于使用
PeekMessage
处理所有消息,直到返回
FALSE


WM_QUIT
是“仅在消息队列为空时生成的”,因此这两种方法看起来应该是相同的,但可能有细微的区别。

雷蒙德的博文说:

因为系统试图不在“坏”位置注入WM_退出消息 时间”;相反,它会等待事情“稳定下来”,然后再生成 WM_退出消息,从而减少程序 可能处于由A触发的多步过程的中间。 已发布消息的顺序

因此,理论上没有区别,因为在队列为空之前,系统不会生成
WM\u QUIT
。然而,Raymond并没有说保证在生成
WM_QUIT
后消息不会到达,只是系统试图避免它

因此,可以想象,在您退出主
GetMessage
循环后,另一个线程可能会向您发布消息,这取决于您的应用程序,这可能是您必须处理的事情。例如,如果您在内部发布消息,其中包含预期接收线程将释放的内存分配,那么您可能需要一个单独的
PeekMessage
循环来在线程完全退出之前清除这些消息


但实际上,没有人会像你的第二个例子那样编写消息循环。

雷蒙德的博文说:

因为系统试图不在“坏”位置注入WM_退出消息 时间”;相反,它会等待事情“稳定下来”,然后再生成 WM_退出消息,从而减少程序 可能处于由A触发的多步过程的中间。 已发布消息的顺序

因此,理论上没有区别,因为在队列为空之前,系统不会生成
WM\u QUIT
。然而,Raymond并没有说保证在生成
WM_QUIT
后消息不会到达,只是系统试图避免它

因此,可以想象,在您退出主
GetMessage
循环后,另一个线程可能会向您发布消息,这取决于您的应用程序,这可能是您必须处理的事情。例如,如果您在内部发布消息,其中包含预期接收线程将释放的内存分配,那么您可能需要一个单独的
PeekMessage
循环来在线程完全退出之前清除这些消息


然而,在实践中,没有人像您的第二个示例那样编写消息循环。

我认为公认的答案无法解决真正的问题。
雷蒙德直接回答了这个问题

基本上:

  • 您无法控制每个消息循环,因此您没有该选项

  • 哦,顺便说一下,别忘了在您自己的消息循环中
    PostQuitMessage

    请注意
    它依赖于您将
    CMessageLoop::Run
    的返回值传递给
    PostQuitMessage


  • 我认为公认的答案并不能解决真正的问题。
    雷蒙德直接回答了这个问题

    基本上:

  • 您无法控制每个消息循环,因此您没有该选项

  • 哦,顺便说一下,别忘了在您自己的消息循环中
    PostQuitMessage

    请注意
    它依赖于您将
    CMessageLoop::Run
    的返回值传递给
    PostQuitMessage


  • 这纯粹是一种智力上的好奇心,还是你试图用非标准的方法达到一种特殊的效果?@AdrianMcCarthy我在看一个使用非标准编程风格的人的代码库。除此之外,除非真的有必要,否则他不愿意更改代码。所以我想知道他所做的是否至少是正确的。这纯粹是一种智力上的好奇,还是你试图用你的非标准方法实现一种特殊的效果?@AdrianMcCarthy我正在看一个使用非标准编程风格的人的代码库。除此之外,除非真的有必要,否则他不愿意更改代码。所以我想知道他所做的是否至少是正确的。谢谢。我知道在这两个例子中,循环退出后可以发布消息,对此无能为力,但我认为可能是特殊的
    WM_QUIT
    做了一些无法手动完成的事情。第二个例子是我在代码库中看到的,这就是为什么我要问这个问题。谢谢。我知道在这两个例子中,循环退出后可以发布消息,对此无能为力,但我认为可能是特殊的
    WM_QUIT
    做了一些无法手动完成的事情。第二个例子是我在代码库中看到的,这就是为什么我要问这个问题。
    void main()
    {
        // ...
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        ExitProcess(0);
    }
    
    // ...
    
    void quit()
    {
        PostQuitMessage(0);
    }
    
    bool quit = false;
    
    void main()
    {
        // ...
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            if(quit)
            {
                while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&_msg);
                }
                ExitProcess(0);
            }
        }
    
        // Shouldn't get here
        ExitProcess(1);
    }
    
    // ...
    
    void quit()
    {
        quit = true;
        PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
    }