Message loop in Microsoft Windows

From Wikipedia, the free encyclopedia
Jump to: navigation, search

The message loop is an obligatory section of code in every program that uses a graphical user interface under Microsoft Windows.

Windows GUI programs are event-driven. After starting a process, Windows maintains an individual message queue for it. Windows places messages into that queue whenever mouse activity occurs on that process's window, whenever keyboard activity occurs while that process's window has focus, and at other times. A process can also add messages to its own queue. To accept user input, and for other reasons, each process must continuously retrieve messages from its queue, and act on them. A programmer makes the process do that by writing a loop that calls GetMessage (which waits for a message and retrieves it), and then calls DispatchMessage (which dispatches the message), and repeats indefinitely. This is the message loop. It is usually part of the main program, which runs on the main thread. Messages for every window of the process pass through its message queue, and are handled by its message loop. A message loop is one kind of event loop.

A basic message loop appears as follows:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    BOOL bRet;

    for(; ; )
    {
        bRet = GetMessage(&msg, NULL, 0, 0);

        if (bRet > 0)  // (bRet > 0 indicates a message that must be processed.)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else if (bRet < 0)  // (bRet == -1 indicates an error.)
        {
            // Handle or log the error; possibly exit.
            // ...
        }
        else  // (bRet == 0 indicates "exit program".)
        {
            break;
        }
    }
    return msg.wParam;
}

It is conventional for the event loop to call TranslateMessage on each message. Calling TranslateMessage is not technically required, but problems can result if it is not called. The message loop must call DispatchMessage.

The message loop does not directly act on the messages that it handles. It dispatches them by calling DispatchMessage, which transfers the message to the "window procedure" for the window that the message was addressed to. (The "window procedure" is a callback procedure, which got associated with the window when it was created.) (More than one window can use the same window procedure.)

Code can also send messages directly to a window procedure. These are called nonqueued messages.

A strict message loop is not the only option. Code elsewhere in the program can also accept and dispatch messages. PeekMessage is a non-blocking call that returns immediately, with a message if any are waiting, or no message if none is waiting. WaitMessage allows a thread to sleep until a message is in he queue.

Modern graphical interface frameworks, such as Windows Forms, Windows Presentation Foundation, MFC, Delphi, Qt, and others do not require applications to code a Windows message loop, because they automatically route events such as key presses and mouse clicks to their appropriate handlers as defined within the framework. However, each framework implements a message loop somewhere, and the message loop can usually be accessed or replaced when more direct control is required.

External links[edit]