Отвечать на клавиатуру, когда не в фокусе? (C #, Vista) - PullRequest
5 голосов
/ 09 февраля 2009

Я пытаюсь написать приложение, которое реагирует на нажатие клавиши Shift, независимо от того, какое приложение в данный момент находится в фокусе.

Я пробовал это с SetWindowsHookEx() и с GetKeyboardState(), но оба они работают только тогда, когда окно приложения имеет фокус. Мне нужно, чтобы он работал глобально.

Как мне это сделать?

Ответы [ 4 ]

5 голосов
/ 14 апреля 2009

Ни один из предоставленных ответов не помог мне решить мою проблему, но я сам нашел ответ. Вот оно.

Использование SetWindowsHookEx() с WH_KEYBOARD_LL было правильным подходом. Однако другие параметры SetWindowsHookEx() не интуитивны:

  • Последний параметр dwThreadId должен быть равен 0.
  • Второй-последний параметр, hMod, должен указывать на некоторую DLL. я использовал User32, которая является DLL, которая всегда загружается и используется всеми процессы с графическим интерфейсом. Я получил эту идею из сообщения CodeProject об этом .

Таким образом, код выглядит примерно так:

instance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookFunction, instance, 0);

В документации по второму последнему параметру неясно. Там написано:

Параметр hMod должен быть установлен в NULL [...], если подключаемая процедура находится в коде, связанном с текущим процессом.

Не говорится, что это относится только к некоторым типам крючков, но не к WH_KEYBOARD_LL и WH_MOUSE_LL.

5 голосов
/ 09 февраля 2009

Вам придется использовать SetWindowsHookEx (). Есть только два типа хуков, которые вы можете реализовать на управляемом языке, WH_KEYBOARD_LL и WH_MOUSE_LL. Все остальные хуки требуют DLL, которая может быть вставлена ​​в другой процесс. Управляемые библиотеки DLL не могут быть внедрены, CLR не может быть инициализирован.

Это сообщение в блоге имеет функциональный пример.

2 голосов
/ 09 февраля 2009

Если вы используете технику в посте, на который ссылается nobugz, вам нужно будет убедиться, что делегат не получает мусор, например с помощью GC.KeepAlive (_proc) при установке ловушки, в противном случае через неопределенный период ловушка перестанет работать, когда расслаивается GCed.

1 голос
/ 09 февраля 2009

Настройка крюка CBT смотрите здесь http://www.codeproject.com/KB/DLL/keyboardhook.aspx

...