2008-11-21 174 views

回答

4

您想使用Win32挂钩。特别是一个键盘钩子。

You can read more about it here

的类型,你要挂钩的是WH_KEYBOARD,您可以通过Win32 API的调用SetWindowsHookEx设置。

基本上,Windows将调用一个dll中的函数,每次在任何应用程序系统中按下某个键时创建该函数。

挂钩将调用函数,都会有这样的接口:

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

More information about this callback here

使用windows挂钩,您不仅可以跟踪所有进程中的系统范围事件,还可以过滤它们并完全停止它们。

2

看一看挂钩,你可以用SetWindowHookEx设置:

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

但是,除非你正在运行的“互动”的服务,您将无法访问到桌面(和你不应该不会运行交互式服务,因为它不适用于更新版本的Windows)。您必须查看会话和桌面管理API才能访问桌面/控制台。

0

在MSDN退房原始输入API:

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

它可以让你从键盘输入(除其他事项外),而不与全局钩子乱搞。全球性的钩子只能作为最后的手段,因为它们可能会带来意想不到的后果。

使用原始输入的唯一缺点是它可能无法正确接收由软件生成的击键。

0

如果你在.net应用程序中实现这个功能,我建议使用GlobalKeyboardHook,否则我会考虑它的源代码,并且因为它正在实现上面提到的DLLImport函数而需要它。

1

只需使用user32 DLL的本机函数GetKeyState,GetAsyncKeyState或GetKeyboardState即可。

你可以阅读我在MSDN网站上面提到的每一个功能:

^h 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为假,那么你就可以改变他们的返回类型布尔代替,但如果这样做的话,那么我认为你应该添加上述本机的另一行代码函数的定义,那就是:

[MarshalAs(UnmanagedType.Bool)] 

OR你可以在本地函数定义的中间添加以下行(其中的DllImport字线之下,而行,上面对“EXTERN”字是):

[return: MarshalAs(UnmanagedType.Bool)] 

Pinvoke网站为这些功能提供了更好的定义,因此您不必使用整数来提及键盘的特定键,而是更易于理解的枚举。

以下链接导致函数GetKeyState的定义在C#:

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

以下链接导致在C#中的GetAsyncKeyState的定义

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

的followi NG链接指向在C#中的GetKeyboardState的定义

^h TTP://www.pinvoke.net/default.aspx/user32.getkeyboardstate

检测哪个键被按下(在任何时间,任何地方),然后调用GetKeyState或GetAsyncKeyState函数,在单个参数中,提及要检测的密钥,然后添加:& 0x8000& 0x80之后的调用。 如果提到键被按下,则表达的返回值不为零,但除此之外,它是零。 根据返回的表达式的整数,您可以确定是否按下哪个键。 请注意,如果你把里面的代码,如果与表达式语句!= 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 
      } 
}