Сообщения и очереди. Трансляция клавиш ускорения. Фильтрация сообщений, страница 3

5.3.9. Фильтрация сообщений

Любая ПП может фильтровать сообщения, которые в противном случае обрабатываются циклом основной программы системы WINDOWS. Для фильтрации сообщений установливается функция фильтрации сообщений, которую WINDOWS может вызывать всякий раз, когда ПП выполняет функцию GetMessage. Функция фильтрации  вызывается  перед  любой обработкой. Как только функция фильтрации вызвана, она может обработать сообщение и возвратить TRUE или ничего не сделать  и  возвратить  FALSE.  Если функция фильтрации возвращает TRUE, WINDOWS  не  производит дальнейшей  обработки  сообщений. Если она возвращает FALSE,

WINDOWS обрабатывает сообщение. Функция фильтрации может также модифицировать сообщение и возвратить FALSE для того, чтобы позволить WINDOWS обработать модифицированное сообщение.

WINDOWS передает в функцию фильтрации код, указывающий причину ее вызова. Для каждой ПП установлен один фильтр. Это означает, что фильтр "видит" только  те  сообщения,  которые относятся к ПП пользователя.

Можно установить функцию фильтрации, используя функцию SetWindowsHook. Вызов имеет вид:

SetWindowsHook(WH_MSGFILTER,fnFilterProc);

где fnFilterProc - это длинный указатель на функцию фильтрации. Функция фильтрации должна иметь вид:

BOOL FAR PASCAL FilterProc( )

Для создания корректного адреса экземпляра для функции фильтрации должна быть использована функция MakeProcInstance.

Если ПП использует свой собственный стек (т.е. в файле определения модуля имеет строку STACKSIZE), fnFilterProc должен быть описан следующим образом:

BOOL FAR PASCAL fnFilterProc(dummy,pMsg,code)

WORD dummy;

PMSG pMsg; int code;

В противном случае fnFilterProc должен быть описан так: BOOL FAR PASCAL fnFilterProc(lpMsg,code) LPMSG lpMsg;

int code;

где pMsg или lpMsg - указатель на структуру данных MSG, а code - это значение, указывающее контекст, в котором вызывается функция фильтрации. Он может быть одним из следующих:

MSGF_DIALOGBOX      -   внутри панели диалога;

MSGF_MESSAGEBOX  -   внутри панели сообщения;

MSGF_SIZE                     -   задание размеров окон;

MSGF_MOVE                 -   перемещение окна;

MSGF_MENU                 -   отслеживание меню.

5.3.10. Фильтрация сообщений для класса окна

Функция SetClassLong полезна для таких задач, как фильтрация сообщений заданного класса. Для установки функции класса окна на адрес функции фильтрации можно использовать значение GCL_WNDPROC. SetClassLong возвращает адрес функции окна по умолчанию, который ПП должна запомнить и использовать для обработки сообщений, не подлежащих фильтрации.

Приведенный ниже пример иллюстрирует как фильтровать сообщения, используя функцию SetClassLong:

FARPROC lpOldProc lpOldProc=SetClassLong(GCL_WNDPROC,(FARPROC)NewProc); Перед окончанием работы ПП должна восстановить первоначальный адрес функции окна.

Чтобы выполнить то же самое для отдельного окна (а не для целого класса), следует использовать функцию SetWindowLong.