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

I am developing a Windows Visual C ++ application that will monitor a message pump for various events. Here is the skeleton of my main cpp file:

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;
}

      

And here is the skeleton of the callback function:

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

      

My simple question is, do the callbacks guarantee to start and end sequentially, or is it possible that they can run in parallel with some overlapping ones? In other words, is it possible that 2 calls to the callback function can be executed in parallel, which could lead to a race condition? Or does Windows guarantee that each message is processed in sequential order, one at a time? Any documentation or links you could provide is greatly appreciated.

+3


source to share


2 answers


Window messages are stored in a queue. Every time you call GetMessage, it removes the first message from the queue. Your window procedure is called when DispatchMessage is called.

So, messages are processed sequentially. However, there is some overlap if, inside your window procedure, you call SendMessage, as this function bypasses the message queue and just calls your window procedure directly (as opposed to PostMessage, which simply puts the message on the queue).



But this does not mean that the window procedure will be executed in parallel (as, for example, from multiple threads). Neither DispatchMessage nor SendMessage will create another thread to execute the window procedure.

+4


source


Window messages are sometimes stored in a message queue, and sometimes they are not. Examples of window messages not stored in the queue are WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR. Other messages such as WM_PAINT are placed on the message queue.

The window procedure is never called in parellel (see previous answer).



Messages are indeed processed in sequence, and GetMessage retrieves the first message from the queue. However, it is important to note that messages can "disappear" from the queue without being processed. For example, windows internally maintain a (PAINTSTRUCT) structure for each window in which it tracks an invalid window region. As soon as any part of the window's client area is invalid, windows put a WM_PAINT message on the message queue. However, if an invalid scope is validated (for example, a call to ValidateRect), Windows actually removes the message from the queue. Also, if another region was added to the invalid region, Windows does not queue another WM_PAINT message, it updates the already posted WM_PAINT message with the updated scope.

+1


source







All Articles