2008-11-21 4 views

ответ

4

Вы хотите использовать крюки Win32. В частности, клавиатурный крючок.

You can read more about it here

Тип крюка вы хотите это WH_KEYBOARD и вы можете установить его с помощью Win32 API SetWindowsHookEx.

В основном окна будут вызывать функцию в DLL, которую вы создаете каждый раз, когда клавиша нажата в любой прикладной системе.

Крюк будет вызывать функцию, которая будет иметь этот интерфейс:

LRESULT CALLBACK KeyboardProc(  
    int code, 
    WPARAM wParam, 
    LPARAM lParam 
); 

More information about this callback here.

С помощью оконных крючков вы можете не только отслеживать события в системе во всех процессах, но также можете фильтровать их и полностью их останавливать.

2

Посмотрите на крючки можно установить с SetWindowHookEx:

http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx

Однако, если вы не работаете в «интерактивный» сервис, вы не будете иметь доступ к рабочему столу (и вы не должны Не запускайте интерактивную службу, потому что она не будет работать в новых версиях Windows. Для доступа к рабочему столу/консоли вам нужно будет заглянуть в интерфейсы управления сеансом и настольным управлением.

0

Заканчивать Необработанный Input API в MSDN:

http://msdn.microsoft.com/en-us/library/ms645536(VS.85).aspx

Это позволяет получить ввод от клавиатуры (среди прочего), не возиться с глобальными крючками. Глобальные крючки следует использовать только в качестве крайней меры, поскольку они могут привести к непредвиденным последствиям.

Единственным недостатком использования Raw Input является то, что он может неправильно получать нажатия клавиш, которые генерируются программным обеспечением.

0

Если вы реализуете это в приложении .net, я бы порекомендовал GlobalKeyboardHook. В противном случае я бы посмотрел его источник и воспользовался тем, что вам нужно, поскольку он реализует упомянутые выше функции DLLImport.

1

Просто используйте встроенную функцию GetKeyState или GetAsyncKeyState или GetKeyboardState из библиотеки user32.

Вы можете прочитать о каждой функции я уже упоминал выше, на сайте MSDN:

ч TTP: //msdn.microsoft.com/en-us/library/windows/desktop/ms646301 (v = vs.85) .aspx

для GetKeyState и

ч TTP: //msdn.microsoft.com/en-us/library/windows/desktop/ms646293 (v = vs.85).ASPX

для GetAsyncKeyState и

ч TTP: //msdn.microsoft.com/en-us/library/windows/desktop/ms646299 (v = vs.85) .aspx

для GetKeyboardState.

Если вы программируете на C#, то:

Ваш код должен содержать следующую строку из любого класса, структуры или перечисления декларации:

using System.Runtime.InteropServices; 

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

[DllImport("user32.dll")] 
static uint GetKeyState(byte virtualKeyCode); 

//or 

[DllImport("user32.dll")] 
static uint GetAsyncKeyState(byte virtualKeyCode); 

//or 

[DllImport("user32.dll")] 
static uint GetKeyboardState(byte[] virtualKeyCodes); 
//NOTE: The length of the byte array parameter must be always 256 bytes! 

Если вы не любите UINT как тип возвращаемого значения, вы можете также изменить его Int.

Если нативные функции всегда возвращают 1 как истинные или 0 как false, то вы можете изменить их тип возврата на bool, но если вы это сделаете, то я думаю, вы должны добавить еще одну строку кода над родной определение функции, которая является:

[MarshalAs(UnmanagedType.Bool)] 

ИЛИ вы можете добавить следующую строку в середине нативного определения функции (ниже линии, где слово DllImport есть, и выше линии, где «Экстерн» слово есть):

[return: MarshalAs(UnmanagedType.Bool)] 

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

Следующая ссылка приводит к определению GetKeyState в C#:

ч TTP: //www.pinvoke.net/default.aspx/user32.getkeystate

Следующая ссылка приводит к определение GetAsyncKeyState в C#

ч TTP: //www.pinvoke.net/default.aspx/user32.getasynckeystate

в followi нг ссылка приводит к определению GetKeyboardState в C#

ч TTP: //www.pinvoke.net/default.aspx/user32.getkeyboardstate

Для того, чтобы определить, какой ключ удерживается в нажатом положении (в любой момент , в любом месте) затем вызвать GetKeyState или GetAsyncKeyState функцию, в одном параметре, упомяните ключ, который вы хотите, чтобы обнаружить, а затем добавить: & 0x8000 или & 0x80 после вызова. Если указанный ключ удерживается нажатой, то возвращаемое значение выражения не равно нулю, но в остальном оно равно нулю. В соответствии с возвращаемым целым выражением вы можете определить, какой ключ удерживается или нет. Обратите внимание, что если вы вставляете код внутри оператора if с этим выражением! = 0 в качестве условия ввода, который находится внутри цикла, код в этом операторе if будет выполняться более одного раза, фактически много раз, когда вы удерживаете это ключ. Если вы хотите какой-то код будет выполняться раз При нажатии на клавишу, а затем отпустить его, то следующий код трюк, который достигает этой цели:

while (boolean exression that will return false when you want to quit this loop) 
{ 
    if (boolean expression that will return true when particular key is **held down**) //This boolean expression calls either GetKeyState or GetAsyncKeyState with the & 0x8000 or & 0x80 after the call, and then != 0 to check for **held down** key 
     while (true) //It's purpose is to wait for the same key that was held down to be released. After code execution, it will encounter the break keyword that will finish him, even though that his enter condition is true. 
      if (boolean expression that will return true when the **same** particular key is **NOT** held down! (NOT held down, means that at that time, that key was released). You can copy the same condition from the first if statement, and just change **!=**, which is next to 0, to **==**, or instead add brackets to the condition '(' and ')', and in left of '(' add '!'). 
      { 
       //Put here the code that you want to execute once, when paticular key was pressed and then released. 
       break; //the while (true), which is the only way to get out of it 
      } 
} 
Смежные вопросы