2013-06-25 5 views
4

DirectInput에 대한 도움이 필요합니다. 내 프로그램이 하나의 키만 누르면 키 조합을 게임에 보내고 싶습니다. 예 : "r"을 누르면 "1", "3", "2", "4"키가 선다. 나는 여기에서 몇 가지 코드를 발견했다. 그러나 그들은 정확하게 일하지 않았습니다.C# DirectInput SendInput 게임에 영향을 미치지 않습니다.

public static void Send_Key_Hold(short Keycode) 
    { 
     INPUT[] InputData = new INPUT[1]; 
     InputData[0].type = 1; 
     InputData[0].ki.wScan = Keycode; 
     InputData[0].ki.dwFlags = (int)(KEYEVENTF_SCANCODE); 

     SendInput(1, InputData, Marshal.SizeOf(InputData[0])); 
    } 
    public static void Send_Key_Release(short Keycode) 
    { 
     INPUT[] InputData = new INPUT[1]; 
     InputData[0].type = 1; 
     InputData[0].ki.wScan = Keycode; 
     InputData[0].ki.dwFlags = (int)(KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE); 

     SendInput(1, InputData, Marshal.SizeOf(InputData[0])); 
    } 

여기에 내 코드 내 질문은 : 나는 Send_Key_Hold을 사용하고 경우에만 먼저 키는 내가 생각 만들었 었지 때문에 누르지 게임 및 기타 조합 키에 하나의 키를 누른다. Send_Key_Hold와 Send_Key_Release를 함께 사용하면 게임의 아무 버튼도 누르지 않습니다. 하지만 바탕 화면 (나는 게임이 아닌 다른 응용 프로그램을 의미)에서 키를 누릅니다.

답변

3

인터넷에서이 예를 발견했습니다. 당신이 지금 시도하고있는 것과 똑같은 일을 시도했을 때 그것을 스스로 테스트했습니다.

[Flags] 
private enum InputType 
{ 
    Mouse = 0, 
    Keyboard = 1, 
    Hardware = 2 
} 

[Flags] 
private enum KeyEventF 
{ 
    KeyDown = 0x0000, 
    ExtendedKey = 0x0001, 
    KeyUp = 0x0002, 
    Unicode = 0x0004, 
    Scancode = 0x0008, 
} 

[DllImport("user32.dll", SetLastError = true)] 
private static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize); 

[DllImport("user32.dll")] 
private static extern IntPtr GetMessageExtraInfo(); 

public static void SendKey(ushort key) 
{ 
    Input[] inputs = 
    { 
     new Input 
     { 
      type = (int) InputType.Keyboard, 
      u = new InputUnion 
      { 
       ki = new KeyboardInput 
       { 
        wVk = 0, 
        wScan = key, 
        dwFlags = (uint) (KeyEventF.KeyDown | KeyEventF.Scancode), 
        dwExtraInfo = GetMessageExtraInfo() 
       } 
      } 
     } 
    }; 

    SendInput((uint) inputs.Length, inputs, Marshal.SizeOf(typeof (Input))); 
} 

private struct Input 
{ 
    public int type; 
    public InputUnion u; 
} 

[StructLayout(LayoutKind.Explicit)] 
private struct InputUnion 
{ 
    [FieldOffset(0)] public readonly MouseInput mi; 
    [FieldOffset(0)] public KeyboardInput ki; 
    [FieldOffset(0)] public readonly HardwareInput hi; 
} 

[StructLayout(LayoutKind.Sequential)] 
private struct MouseInput 
{ 
    public readonly int dx; 
    public readonly int dy; 
    public readonly uint mouseData; 
    public readonly uint dwFlags; 
    public readonly uint time; 
    public readonly IntPtr dwExtraInfo; 
} 

[StructLayout(LayoutKind.Sequential)] 
private struct KeyboardInput 
{ 
    public ushort wVk; 
    public ushort wScan; 
    public uint dwFlags; 
    public readonly uint time; 
    public IntPtr dwExtraInfo; 
} 

[StructLayout(LayoutKind.Sequential)] 
private struct HardwareInput 
{ 
    public readonly uint uMsg; 
    public readonly ushort wParamL; 
    public readonly ushort wParamH; 
} 

이제 활성 창 (또는 게임)에 T 키를 보낼 SendKey(0x14)를 사용합니다.

참고 : 플래그로 KeyEventF.Scancode이 필요하거나 wScan 속성이 무시됩니다.

+0

매직 플래그'Scancode'가 트릭을 만들었습니다. C++에서는 플래그가'KEYEVENTF_SCANCODE'입니다. – razzak

+0

당신은 이것을 사용하기 위해 open/open 절과 참조를 답안에 넣을 수 있습니까? 어디에서나 타입'INPUT'을 찾을 수없는 것 같습니다. – Maslow

+0

@Maslow 최근 응답에 대해 죄송합니다. 나는 그것을 http://www.pinvoke.net/default.aspx/Structures/INPUT.html에서 추가했다. – Measuring