2008-11-21 124 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 
      } 
}