The message loop is an obligatory section of code in every program that uses a graphical user interface under Microsoft Windows.
Windows programs that have a GUI are event-driven. Windows maintains an individual message queue for each thread that has created a window. Usually only the first thread creates windows. Windows places messages into that queue whenever mouse activity occurs on that thread's window, whenever keyboard activity occurs while that 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 thread with a window 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 blocks for a message and retrieves it), and then calls DispatchMessage (which dispatches the message), and repeats indefinitely. This is the message loop. There usually is a message loop in the main program, which runs on the main thread, and additional message loop in each created modal dialog. 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;

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

        if (bRet == -1)  // If bRet is -1, GetMessage has failed.
        {
            // Handle or log the error; possibly exit.
            // ...
        }
        else if (bRet != 0)  // If bRet is not 0 or -1, the message must be processed.
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else  // If bRet is 0, the message loop should exit.
        {
            break;
        }
    }
    return msg.wParam;
}

It is conventional for the event loop to call TranslateMessage on each message which can translate virtual keystrokes into strings. 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 class when it was registered.) (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 the 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.

See also
 Xlib for the event loop in the X Window System

External links
 Meandering Through the Maze of MFC Message and Command Routing (MSJ, July 1995)
 A Key's Odyssey: the path of a keystroke message through the VCL
 Platform SDK: Messages and Message Queues
 Platform SDK: Windows API: Entering the Message Loop
 Using Messages and Message Queues (MSDN)
 GetMessage function
 PeekMessage function

Events (computing)
Microsoft application programming interfaces
메시지 루프()는 윈도우 프로그램에서 메시지를 받아들이는 부분을 뜻하며, 윈도우 기반의 모든 GUI 프로그램에 반드시 포함되는 루틴이다.

윈도우의 GUI 프로그램은 기본적으로 이벤트 드리븐으로 동작한다. 윈도우 시스템은 각각 프로세스에 대해서 개별적인 메시지 큐를 할당한다. 어떤 프로세스가 실행되었을 때 해당 프로세스는 메시지 큐를 부여 받으며, 프로세스에 대해서 사용자의 마우스 입력이나 키보드 입력 등 메시지가 발생했을 때 운영체제가 해당 프로세스의 메시지 큐에 메시지를 넣는다. 또는 프로세스가 이런 메시지들을 스스로 자신의 큐에 추가할 수도 있다. 사용자의 입력이나 기타 여러 가지 행동을 받아서 처리하기 위해서 각각의 프로세스는 자신의 큐에서 메시지들을 지속적으로 읽어들이면서 각 메시지에 대응하는 행동을 수행한다. 이를 위해 프로그래머는 프로그램 내부에 메시지를 받아들이는 GetMessage()와 받은 메시지를 메시지 처리 함수로 디스패치(전달; 전파)하는 DispatchMessage()를 무한정 호출하는 루프를 작성함으로써 프로세스가 메시지를 처리할 수 있게 한다. 이를 메시지 루프라고 한다. 이는 일반적으로 메인 프로그램(메인 함수)의 일부로서 메인 스레드에서 동작한다. 프로세스가 소유한 모든 창(윈도우) 각각에 대한 메시지는 메시지 큐를 통해 전달되며, 해당 프로세스의 메시지 루프에 의해 처리(핸들링)된다. 메시지 루프는 이벤트 루프의 일종이기도 하다.

메시지 루프는 기본적으로 다음과 같이 구성된다.

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

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

        if (bRet > 0)  // (bRet > 0 이면 메시지가 처리되어야 한다.)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else if (bRet < 0)  // (bRet == -1 은 에러를 뜻한다.)
        {
            // 에러에 대한 처리나 로그 남김이나 프로그램 종료 등의 구문.
            // ...
        }
        else  // (bRet == 0 은 프로그램 종료를 의미한다.)
        {
            break;
        }
    }
    return msg.wParam;
}

전형적으로 이벤트 루프는 가상 키 입력을 문자열로 변환하기 위한 TranslateMessage()를 각 메시지에 대해 호출한다. TranslateMessage() 호출은 필수는 아니지만 호출되지 않는 경우 문제가 발생할 소지가 있다. 메시지 루프는 DispatchMessage()는 반드시 호출해야 한다.

메시지 루프는 핸들링하고 있는 메시지 자체에 대해서 직접적으로 처리하지는 않는다. 메시지 루프는 DispatchMessage()를 통해서 메시지들을 해당 메시지가 전달되어야 하는 윈도우의 "윈도우 프로시저"에 전달함으로써 메시지를 전파(Dispatch; 디스패치)시킨다. ("윈도우 프로시저"는 윈도우 클래스가 등록될 때 함께 등록되는 콜백 프로시저를 뜻한다. 여러 개의 창이 하나의 윈도우 프로시저를 공유하는 것도 가능하다.)

프로그램 코드를 통해서 윈도우 프로시저에 직접 메시지를 보낼 수도 있으며, 시스템 큐를 거치지 않고 바로 전달되는 이런 메시지들을 가리켜 비큐 메시지(Nonqueued Messages)라고 부른다.

메시지 루프는 윈도우 GUI 프로그램에 반드시 필요한 부분이지만 엄격한 규칙이나 요구사항은 없다. 메시지를 받아들이고 디스패치하는 부분은 프로그램 코드의 어느 부분에라도 구현될 수 있으며 다양한 옵션이 있다. 예를 들어 GetMessage()는 메시지가 들어올 때까지 스레드를 블록시키지만, GetMessage() 대신 PeekMessage()와 같이 메시지가 있을 때는 읽어들이지만 메시지가 없을 경우에는 즉시 반환하는 논블록킹(Non-blocking) 함수를 이용하는 수도 있다. 또한 WaitMessage()를 이용하면 큐에 메시지가 있을 때까지 스레드를 슬립시키는 것도 가능하다.

한편 윈도우 폼, 윈도우 프레젠테이션 파운데이션, MFC, 델파이, Qt와 같은 최근의 GUI 프레임워크로 프로그램을 개발할 때에는 프로그래머가 메시지 루프를 별도로 구현할 필요가 없다. 하지만 프레임워크가 내부적으로 메시지 루프와 같은 형태로 사용자 입력을 처리하는 부분을 구현하고 있으며, 깊이 있는 프로그래밍이 필요한 경우 프로그래머에 의해 수정될 여지가 있다.

외부 링크 
Meandering Through the Maze of MFC Message and Command Routing (MSJ, July 1995)
A Key's Odyssey: the path of a keystroke message through the VCL 
Platform SDK: Messages and Message Queues
Platform SDK: Windows API: Entering the Message Loop
Using Messages and Message Queues (MSDN)
GetMessage function
PeekMessage function

이벤트 (컴퓨팅)
마이크로소프트 API