为什么按键一次就像反复按下一样?

时间:2012-11-10 16:02:45

标签: c# winforms input

我正在使用Winform在DirectX游戏中提供按钮。因此我正在使用这个课程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace DirectInput
{
    public class cDirectInput
    {
        [DllImport("user32.dll")]
        static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);

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

        [StructLayout(LayoutKind.Sequential)]
        struct KEYBDINPUT
        {
            public short wVk;
            public short wScan;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }

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

        [StructLayout(LayoutKind.Explicit)]
        struct INPUT
        {
            [FieldOffset(0)]
            public int type;
            [FieldOffset(4)]
            public MOUSEINPUT mi;
            [FieldOffset(4)]
            public KEYBDINPUT ki;
            [FieldOffset(4)]
            public HARDWAREINPUT hi;
        }

        const int KEYEVENTF_EXTENDEDKEY = 0x0001;
        const int KEYEVENTF_KEYUP = 0x0002;
        const int KEYEVENTF_UNICODE = 0x0004;
        const int KEYEVENTF_SCANCODE = 0x0008;


        public void Send_Key(short Keycode, int KeyUporDown)
        {
            INPUT[] InputData = new INPUT[1];

            InputData[0].type = 1;
            InputData[0].ki.wScan = Keycode;
            InputData[0].ki.dwFlags = KeyUporDown;
            InputData[0].ki.time = 0;
            InputData[0].ki.dwExtraInfo = IntPtr.Zero;

            SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));
        }

    }
}

然后我发送按钮:

DirectInput.cDirectInput d = new DirectInput.cDirectInput();
d.Send_Key(0x11, 0x0008);

但是当我发送它时它是永久性的。当我发送w时,玩家将永远前进。我可以通过按键盘上的w来阻止它。为什么不停止?当我将它发送给编辑器时,当我停止发送时它会停止,它不会停止。问题是什么? 提前谢谢!

1 个答案:

答案 0 :(得分:2)

您正在发送密钥消息,但不会发送密钥消息。来自文档:

  

KEYBDINPUT.dwFlags:

     
      
  • KEYEVENTF_KEYUP(0x0002)
      如果指定,则正在释放密钥。如果未指定,则按下该键。
  •   

要向前移动1秒,请尝试:

d.Send_Key(0x11, 0x0008);
Thread.Sleep(1000);
d.Send_Key(0x11, 0x000A);

请注意,按 w 解决问题的原因是它发送了一个keydown事件(可以忽略),然后是一个keyup事件,最后释放了该键。