Почему отдельные вызовы "TranslateMessage" и "DispatchMessage"?
Большинство основных циклов Win32, которые я видел, структурированы так:
while (GetMessage(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
Было указано, что MsgWaitForMultipleObjects
может использоваться для добавления некоторого разнообразия в основной цикл. Но есть ли сценарий, где что-то происходит между GetMessage
, TranslateMessage
и DispatchMessage
действительно полезно?
Ответы
Ответ 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()
преобразует сообщения виртуальных клавиш в сообщения ввода символов.
Это отдельный вызов удаленной случайности, что при определенных обстоятельствах вы не хотите создавать сообщения ввода символов для определенных виртуальных клавиш.