Подтвердить что ты не робот

Почему отдельные вызовы "TranslateMessage" и "DispatchMessage"?

Большинство основных циклов Win32, которые я видел, структурированы так:

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

Было указано, что MsgWaitForMultipleObjects может использоваться для добавления некоторого разнообразия в основной цикл. Но есть ли сценарий, где что-то происходит между GetMessage, TranslateMessage и DispatchMessage действительно полезно?

4b9b3361

Ответ 1

Более традиционный цикл сообщений выглядит следующим образом:

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

Это довольно большой намек на то, что вы хотели бы сделать, прежде чем отправлять сообщение: поймать сообщения, которые следует перехватить и обработать специально, прежде чем окно их увидит. Ярлыки клавиш являются классическим примером, они должны быть обнаружены независимо от того, какое окно имеет фокус.

Любая библиотека классов GUI предоставляет ее с помощью виртуального метода с именем вроде App.PreProcessMessage, виртуальной функции, которая может быть переопределена, поэтому ваша программа может реализовать свои собственные ярлыки и многое другое.

Ответ 2

Они разные звери.

Для Функция TranslateMessage

Переводит сообщения виртуальных клавиш в символьные сообщения. Персонаж сообщения отправляются на вызов очередь сообщений потока, для чтения в следующий раз поток вызывает GetMessage или PeekMessage. [...] Функция TranslateMessage не изменить сообщение, на которое указывает lpMsg.

DispatchMessage, с другой стороны, отправляет сообщение в оконную процедуру.

Итак, DispatchMessage выполняет фактическую работу по обработке сообщения. TranslateMessage МОЖЕТ или НЕ МОЖЕТ отправить новое сообщение в очередь потоков. Если сообщение переводится, сообщение символа отправляется в очередь сообщений потока.

Функция TranslateMessage не изменить сообщение, на которое указывает lpMsg.

Это отдельные вызовы, поэтому у вас, программиста, есть шанс избежать перевода сообщения, предоставляемого TranslateMessage.

Ответ 3

Ну, чтобы привести пример из MSDN:

Вы можете модифицировать цикл сообщений различными способами. Например, вы можете получать сообщения из очереди, не отправляя их в окно. Это полезно для приложений, которые публикуют сообщения, не указывающие окно. Вы также можете направлять GetMessage для поиска конкретных сообщений, оставляя другие сообщения в очереди. Это полезно, если вы должны временно обходить обычный порядок FIFO очереди сообщений.

Вы также можете избежать вызовов для перевода сообщения, если вам не нужно преобразовывать коды управления клавиатурой.

Ответ 4

TranslateMessage() преобразует сообщения виртуальных клавиш в сообщения ввода символов.

Это отдельный вызов удаленной случайности, что при определенных обстоятельствах вы не хотите создавать сообщения ввода символов для определенных виртуальных клавиш.