2010-01-14 3 views
8

Я нашел эту клавиатуру крюк код, который я пытаюсь немного изменить для моих целей: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspxМогу ли я изменить ввод клавиатуры пользователя?

В качестве обзора, я хочу, чтобы пользователь нажать клавишу, скажем, «Е», и есть возвращение клавиатуры другой символ, «Z», для любого приложения, находящегося в фокусе.

Соответствующий метод, который я изменил теперь выглядит следующим образом:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     { 
      //The truely typed character: 
      int vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 

      KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); 
      replacementKey.vkCode = 90; // char 'Z' 
      Marshal.StructureToPtr(replacementKey, lParam, false); 

      //Now changed to my set character 
      vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 
     } 
     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

Консоль правильно выводит это так:

E 
Z 
T 
Z 
G 
Z 
etc. 

ОДНАКО, «E» ИН фокус приложения по-прежнему типов вместо «Z» , Зачем? Я изменил подключенный клавиатурный ввод, чтобы содержать «Z» вместо «E», а строки консоли показывают, что он был изменен правильно!

Как я понимаю, вызов return CallNextHookEx(_hookID, nCode, wParam, lParam); - это то, что отправляет команду «распечатать это сейчас» в открытое приложение. Разве это не так, как это работает? Есть ли что-то, что мешает мне печатать персонажа, которого я хочу? Я знаю, что приложения, такие как AutoHotkey, берут ключ ввода, проверяют его и возвращают другой символ. Как мне сделать то же самое здесь?

Спасибо!

+3

из любопытства, что это такое? –

+1

Это не кейлоггер! :) Приложение является вспомогательной технологией.Подумайте о клавиатуре iPhone; за кулисами, он изменяет ключевую область, исправляет очевидные ошибки и запускает другой смарт-код, который поможет вам печатать быстрее и точнее. Это аналогичное приложение, но для полноценных клавиатур. – cksubs

ответ

5

Я сделал это раньше, но немного иначе.
Вместо того, чтобы пытаться изменить параметры, отправленные на CallNextHookEx, я «проглотил» нажатие клавиши (вы можете сделать это, возвращая ненулевое значение из процедуры крючка, чтобы предотвратить последующие процедуры от вызова).

Затем я использовал SendInput, чтобы отправить новый ключ, который я хотел «ввести».

Поэтому в основном это работает так:

  • процедура Hook идентифицирует целевой ключ нажимается
  • Зова SendInput с новым ключом
  • Return 1 из процедуры крючков игнорировать оригинальный ключ

Будьте осторожны циклических переадресовывает, то есть «а» перенаправлены «Ъ» перенаправлены «а», он может легко взорвать;)

+0

Прохладный, я успешно проигнорировал исходный ключ с возвратом '(IntPtr) 1;' Теперь, как мне «SendInput»? Есть ли конкретный 'использование XXX', который мне нужно включить в заголовок, или другой код, который мне нужно добавить, чтобы использовать эту команду? – cksubs

+0

pinvoke.net имеет весь код, необходимый для вызова 'SendInput' - http://www.pinvoke.net/default.aspx/user32/SendInput.html –

+0

Хорошо, получилось, что он использует' [DllImport («coredll.dll», SetLastError = true)] static extern uint SendInput (uint cInputs,/* [MarshalAs (UnmanagedType.LPArray)] */KEYBOARDINPUT [] входы, int cbSize); 'и структура KEYBOARDINPUT. Теперь я работаю над передачей SendInput() правильных параметров. – cksubs

0

Вы, скорее всего, установили крючок «нить шириной», а не «шириной системы», что означает, что перевод ключа будет происходить только для резьбы, устанавливающей крюк.

Чтобы установить его «в системном порядке», вам понадобятся две части: одна dll, имеющая «поставщик крюка» и exe, управляющая им. Вот хороший учебник http://www.codeproject.com/KB/system/hooksys.aspx и вот пример: http://www.codeguru.com/cpp/com-tech/shell/article.php/c4509/

Но: 1. Установка общесистемные крючки могут серьезно испортить вашу систему (убедитесь, что вы пересылаете ключи, которые вы не переводить) , 2. Пожалуйста ... не создавайте еще один кейлоггер

+2

Он использует низкоуровневый клавиатурный крючок, а не обычный клавиатурный крючок. Крючок низкого уровня не нуждается в отдельной DLL, которая загружается в каждый процесс. От http://msdn.microsoft.com/en-us/library/ms644985.aspx - Однако крюк WH_KEYBOARD_LL не вводится в другой процесс. Вместо этого контекст переключается обратно на процесс, который установил hook, и он вызывается в его исходном контексте. Затем контекст переключается обратно в приложение, которое генерирует событие. –

+0

Итак ... это означает, что я правильно использую это? :) – cksubs

+0

Много информации об использовании/использовании WH_KEYBOARD_LL (и много обсуждений по вопросам обнаружения управляющих модификаторов, передачи ключевой информации в следующее приложение или блокировки и т. Д. В комментариях) CodeProject: http: // www. codeproject.com/KB/system/CSLLKeyboard.aspx «Низкоуровневые API-интерфейсы Windows от C#, чтобы остановить нежелательные нажатия клавиш». Эмма Берроуз. 2007. – BillW