2016-06-14 44 views
4

在我的具體情況下,我試圖創建一個應用程序,將鍵盤按鍵發送到DosBox(DOS遊戲模擬器,而不是Windows命令提示符)。C#.net發送鍵不使用SendKey()而是使用連接mabye

我試着用SendKeys來做,但那不起作用,因爲DosBox不是一個處理Windows消息的應用程序(一個例外告訴了我)。

目前,我正在試圖做的是使用鍵盤鉤子,像這樣: 第一種方法是接收鉤鍵擊,並把它們傳送到下一個應用程序(如在this example

private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     return CallNextHookEx(hookId, nCode, wParam, lParam); 
    } 

    private void GenerateKeyPress() 
    { 
     int vkCode = (int)Keys.Up; //My chosen key to be send to dosbox 
     IntPtr lParam = new IntPtr(vkCode); 
     IntPtr wParam = new IntPtr(255); 

     CallNextHookEx(hookId, 0, wParam, lParam); 
    } 
的一個

但CallNextHookEx()函數調用會引發訪問衝突異常。

我在這裏需要考慮什麼?

回答

4

訪問衝突是通過以下事實:LPARAM用於low-level keyboard hook,即引起的,一個與

SetWindowsHookEx(WH_KEYBOARD_LL,...) 

創建是一個指向KBDLLHOOKSTRUCT,而不是一鍵碼僞裝成一個指針。您正在告訴鉤子鏈中的下一個鉤子以訪問任意的內存位置。 (另外,WPARAM應該是WM_KEYDOWN之一,WM_KEYUPWM_SYSKEYDOWN,或WM_SYSKEYUP。)

您鏈接的示例代碼,使用Marshal.ReadInt32(lParam)拿到鑰匙代碼,這實際上是讀結構中引用的第一個整數由指針。

至於你想實現什麼,做它的方式是使用SendInput這是一個主題,就是beencoveredheresomanytimesthatitdoesnotbearrepeating.


(這甚至不是所有的SendInput問題)

0

我認爲你應該使用「keybd_event」來代替「SendKeys」。

public static class Keyboard 
{ 
    public static void Press(Keys keys, int sleep = 1) 
    { 
     var keyValue = (byte)keys; 

     NativeMethods.keybd_event(keyValue, 0, 0, UIntPtr.Zero); //key down 

     Thread.Sleep(sleep); 

     NativeMethods.keybd_event(keyValue, 0, 0x02, UIntPtr.Zero); //key up 
    } 
} 

internal static partial class NativeMethods 
{ 
    [DllImport("user32.dll")] 
    internal static extern void keybd_event(byte bVk, byte bScan, int dwFlags, UIntPtr dwExtraInfo); 
}