2010-01-14 107 views
2

我正在創建自定義鍵盤佈局。作爲開始的一步,我想讓用戶按下一個鍵,讓我的鍵盤鉤子攔截它,並輸出我選擇的不同鍵。使用低級別鍵盤掛鉤更改鍵盤字符

我發現這個鍵盤鉤子代碼,我想稍微修改一下我的目的: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx

我已經改變了相關的方法是:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
    { 
     KBDLLHOOKSTRUCT replacementKey = new KBDLLHOOKSTRUCT(); 
     Marshal.PtrToStructure(lParam, replacementKey); 
     replacementKey.vkCode = 90; // char 'Z' 
     Marshal.StructureToPtr(replacementKey, lParam, true); 
    } 
    return CallNextHookEx(_hookID, nCode, wParam, lParam); 
} 

我希望它聲明一個新的KBD結構對象,將鍵盤鉤子提供的KBD結構複製到它中,修改我的對象的vkCode以使用不同的字符,然後用我的修改版本覆蓋提供的對象。這應該有希望保持一切,除了它寫一個不同的字符。

不幸的是,它不工作。鍵入原始鍵盤字符。 Visual Studio輸出窗格也會得到一個A first chance exception of type 'System.ArgumentException' occurred in MirrorBoard.exe錯誤。

我可以在這裏做些什麼來攔截鍵盤鉤子並將其替換爲我選擇的字符?

謝謝!

回答

4

Marshal.PtrToStructure的第二個參數必須是一個類而不是結構,而KBDLLHOOKSTRUCT可能是一個結構。

相反,你應該使用這樣的:

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

Visual Studio中告訴我,它的'Marshal.PtrToStructure(IntPtr的PTR,對象結構);'...不跟你說什麼花言巧語?它不會拋出錯誤或任何東西,編譯得很好。 – cksubs 2010-01-14 07:39:02

+0

它編譯得很好,但在運行時拋出'ArgumentException'。 – 2010-01-14 07:41:13

+0

如果它沒有將Ptr保存到結構中,爲什麼它會被稱爲PtrToStructure?但是如果我確實需要改變它,我應該在這裏做什麼?如果我不能使用KBD結構來保存指向KBD結構的指針,我該如何修改它? – cksubs 2010-01-14 07:47:55