Фильтрация очереди сообщений Windows - PullRequest
0 голосов
/ 13 мая 2011

У меня есть процедура, которая выглядит примерно так, в псевдокоде:

while PeekMessage(Message, 0, 0, 0, PM_REMOVE)
  HandleMessageAppropriately(Message)

По сути, он проходит и извлекает все сообщения из очереди и отправляет их. Я не могу изменить эту рутину.

У меня есть сценарий, в котором эта подпрограмма, если она вызывается при определенных условиях и в очереди есть сообщение о том, что пользователь нажал ESC в самый неподходящий момент, может вызвать сбой программы. (Должен любить условия гонки.)

Я не могу изменить приведенную выше процедуру, но я могу изменить код, который ее вызывает. Есть ли какой-нибудь способ, которым я могу сделать что-то непосредственно перед запуском, которое скажет «пройти через очередь сообщений и удалить все сообщения ввода с клавиатуры, когда пользователь нажимает ESC, , не затрагивая остальные элементы в очереди или изменяя их заказ"?

Ответы [ 3 ]

3 голосов
/ 13 мая 2011

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

Вы не возитесь с этим, вы вызываете EnableWindow (hWnd, FALSE) перед тем, как войти в этот цикл, чтобы отключить ввод в окне, которое не должно закрываться. Теперь вас больше не волнует, что находится в очереди сообщений. Точно так же, как это делают диалоги.

Не обматывайте модальную петлю. Сделайте это модальным, сделайте это очевидным и для пользователя.

3 голосов
/ 13 мая 2011

Вы можете использовать параметры диапазона в PeekMessage, чтобы ограничиться только сообщением WM_CHAR, и PM_NOREMOVE, чтобы оставить очередь сообщений нетронутой, если символ не ESC; если сообщение необходимо удалить, повторите процесс с флагом PM_REMOVE. К сожалению, нет возможности заглянуть за первый WM_CHAR в очереди.

0 голосов
/ 13 мая 2011

Возможно, вам лучше всего подключить вызов к PeekMessages и заменить его версией, которая делает то, что вам нужно.

Вы можете использовать процедуры перехвата Мэдши, но это не сложно - я опубликовал простую процедуру перехвата здесь, в Переполнении стека.

Если код выполнялся в исполняемом модуле, который вы компилируете, вы можете скомпилировать настроенную версию Windows.pas, которая заменила PeekMessage. Конечно, я предполагаю, что твой код - Delphi.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...