Visual C++中消息回调函数的执行顺序

Order of execution of message callback function in Visual C++

我正在开发 Windows Visual C++ 应用程序,它将监视消息泵的各种事件。这是我的主要 cpp 文件的框架:

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) {
    HWND hwnd;
    WNDCLASSEX wincl;

    // register WindowProcedure() as message callback function
    wincl.lpfnWndProc = WindowProcedure;
    // assign other properties...

    if (!RegisterClassEx (&wincl))
        return 0;

    // create main window
    hwnd = CreateWindowEx ( ... );

    // infinite message loop
    while (GetMessage (&messages, NULL, 0, 0)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    return 0;
}

这里是回调函数的框架:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch(message) {
        case WM_CLIPBOARDUPDATE:
            // handle the update here
    }
}

我的简单问题是回调函数是否保证以 sequence 开始和结束,或者它们是否有可能以 parallel 执行] 有一些重叠?换句话说,是否有可能并行执行对回调函数的 2 次调用,从而可能导致竞争条件?还是 Windows 保证每条消息都按顺序处理,一次一条?欢迎您提供任何文档或参考资料。

Window 消息存储在队列中。每次调用 GetMessage 时,它​​都会从队列中删除第一条消息。当您调用 DispatchMessage 时,将调用您的 window 过程。

是的,消息是按顺序处理的。但是,如果在您的 window 过程中调用 SendMessage,则可能存在一些重叠,因为该函数绕过消息队列并直接调用您的 window 过程(与仅将消息放入排队)。

但这并不意味着 window 过程将并行执行(例如,从多个线程)。 DispatchMessage 和 SendMessage 都不会为 运行 window 过程创建不同的线程。

Window 消息有时存储在消息队列中,有时不存储。未存储在队列中的 window 消息示例为 WM_ACTIVATE、WM_SETFOCUS 和 WM_SETCURSOR。其他消息,如 WM_PAINT,放在消息队列中。

window 的 window 过程从未被并行调用(参见前面的回答)。

消息确实按顺序处理,GetMessage 从队列中提取第一条消息。然而,需要注意的一件重要事情是,消息可以 "disappear" 来自队列而不被处理。例如,windows 在内部为每个 window 维护一个结构 (PAINTSTRUCT),在其中跟踪 window 的无效区域。一旦 window 客户区的任何部分无效,windows 就会在消息队列中放置一条 WM_PAINT 消息。但是,如果验证了无效区域(例如调用 ValidateRect),Windows 实际上会从队列中删除消息。此外,如果将另一个区域添加到无效区域 Windows 不会将另一个 WM_PAINT 消息放入队列,它会使用更新后的区域更新已放置的 WM_PAINT 消息。