Иногда бывает необходимо отлавливать события внутри приложения вне зависимости от того, какой контрол активен. Например, вы хотите реализовать аналог "IDDQD" в своем приложении ;))) Или просто хотите обрабатывать события по каким-то своим законам. Сегодня я расскажу вас как это сделать.
Для начала создадим класс, который наследует от IMessageFilter, и создать в нем события которые будут вызываться в процессе обработке. В моем случае - это для события: для нажатия клавиши на клавиатуре и прокрутки колесика мыши. Интерфейс IMessageFilter представляет только один член - метод PreFilterMessage в котором и происходит обработка очереди событий.
Да, и для каждого события нам нужен делегат описывающий сигнатуру вызова.
public delegate void MouseWheelEvent(int rotation); public delegate void KeyDownEvent(int keyCode); public class GlobalEventHandler : IMessageFilter { public event MouseWheelEvent TheMouseWheel; public event KeyDownEvent TheKeyDown; public bool PreFilterMessage(ref Message m) { } }следующий этап - реализовать метод PreFilterMessage:
public bool PreFilterMessage(ref Message m) { //WM_MOUSEWHEEL if (m.Msg == 0x20A) { if (TheMouseWheel != null) { try { TheMouseWheel(m.WParam.ToInt32()); } catch { } //возвращаем true, чтобы предотвратить дальнейшую обработку события return true; } } //WM_KEYDOWN else if (m.Msg == 0x100) { if (TheKeyDown != null) { try { TheKeyDown(m.WParam.ToInt32()); } catch { } //еcли дальнейшую обработку предотвращать не нужно, то возвращаем false //в таком случае, и вы будете знать о нажатии клавиши, и, например, textbox получит событие нажатия return false; } } return false; }
Внутри этого метода вы можете отлавливать какие угодно события. Вот тут их относительно полный список ( http://msdn.microsoft.com/en-us/library/ms644927%28v=VS.85%29.aspx#system_defined )
Ну и последний этап - нам надо написать методы обработчиков событий. Обратите внимание на строчку получения смещения из параметра delta. В сообщении WM_MOUSEWHEEL смещение прокрутки колеса находится в старшем слове параметра. Так, что, нам нужно сдвинуть его значение вправо и обрезать до short. Это я к тому, что внимательнее читайте описание сообщений
public void WheelRotate(int delta) { short realRotateDelta = ((short)(delta >> 16)); textBox1.Text += realRotateDelta.ToString() + Environment.NewLine; } public void KeyPressed(int keyCode) { textBox1.Text += keyCode.ToString() + Environment.NewLine; }
И, добавить ваш фильтр в очередь обработки сообщений приложения. Делать это нужно в Form_Load
private void Form1_Load(object sender, EventArgs e) { GlobalEventHandler geh = new GlobalEventHandler(); geh.TheMouseWheel += new MouseWheelEvent(WheelRotate); geh.TheKeyDown += new KeyDownEvent(KeyPressed); Application.AddMessageFilter(geh); }
Вот и все.
Комментариев нет:
Отправить комментарий