COM-объект для перехвата сообщений, получаемых окнами(формами)
COM-объект предназначен для перехвата и обработки сообщений, посылаемых Windows к формам приложения. Возможно как слежение, так и собственная обработка сообщений.
COM-объект для перехвата сообщений, получаемых окнами(формами)
Как известно, Фокс не позволяет получить доступ к своему циклу сообщений. Поэтому, для перехвата
сообщений необходимо организовывать subclassing окон(форм). Данный объект предназначен именно для
этого.
В архиве FoxSubclass.zip расположена FoxSubclass.Dll и исходники. Объект необходимо
зарегистрировать в системе с помощью вызова regsvr32 c:\path\FoxSubclass.dll.
ProgID объекта: FoxSubclass.WndSubclass
Реализованы следующие методы:
1. SubclassWindow(hWnd, szHandler, bReceiveAll) - "главный" метод, собственно осуществляющий
subclassing.
hWnd - окно, сообщения которого надо перехватывать
szHandler - ф-ция в Фоксе, которая будет вызываться для обработки сообщений (только имя)
bReceiveAll - если TRUE, то получать все сообщения, иначе, только те сообщения, которые добавлены
с помощью метода AddMessage()
2. AddMessage(hWnd, uMsg, uPlace) - добавляет сообщение к карте сообщений и позволяет получать
указанное сообщение в обработчике (szHandler).
hWnd - окно, которое указывалось при вызове метода SubclassWindow
uMsg - номер сообщения
uPlace - положение вашего обработчика в цепочке вызовов (0 - ваш обработчик вызывается до
стандартного обработчика, 1- после стандартного, 2 - до и после стандартного).
3. ChangeMessageParam - данный метод изменяет параметры обрабатываемого сообщения WPARAM и LPARAM
(иногда необходимо, если вы сами обрабатываете сообщение). Данный метод действителен только в
момент обработки сообщения.
4. UnSubclassWindow, RemoveMessage, RemoveMessageAll - я думаю понятно, для чего эти методы.
Свойства объекта:
1. pFoxDispatch - указатель на интерфейс Dispatch Фокса. Необходимо для всязи объекта с Фоксом,
устанавливайте это свойство ДО вызова любого другого методаю. Обычно pFoxDispatch = _vfp.
2. IsHandled - позволяет указать, что сообщение обработано и дальнейшая обработка не требуется.
Установка данного свойства в TRUE в вашем обработчике позволяет пропустить обработку сообщения
стандартным обработчиком. В этом случае вся необходимая работа по обработке сообщения должна
выполняться вашим обработчиком. Также значение этого свойства позволяет узнать, в каком месте
цепочки вызовов стоит ваш обработчик. Если при вызове вашего обработчика это свойство установлено
в .F., то стандартная обработка еще не была выполнена и ваш обработчик вызывается до стандартного.
Если .Т. - то обработка уже была выполнена и ваш обработчик вызывается ПОСЛЕ стандартного (либо и
ДО и ПОСЛЕ).
Обработчик на Фоксе должен быть доступен глобально и иметь следующий формат: Имя_обработчика(hWnd,
uMsg, wParam, lParam), где hWnd - хендл окна, получившего сообщение; uMsg - номер сообщения;
wParam - параметр WPARAM сообщения; lParam - параметр LPARAM сообщения. Если вы сами
обрабатывается сообщение, то возвращаемое значение должно быть численным и зависит от сообщения
(см. MSDN).
Пример использования класса:
SET procedure to wndproc.prg && здесь находится наш обработчик WndProc(hWnd, uMsg, wParam,
lParam)
o = CreateObject("FoxSubclass.WndSubclass")
if vartype(o)<>"O"
return
endif
o.pFoxDispatch = _vfp && устанавливаем связь объекта с Фоксом
o.SubclassWindow(_vfp.hWnd, "WndProc", .F.) && subclassing главного окна Фокса
o.AddMessage(_vfp.hWnd, 6, 0) && перехватываем сообщение WM_ACTIVATE до вызова стандартного
обработчика
o.UnSubclassWindow(_vfp.hWnd)
Если сообщение WM_ACTIVATE обработано вашим обработчиком и стандартная обработка не требуется, то
необходимо в теле обработчика установить свойство IsHandled в TRUE (o.IsHandled = .T.).
Настоятельно рекомендую не использовать перехват всех сообщений (указание последнего параметра
SubclassWindow в .T.), т.к. это может вызвать падение производительности на медленных машинах.
Перехватывайте только те сообщения, которые вам необходимы.
В случае каких-либо замечаний или пожеланий обращайтесь по адресу: wiruc@mail.ru
Проект разработан с использованием Visual Studio.NET и ATL.
Разработчик: Колпачев Сергей aKa WiRuc
Проверил на всех доступных мне версиях Fox’а, работает. По ходу дела, два вопроса.
Первый: при выполнении метода SubclassWindow с даже с рекомендованным значением параметра
bReceiveAll=.f., происходит вызов процедуры назначенной по SET PROCEDURE, хотя метод AddMessage не
выполнялся.
Второй: можно ли ожидать расширения функциональности библиотеки, например для поддержки
API-функций, требующих вызова CallBack-процедур.
P.S. Удачи.
Колпачев Сергей
09.12.02 10:07:17
1. Первый вызов обработчика производится в методе SubclassWindow для проверки его доступности, при
этом в качестве параметров передаются нули. Этот момент я упустил в описании, каюсь...
2. А есть какие-либо конкретные пожелания? Расширение возможно, но таких функций очень много. Если
нужно что-то конкретно, то пишите мне на e-mail, я постараюсь максимально быстро обновить
библиотеку.