31

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?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Stéphan Kochen
  • 19,513
  • 9
  • 61
  • 50

4 Answers4

22

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
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Is it ok if I Translate and Dispatch one message more than one time, or not translate and dispatch message at all? - I have tested and seen no problem, but I just want to make sure it's really no problem. – 123iamking Apr 06 '17 at 14:18
12

They are different beasts.

For TranslateMessage 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.

Community
  • 1
  • 1
Jorge Ferreira
  • 96,051
  • 25
  • 122
  • 132
  • 1
    After a message has been translated, will the virtual key message still get dispatched by DispatchMessage? – Jeroen Aug 06 '14 at 12:11
  • @JeroenBollen Yes, since `TranslateMessage` pushes the translation result on the message queue instead of modifying the message you pass to it. Therefore both the translated version and the virtual key original are dispatched. – Kotauskas Aug 26 '19 at 11:16
2

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.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
zdan
  • 28,667
  • 7
  • 60
  • 71
1

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
  • 76,898
  • 55
  • 205
  • 325