2016-07-04 11 views
1

Ich versuche The SendInput API zu verwenden, um automatisch eine Taste wiederholt in einem Spiel zu drücken OHNE Verzögerungen zu verwenden. Ich möchte die Tasten drücken, um so schnell wie möglich zu sein, also würde ich gerne weg von Verzögerungen wie die Task.Delay oder Thread.Sleep Methoden bleiben.SendInput funktioniert nicht in einem Spiel, wenn ich keine Verzögerungen hinzufüge. Warum?

Konzentrieren Sie sich auf die Strum Methode.

Der folgende Code drückt die rechte UMSCHALTTASTE 18 mal, wenn der Benutzer die Tastenkombination STRG + B verwendet.

using System; 
using System.Runtime.InteropServices; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Guitar_Hero_Strumming 
{ 
    public partial class GHSForm : Form 
    { 
     public GHSForm() 
     { 
      InitializeComponent(); 
     } 

     private static async void Strum() 
     { 
      for (var i = 0; i < 18; i++) 
      { 
       var nInputs = new[] 
       { 
        new INPUT 
        { 
         type = InputType.KEYBOARD, 
         U = 
         { 
          ki = 
          { 
           wScan = ScanCodeShort.RSHIFT 
          } 
         } 
        } 
       }; 
       SendInput((uint)nInputs.Length, nInputs, INPUT.Size); 
       await Task.Delay(1); 
       nInputs = new[] 
       { 
        new INPUT 
        { 
         type = InputType.KEYBOARD, 
         U = 
         { 
          ki = 
          { 
           wScan = ScanCodeShort.RSHIFT, 
           dwFlags = KEYEVENTF.KEYUP 
          } 
         } 
        } 
       }; 
       SendInput((uint)nInputs.Length, nInputs, INPUT.Size); 
       await Task.Delay(1); 
      } 
     } 

     [DllImport("user32.dll")] 
     private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk); 

     [DllImport("user32.dll")] 
     private static extern bool UnregisterHotKey(IntPtr hWnd, int id); 

     private const int ModControl = 0x0002; 
     private const int WmHotkey = 0x0312; 

     private void GHSForm_Load(object sender, EventArgs e) 
     { 
      RegisterHotKey(Handle, 1, ModControl, (int)Keys.B); 
     } 

     private void GHSForm_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      UnregisterHotKey(Handle, 1); 
     } 

     protected override void WndProc(ref Message m) 
     { 
      if (m.Msg == WmHotkey && (int)m.WParam == 1) 
      { 
       Strum(); 
      } 
      base.WndProc(ref m); 
     } 

     [DllImport("user32.dll")] 
     internal static extern uint SendInput(uint nInputs, 
      [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, 
      int cbSize); 

     [StructLayout(LayoutKind.Sequential)] 
     public struct INPUT 
     { 
      internal InputType type; 
      internal InputUnion U; 

      internal static int Size 
      { 
       get { return Marshal.SizeOf(typeof(INPUT)); } 
      } 
     } 

     internal enum InputType : uint 
     { 
      MOUSE = 0, 
      KEYBOARD = 1, 
      HARDWARE = 2 
     } 

     [StructLayout(LayoutKind.Explicit)] 
     internal struct InputUnion 
     { 
      [FieldOffset(0)] 
      internal MOUSEINPUT mi; 

      [FieldOffset(0)] 
      internal KEYBDINPUT ki; 

      [FieldOffset(0)] 
      internal HARDWAREINPUT hi; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     internal struct MOUSEINPUT 
     { 
      internal int dx; 
      internal int dy; 
      internal int mouseData; 
      internal MOUSEEVENTF dwFlags; 
      internal uint time; 
      internal UIntPtr dwExtraInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     internal struct KEYBDINPUT 
     { 
      internal VirtualKeyShort wVk; 
      internal ScanCodeShort wScan; 
      internal KEYEVENTF dwFlags; 
      internal int time; 
      internal UIntPtr dwExtraInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     internal struct HARDWAREINPUT 
     { 
      internal int uMsg; 
      internal short wParamL; 
      internal short wParamH; 
     } 

     [Flags] 
     internal enum MOUSEEVENTF : uint 
     { 
      ABSOLUTE = 0x8000, 
      HWHEEL = 0x01000, 
      MOVE = 0x0001, 
      MOVE_NOCOALESCE = 0x2000, 
      LEFTDOWN = 0x0002, 
      LEFTUP = 0x0004, 
      RIGHTDOWN = 0x0008, 
      RIGHTUP = 0x0010, 
      MIDDLEDOWN = 0x0020, 
      MIDDLEUP = 0x0040, 
      VIRTUALDESK = 0x4000, 
      WHEEL = 0x0800, 
      XDOWN = 0x0080, 
      XUP = 0x0100 
     } 

     [Flags] 
     internal enum KEYEVENTF : uint 
     { 
      EXTENDEDKEY = 0x0001, 
      KEYUP = 0x0002, 
      SCANCODE = 0x0008, 
      UNICODE = 0x0004 
     } 

     internal enum VirtualKeyShort : short 
     { 
      LBUTTON = 0x01, 
      RBUTTON = 0x02, 
      CANCEL = 0x03, 
      MBUTTON = 0x04, 
      XBUTTON1 = 0x05, 
      XBUTTON2 = 0x06, 
      BACK = 0x08, 
      TAB = 0x09, 
      CLEAR = 0x0C, 
      RETURN = 0x0D, 
      SHIFT = 0x10, 
      CONTROL = 0x11, 
      MENU = 0x12, 
      PAUSE = 0x13, 
      CAPITAL = 0x14, 
      KANA = 0x15, 
      HANGUL = 0x15, 
      JUNJA = 0x17, 
      FINAL = 0x18, 
      HANJA = 0x19, 
      KANJI = 0x19, 
      ESCAPE = 0x1B, 
      CONVERT = 0x1C, 
      NONCONVERT = 0x1D, 
      ACCEPT = 0x1E, 
      MODECHANGE = 0x1F, 
      SPACE = 0x20, 
      PRIOR = 0x21, 
      NEXT = 0x22, 
      END = 0x23, 
      HOME = 0x24, 
      LEFT = 0x25, 
      UP = 0x26, 
      RIGHT = 0x27, 
      DOWN = 0x28, 
      SELECT = 0x29, 
      PRINT = 0x2A, 
      EXECUTE = 0x2B, 
      SNAPSHOT = 0x2C, 
      INSERT = 0x2D, 
      DELETE = 0x2E, 
      HELP = 0x2F, 
      KEY_0 = 0x30, 
      KEY_1 = 0x31, 
      KEY_2 = 0x32, 
      KEY_3 = 0x33, 
      KEY_4 = 0x34, 
      KEY_5 = 0x35, 
      KEY_6 = 0x36, 
      KEY_7 = 0x37, 
      KEY_8 = 0x38, 
      KEY_9 = 0x39, 
      KEY_A = 0x41, 
      KEY_B = 0x42, 
      KEY_C = 0x43, 
      KEY_D = 0x44, 
      KEY_E = 0x45, 
      KEY_F = 0x46, 
      KEY_G = 0x47, 
      KEY_H = 0x48, 
      KEY_I = 0x49, 
      KEY_J = 0x4A, 
      KEY_K = 0x4B, 
      KEY_L = 0x4C, 
      KEY_M = 0x4D, 
      KEY_N = 0x4E, 
      KEY_O = 0x4F, 
      KEY_P = 0x50, 
      KEY_Q = 0x51, 
      KEY_R = 0x52, 
      KEY_S = 0x53, 
      KEY_T = 0x54, 
      KEY_U = 0x55, 
      KEY_V = 0x56, 
      KEY_W = 0x57, 
      KEY_X = 0x58, 
      KEY_Y = 0x59, 
      KEY_Z = 0x5A, 
      LWIN = 0x5B, 
      RWIN = 0x5C, 
      APPS = 0x5D, 
      SLEEP = 0x5F, 
      NUMPAD0 = 0x60, 
      NUMPAD1 = 0x61, 
      NUMPAD2 = 0x62, 
      NUMPAD3 = 0x63, 
      NUMPAD4 = 0x64, 
      NUMPAD5 = 0x65, 
      NUMPAD6 = 0x66, 
      NUMPAD7 = 0x67, 
      NUMPAD8 = 0x68, 
      NUMPAD9 = 0x69, 
      MULTIPLY = 0x6A, 
      ADD = 0x6B, 
      SEPARATOR = 0x6C, 
      SUBTRACT = 0x6D, 
      DECIMAL = 0x6E, 
      DIVIDE = 0x6F, 
      F1 = 0x70, 
      F2 = 0x71, 
      F3 = 0x72, 
      F4 = 0x73, 
      F5 = 0x74, 
      F6 = 0x75, 
      F7 = 0x76, 
      F8 = 0x77, 
      F9 = 0x78, 
      F10 = 0x79, 
      F11 = 0x7A, 
      F12 = 0x7B, 
      F13 = 0x7C, 
      F14 = 0x7D, 
      F15 = 0x7E, 
      F16 = 0x7F, 
      F17 = 0x80, 
      F18 = 0x81, 
      F19 = 0x82, 
      F20 = 0x83, 
      F21 = 0x84, 
      F22 = 0x85, 
      F23 = 0x86, 
      F24 = 0x87, 
      NUMLOCK = 0x90, 
      SCROLL = 0x91, 
      LSHIFT = 0xA0, 
      RSHIFT = 0xA1, 
      LCONTROL = 0xA2, 
      RCONTROL = 0xA3, 
      LMENU = 0xA4, 
      RMENU = 0xA5, 
      BROWSER_BACK = 0xA6, 
      BROWSER_FORWARD = 0xA7, 
      BROWSER_REFRESH = 0xA8, 
      BROWSER_STOP = 0xA9, 
      BROWSER_SEARCH = 0xAA, 
      BROWSER_FAVORITES = 0xAB, 
      BROWSER_HOME = 0xAC, 
      VOLUME_MUTE = 0xAD, 
      VOLUME_DOWN = 0xAE, 
      VOLUME_UP = 0xAF, 
      MEDIA_NEXT_TRACK = 0xB0, 
      MEDIA_PREV_TRACK = 0xB1, 
      MEDIA_STOP = 0xB2, 
      MEDIA_PLAY_PAUSE = 0xB3, 
      LAUNCH_MAIL = 0xB4, 
      LAUNCH_MEDIA_SELECT = 0xB5, 
      LAUNCH_APP1 = 0xB6, 
      LAUNCH_APP2 = 0xB7, 
      OEM_1 = 0xBA, 
      OEM_PLUS = 0xBB, 
      OEM_COMMA = 0xBC, 
      OEM_MINUS = 0xBD, 
      OEM_PERIOD = 0xBE, 
      OEM_2 = 0xBF, 
      OEM_3 = 0xC0, 
      OEM_4 = 0xDB, 
      OEM_5 = 0xDC, 
      OEM_6 = 0xDD, 
      OEM_7 = 0xDE, 
      OEM_8 = 0xDF, 
      OEM_102 = 0xE2, 
      PROCESSKEY = 0xE5, 
      PACKET = 0xE7, 
      ATTN = 0xF6, 
      CRSEL = 0xF7, 
      EXSEL = 0xF8, 
      EREOF = 0xF9, 
      PLAY = 0xFA, 
      ZOOM = 0xFB, 
      NONAME = 0xFC, 
      PA1 = 0xFD, 
      OEM_CLEAR = 0xFE 
     } 

     internal enum ScanCodeShort : short 
     { 
      LBUTTON = 0, 
      RBUTTON = 0, 
      CANCEL = 70, 
      MBUTTON = 0, 
      XBUTTON1 = 0, 
      XBUTTON2 = 0, 
      BACK = 14, 
      TAB = 15, 
      CLEAR = 76, 
      RETURN = 28, 
      SHIFT = 42, 
      CONTROL = 29, 
      MENU = 56, 
      PAUSE = 0, 
      CAPITAL = 58, 
      KANA = 0, 
      HANGUL = 0, 
      JUNJA = 0, 
      FINAL = 0, 
      HANJA = 0, 
      KANJI = 0, 
      ESCAPE = 1, 
      CONVERT = 0, 
      NONCONVERT = 0, 
      ACCEPT = 0, 
      MODECHANGE = 0, 
      SPACE = 57, 
      PRIOR = 73, 
      NEXT = 81, 
      END = 79, 
      HOME = 71, 
      LEFT = 75, 
      UP = 72, 
      RIGHT = 77, 
      DOWN = 80, 
      SELECT = 0, 
      PRINT = 0, 
      EXECUTE = 0, 
      SNAPSHOT = 84, 
      INSERT = 82, 
      DELETE = 83, 
      HELP = 99, 
      KEY_0 = 11, 
      KEY_1 = 2, 
      KEY_2 = 3, 
      KEY_3 = 4, 
      KEY_4 = 5, 
      KEY_5 = 6, 
      KEY_6 = 7, 
      KEY_7 = 8, 
      KEY_8 = 9, 
      KEY_9 = 10, 
      KEY_A = 30, 
      KEY_B = 48, 
      KEY_C = 46, 
      KEY_D = 32, 
      KEY_E = 18, 
      KEY_F = 33, 
      KEY_G = 34, 
      KEY_H = 35, 
      KEY_I = 23, 
      KEY_J = 36, 
      KEY_K = 37, 
      KEY_L = 38, 
      KEY_M = 50, 
      KEY_N = 49, 
      KEY_O = 24, 
      KEY_P = 25, 
      KEY_Q = 16, 
      KEY_R = 19, 
      KEY_S = 31, 
      KEY_T = 20, 
      KEY_U = 22, 
      KEY_V = 47, 
      KEY_W = 17, 
      KEY_X = 45, 
      KEY_Y = 21, 
      KEY_Z = 44, 
      LWIN = 91, 
      RWIN = 92, 
      APPS = 93, 
      SLEEP = 95, 
      NUMPAD0 = 82, 
      NUMPAD1 = 79, 
      NUMPAD2 = 80, 
      NUMPAD3 = 81, 
      NUMPAD4 = 75, 
      NUMPAD5 = 76, 
      NUMPAD6 = 77, 
      NUMPAD7 = 71, 
      NUMPAD8 = 72, 
      NUMPAD9 = 73, 
      MULTIPLY = 55, 
      ADD = 78, 
      SEPARATOR = 0, 
      SUBTRACT = 74, 
      DECIMAL = 83, 
      DIVIDE = 53, 
      F1 = 59, 
      F2 = 60, 
      F3 = 61, 
      F4 = 62, 
      F5 = 63, 
      F6 = 64, 
      F7 = 65, 
      F8 = 66, 
      F9 = 67, 
      F10 = 68, 
      F11 = 87, 
      F12 = 88, 
      F13 = 100, 
      F14 = 101, 
      F15 = 102, 
      F16 = 103, 
      F17 = 104, 
      F18 = 105, 
      F19 = 106, 
      F20 = 107, 
      F21 = 108, 
      F22 = 109, 
      F23 = 110, 
      F24 = 118, 
      NUMLOCK = 69, 
      SCROLL = 70, 
      LSHIFT = 42, 
      RSHIFT = 54, 
      LCONTROL = 29, 
      RCONTROL = 29, 
      LMENU = 56, 
      RMENU = 56, 
      BROWSER_BACK = 106, 
      BROWSER_FORWARD = 105, 
      BROWSER_REFRESH = 103, 
      BROWSER_STOP = 104, 
      BROWSER_SEARCH = 101, 
      BROWSER_FAVORITES = 102, 
      BROWSER_HOME = 50, 
      VOLUME_MUTE = 32, 
      VOLUME_DOWN = 46, 
      VOLUME_UP = 48, 
      MEDIA_NEXT_TRACK = 25, 
      MEDIA_PREV_TRACK = 16, 
      MEDIA_STOP = 36, 
      MEDIA_PLAY_PAUSE = 34, 
      LAUNCH_MAIL = 108, 
      LAUNCH_MEDIA_SELECT = 109, 
      LAUNCH_APP1 = 107, 
      LAUNCH_APP2 = 33, 
      OEM_1 = 39, 
      OEM_PLUS = 13, 
      OEM_COMMA = 51, 
      OEM_MINUS = 12, 
      OEM_PERIOD = 52, 
      OEM_2 = 53, 
      OEM_3 = 41, 
      OEM_4 = 26, 
      OEM_5 = 43, 
      OEM_6 = 27, 
      OEM_7 = 40, 
      OEM_8 = 0, 
      OEM_102 = 86, 
      PROCESSKEY = 0, 
      PACKET = 0, 
      ATTN = 0, 
      CRSEL = 0, 
      EXSEL = 0, 
      EREOF = 93, 
      PLAY = 0, 
      ZOOM = 98, 
      NONAME = 0, 
      PA1 = 0, 
      OEM_CLEAR = 0, 
     } 
    } 
} 

Wie Sie sehen können, die Strum Methode enthält zwei Instanzen der Task.Delay Methode. Der obige Code wird nicht funktionieren, wenn ich die 2 Instanzen der Task.Delay Methode entfernen.

Warum wird die Tastatureingabe nicht gesendet, wenn ich die Verzögerungen entferne?

Wie kann ich die Tastatureingabe senden, ohne die Verzögerungen zu verwenden?

Jede Hilfe wird geschätzt!

Antwort

0

Ändert dies das Ergebnis? (beachten Sie, absichtlich entfernt den asynchronen Rückgabetyp)

private static void Strum() 
{ 
    var inputs = new[] 
    { 
     new INPUT 
     { 
      type = InputType.KEYBOARD, 
      U = 
      { 
       ki = 
       { 
        wScan = ScanCodeShort.RSHIFT 
       } 
      } 
     }, 
     new INPUT 
     { 
      type = InputType.KEYBOARD, 
      U = 
      { 
       ki = 
       { 
        wScan = ScanCodeShort.RSHIFT, 
        dwFlags = KEYEVENTF.KEYUP 
       } 
      } 
     } 
    }; 

    for (var i = 0; i < 18; i++) 
    { 
     SendInput((uint)inputs.Length, inputs, INPUT.Size); 
    } 
} 
+0

Tolle Idee, aber leider nein. – Albertay

+0

Shucks, das ist alles, was ich zu bieten habe, außer alle 36 in einen SendInput-Call zu stopfen. Oh, und in meiner obigen Lösung habe ich gerade festgestellt, dass ich den asynchronen Rückgabewert entfernt haben sollte (jetzt bearbeitet). Ich fange an zu denken, dass das die Ursache des Problems ist. –

+0

Sie denken, dass Async die Ursache des Problems ist? SendInput funktioniert überhaupt erst, wenn eine Verzögerung verwendet wird. Thread.Sleep und Task.Delay funktionieren beide, damit SendInput funktioniert. :ICH – Albertay