Иногда бывает необходимо отлавливать события внутри приложения вне зависимости от того, какой контрол активен. Например, вы хотите реализовать аналог "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);
}
Вот и все.
Комментариев нет:
Отправить комментарий