2013-05-02 72 views
3

我正在尝试制作一个C#应用程序,它将控制游戏。我试图做的是例如:按住A键150ms,按住左箭头500ms等等。 我搜索了很多,我发现下面的代码。我的程序首先瞄准游戏,然后拿着钥匙。C#在游戏应用程序中保存密钥

I'm holding the keys this way: 

Keyboard.HoldKey(Keys.Left); 
Thread.sleep(500); 
Keyboard.ReleaseKey(Keys.Left); 

下面是键盘类:

public class Keyboard 
{ 
    public Keyboard() 
    { 
    } 

    [StructLayout(LayoutKind.Explicit, Size = 28)] 
    public struct Input 
    { 
     [FieldOffset(0)] 
     public uint type; 
     [FieldOffset(4)] 
     public KeyboardInput ki; 
    } 

    public struct KeyboardInput 
    { 
     public ushort wVk; 
     public ushort wScan; 
     public uint dwFlags; 
     public long time; 
     public uint dwExtraInfo; 
    } 

    const int KEYEVENTF_KEYUP = 0x0002; 
    const int INPUT_KEYBOARD = 1; 

    [DllImport("user32.dll")] 
    public static extern int SendInput(uint cInputs, ref Input inputs, int cbSize); 

    [DllImport("user32.dll")] 
    static extern short GetKeyState(int nVirtKey); 

    [DllImport("user32.dll")] 
    static extern ushort MapVirtualKey(int wCode, int wMapType); 


    public static bool IsKeyDown(Keys key) 
    { 
     return (GetKeyState((int)key) & -128) == -128; 
    } 

    public static void HoldKey(Keys vk) 
    { 
     ushort nScan = MapVirtualKey((ushort)vk, 0); 

     Input input = new Input(); 
     input.type = INPUT_KEYBOARD; 
     input.ki.wVk = (ushort)vk; 
     input.ki.wScan = nScan; 
     input.ki.dwFlags = 0; 
     input.ki.time = 0; 
     input.ki.dwExtraInfo = 0; 
     SendInput(1, ref input, Marshal.SizeOf(input)).ToString(); 
    } 

    public static void ReleaseKey(Keys vk) 
    { 
     ushort nScan = MapVirtualKey((ushort)vk, 0); 

     Input input = new Input(); 
     input.type = INPUT_KEYBOARD; 
     input.ki.wVk = (ushort)vk; 
     input.ki.wScan = nScan; 
     input.ki.dwFlags = KEYEVENTF_KEYUP; 
     input.ki.time = 0; 
     input.ki.dwExtraInfo = 0; 
     SendInput(1, ref input, Marshal.SizeOf(input)); 
    } 

    public static void PressKey(Keys vk) 
    { 
     HoldKey(vk); 
     ReleaseKey(vk); 
    } 
} 

及其在记事本/浏览器等的工作,但它不是在任何游戏中工作,无论全屏或窗口模式。 你能帮我弄清楚如何在全屏应用程序/游戏中保存按键吗? 谢谢!

+5

你不能只是谷歌的一段代码,它转储到一个应用程序,并期望它的工作。定义'不工作'?这是一个非常广泛的术语,究竟是什么不工作? – DGibbs 2013-05-02 16:02:14

+1

游戏通常通过DirectX获得键盘,这是一种非常不同的处理方式。发送Windows输入消息到这样的应用程序是没有用的。 [例如](http://courses.washington.edu/css450/2008.Fall/web_contents/from_students/450Hints/DirectInputTutorial/DirectInputTutorial.pdf)[PDF]。 – GSerg 2013-05-02 16:05:40

+0

好吧,我自己做了一切,只是我不习惯windows API。不工作我的意思是我的应用程序是针对游戏,并试图保持/释放箭头游戏,但游戏中没有任何反应。如果我按下键盘上的箭头,它就会起作用。 – Deepsy 2013-05-02 16:07:54

回答

0

我Windown API和SendInput做到了方法。

+4

你能告诉我们怎么样? – 2016-02-11 15:00:23

2

“Hold键用于150毫秒,保持500毫秒左箭头”

见,如果这个工程:

 Keyboard.HoldKey((byte)Keys.A, 150); 
     Keyboard.HoldKey((byte)Keys.Left, 500); 

使用:

public class Keyboard 
{ 
    [DllImport("user32.dll", SetLastError = true)] 
    static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); 

    const int KEY_DOWN_EVENT = 0x0001; //Key down flag 
    const int KEY_UP_EVENT = 0x0002; //Key up flag 

    public static void HoldKey(byte key, int duration) 
    { 
     int totalDuration = 0; 
     while (totalDuration < duration) 
     { 
      keybd_event(key, 0, KEY_DOWN_EVENT, 0); 
      keybd_event(key, 0, KEY_UP_EVENT, 0); 
      System.Threading.Thread.Sleep(PauseBetweenStrokes); 
      totalDuration += PauseBetweenStrokes; 
     } 
    } 
} 
+0

你好。感谢您的回答,但遗憾的是,效果与我在第一篇文章中发布的代码相同:它在记事本/浏览器等中工作,但不适用于游戏窗口。 – Deepsy 2013-05-02 16:35:26

+0

我改变了HoldKey()快速按下/释放键直到持续时间满足。看看是否有什么更好的... – 2013-05-02 16:52:46

+0

仍然一样,似乎游戏正在处理按不同的方式按键:( – Deepsy 2013-05-02 17:15:43

0

你可以得到它与工作,这为按住键的伟大工程:

public class Keyboard 
{ 

    const int PauseBetweenStrokes = 50; 
    [DllImport("user32.dll", SetLastError = true)] 
    static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); 

    const int KEY_DOWN_EVENT = 0x0001; //Key down flag 
    const int KEY_UP_EVENT = 0x0002; //Key up flag 

    public static void HoldKey(byte key, int duration) 
    { 
     keybd_event(key, 0, KEY_DOWN_EVENT, 0); 
     System.Threading.Thread.Sleep(duration); 
     keybd_event(key, 0, KEY_UP_EVENT, 0); 
    } 
}