If MessageBox()/related are synchronous, why doesn’t my message loop freeze? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of If MessageBox()/related are synchronous, why doesn’t my message loop freeze? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

Why is it that if I call a seemingly synchronous Windows function like MessageBox() inside of my message loop, the loop itself doesn’t freeze as if I called Sleep() (or a similar function) instead? To illustrate my point, take the following skeletal WndProc:

int counter = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_CREATE:
             SetTimer(hwnd, 1, 1000, NULL); //start a 1 second timer
             break;
        case WM_PAINT:
             // paint/display counter variable onto window
             break;
        case WM_TIMER: //occurs every second
             counter++;
             InvalidateRect(hwnd, NULL, TRUE); //force window to repaint itself
             break; 
        case WM_LBUTTONDOWN: //someone clicks the window
             MessageBox(hwnd, "", "", 0);
             MessageBeep(MB_OK); //play a sound after MessageBox returns
             break;
        //default ....
    }
    return 0;
}

In the above example, the program’s main function is to run a timer and display the counter’s value every second. However, if the user clicks on our window, the program displays a message box and then beeps after the box is closed.

Here’s where it gets interesting: we can tell MessageBox() is a synchronous function because MessageBeep() doesn’t execute until the message box is closed. However, the timer keeps running, and the window is repainted every second even while the message box is displayed. So while MessageBox() is apparently a blocking function call, other messages (WM_TIMER/WM_PAINT) can still be processed. That’s fine, except if I substitute MessageBox for another blocking call like Sleep()

    case WM_LBUTTONDOWN:
         Sleep(10000); //wait 10 seconds
         MessageBeep(MB_OK);
         break;

This blocks my application entirely, and no message processing occurs for the 10 seconds (WM_TIMER/WM_PAINT aren’t processed, the counter doesn’t update, program ‘freezes’, etc). So why is it that MessageBox() allows message processing to continue while Sleep() doesn’t? Given that my application is single-threaded, what is it that MessageBox() does to allow this functionality? Does the system ‘replicate’ my application thread, so that way it can finish the WM_LBUTTONDOWN code once MessageBox() is done, while still allowing the original thread to process other messages in the interim? (that was my uneducated guess)

Thanks in advance

Answer

The MessageBox() and similar Windows API functions are not blocking the execution, like an IO operation or mutexing would do. The MessageBox() function creates a dialog box usually with an OK button – so you’d expect automatic handling of the window messages related to the message box. This is implemented with its own message loop: no new thread is created, but your application remains responsive, because selected messages (like for painting) are handled calling recursively your WndProc() function, while other messages are not transmitted, because of the modal type of the created window.

Sleep() and other functions (when called directly from your WndProc() handling a window message) would actually block the execution of your single threaded message loop – no other message would be processed.

We are here to answer your question about If MessageBox()/related are synchronous, why doesn’t my message loop freeze? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji