Отслеживаем Windows события в Вашем .NET приложении

четверг, 2 апреля 2009, Oleksandr Reminnyi

Возникла сегодня задача... Сделать возможность приложению реагировать на нажатие клавиш. Ничего сложного, если у вас одна форма(или контрол), для которой можна перегрузить OnKeyPress или добавить делегат обработчик события KeyPress.

Вот только приложение у меня многоуровневое и вложеность контролов была довольно большая. Полазив в интернете нашел такое описание: Когда есть выбраная ячейка в DataGrid, событие нажатия клавиши не попадет в обработчик к DataGrid, его перехватит ячейка - сделано для того, чтобы можно было двигаться по таблице с помощью клавиш навигации. По аналогии сообразил, что и в моем приложении нельзя перехватить сообщения клавиш, так как они отлавливаються в контролах. Неудобно было бы лопатить весь свой код, а также код сторонних разработчиков контролов, который я использую, для добавления обработчиков нажатия клавиш и пересылки сообщений главной форме. Поэтому я продолжил поиск.

И наиболее интересным мне представилась возможность отлавливать сообщения на уровне Windows. Для этого можно использовать вспомогательный функции WindowsHook. Они не являються управляемыми, однако довольно точно исполняют нужную задачу.

Суть в том, что Вы практически подписываетесь через колбек на низкоуровневые сообщения Windows. Соответственно, обрабатывая их по своей логике, можете использовать информацию по назначению.

Рассмотрим пример консольного приложения, отлавливающего нажатие клавиш. Скопируйте в консольный проект, скомпилируйте и запустите.

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class InterceptKeys
{
  private const int WH_KEYBOARD_LL = 13;
  private const int WM_KEYDOWN = 0x0100;
  private static LowLevelKeyboardProc _proc = HookCallback;
  private static IntPtr _hookID = IntPtr.Zero;

  public static void Main()
  {
    _hookID = SetHook(_proc);
    Application.Run();
    UnhookWindowsHookEx(_hookID);
  }

  private static IntPtr SetHook(LowLevelKeyboardProc proc)
  {
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
      return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
        GetModuleHandle(curModule.ModuleName), 0);
    }
  }

  private delegate IntPtr LowLevelKeyboardProc(
    int nCode, IntPtr wParam, IntPtr lParam);

  private static IntPtr HookCallback(
    int nCode, IntPtr wParam, IntPtr lParam)
  {
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
      int vkCode = Marshal.ReadInt32(lParam);
      Keys pressed = (Keys)vkCode;
      if (pressed == Keys.Space)
        Console.Write(" ");
      else if (pressed == Keys.Return || pressed == Keys.Tab)
        Console.Write(Environment.NewLine);
      else if (pressed >= Keys.A && pressed <= Keys.Z)
        Console.Write(pressed);
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
  }

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  private static extern IntPtr SetWindowsHookEx(int idHook,
    LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  [return: MarshalAs(UnmanagedType.Bool)]
  private static extern bool UnhookWindowsHookEx(IntPtr hhk);

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
    IntPtr wParam, IntPtr lParam);

  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  private static extern IntPtr GetModuleHandle(string lpModuleName);
}

Теперь вы подписаны на нажатие клавишь на клавиатуре. Список сообщений, на которые вы можете подписатся можно найти здесь.Так можно просто прятать ваше приложение или востанавливать, реализовывать hotkeys.

П.С. Если запустить это приложение невидимо в фоне вы практически можете записывать все свои(и не только;) ) действия на компьютере. А если тут еще и добавить отправку через интернет....

Пользуйтесь на здоровье.

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии