Как подключиться к конкретному сообщению Windows без подклассов? - PullRequest
1 голос
/ 06 мая 2010

Есть ли способ перехватить конкретное сообщение Windows, не разбивая окно на подклассы.

Существует WH_GETMESSAGE, но это создает проблемы с производительностью.

Есть ли другие решения, кроме тех, которые не ухудшают производительность?

1 Ответ

3 голосов
/ 06 мая 2010

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

Давайте подумаем, по какому пути проходит сообщение, пока оно не будет обработано окном:

  1. Сообщение либо публикуется, либо отправляется в окно либо явным вызовом PostMessage / SendMessage, либо неявно операционной системой.
  2. Только отправленные сообщения: в конце концов поток извлекает это сообщение из очереди сообщений (вызывая GetMessage или аналогичный), а затем вызывает DispatchMessage.
  3. ОС вызывает процедуру окна, вызывая CallWindowProc (или аналогичный).
  4. CallWindowProc идентифицирует процедуру окна, связанную с окном (через GetClassLong / GetWindowLong)
  5. Вышеуказанная процедура называется.

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

  1. Причины производительности.
  2. Вы получите уведомление только для окон, созданных в определенной теме
  3. Вы будете получать уведомления только для опубликованных сообщений (отправленные сообщения не будут видны)
  4. «Размещенное» сообщение не обязательно означает «доставлено». То есть он может фильтроваться циклом сообщений (отбрасываться без вызова DispatchMessage).
  5. Вы не можете видеть, что фактическое окно делает и возвращает для этого сообщения.

Так что подклассы кажутся намного лучше.

Еще одно решение - если ваше конкретное сообщение отправлено (а не отправлено), вы можете переопределить цикл обработки сообщений, и для каждого полученного сообщения вы можете выполнить некоторую предварительную / постобработку

...