2010-11-25 2 views
6

Я хочу сделать приложение для перехвата всех событий пользовательского интерфейса во всех формах моего приложения и записи их в журнал. Эти данные могут использоваться, чтобы определить, какие элементы управления наиболее используются, в каком порядке и т. Д. Проблема заключается в том, что я хочу, чтобы это произошло автоматически, без изменения существующих классов.Перехват события click для всех элементов управления в приложении в C# (WinForms)

Я сделал прототип, который прикрепляет метод к событию click для всех элементов управления в форме, но как это можно сделать для всех форм? Отражение требует целевого объекта при манипулировании событиями, но можно легко получить доступ только к форме запуска.

Есть ли способ подключить конструктор объекта? Тогда я мог бы «ввести» мой метод во все события новой формы. Или, может быть, есть еще один способ сделать это.

Заранее спасибо!

ответ

7

Вы можете установить message filter.

Фильтр сообщений - это объект, который реализует IMessageFilter. WinForms вызывает ваш метод PreFilterMessage для каждого сообщения, которое проходит через цикл сообщений вашего потока. Этого достаточно, чтобы контролировать вход пользователя через приложение (и дает вам возможность манипулировать им).

1

В Windows API это делается с использованием локальных крючков (вы можете установить локальный крючок мыши с помощью функции SetWindowsHookEx). Это правильный способ выполнить свою задачу. В C# вам нужно использовать P/Invoke для доступа к SetWindowsHookEx.

Еще одна задача - совместить HWND (дескриптор Windows) с соответствующим элементом управления WinForms. Прочитайте this article, как это сделать (через сообщение WM_GETCONTROLNAME).

Также см. this question, который является вашим дубликатом.

0

Вы должны быть в состоянии добиться того, что хотите, с message filters - нет прямого P/Invoke для Win32-API требуется!

Для получения дополнительной информации см. Справку по интерфейсу IMessageFilter.