tags:

views:

59

answers:

4

Most of the Win32 main loops I've seen are all structured like:

while (GetMessage(&message, NULL, 0, 0) > 0) {
  TranslateMessage(&message);
  DispatchMessage(&message);
}

It was pointed out to me that MsgWaitForMultipleObjects may be used to add some variety to a main loop. But is there a scenario where doing something between GetMessage, TranslateMessage and DispatchMessage is actually useful?

A: 

They are different beasts.

For Translate function

Translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function. [...] The TranslateMessage function does not modify the message pointed to by the lpMsg parameter.

DispatchMessage, on the other hand, dispatches a message to a window procedure.

So DispatchMessage does the actual work of processing the message. TranslateMessage MAY or MAY NOT post a new message to the thread queue. If the message is translated then a character message is posted to the thread's message queue.

The TranslateMessage function does not modify the message pointed to by the lpMsg parameter.

They are separate calls so you, the programmer, can have a chance to avoid the message translation provided by TranslateMessage.

smink
A: 

TranslateMessage() converts virtual keys messages to character input messages.

It is a separate call for the remote chance that under certain circumstances you would want to not produce character input messages for certain virtual keys.

shoosh
A: 

Well to quote an example from the MSDN:

You can modify a message loop in a variety of ways. For example, you can retrieve messages from the queue without dispatching them to a window. This is useful for applications that post messages not specifying a window. You can also direct GetMessage to search for specific messages, leaving other messages in the queue. This is useful if you must temporarily bypass the usual FIFO order of the message queue.

You can also possibly avoid calls to Translate message if you don't need to convert keyboard input control codes.

zdan
+3  A: 

The more traditional message loop looks like this:

while (GetMessage(&msg, 0, 0, 0)) 
{
    if (!TranslateAccelerator(hwndMain, haccel, &msg))
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    } 
}

It is a pretty big hint to what you'd want to do before dispatching the message: catch messages that ought to be intercepted and treated specially before the window sees them. Keyboard shortcuts are a classic example, they need to be detected no matter what window has the focus.

Any GUI class library exposes it with a virtual method named something like App.PreProcessMessage, a virtual function that can be overridden so your program can implement its own shortcuts and whatnot.

Hans Passant
That's a nice practical example, thanks. :)
Shtééf