0

我正在使用 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 来停止它。为什么停不下来?当我将它发送给编辑器时,它会在我停止发送时停止,在游戏中它不会停止。问题是什么?先感谢您!

4

1 回答 1

2

您正在发送一个按键消息,但没有在它之后发送按键消息。从文档中:

KEYBDINPUT.dwFlags:

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

要前进 1 秒,请尝试:

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

请注意,按下w修复问题的原因是它发送一个 keydown 事件(将被忽略),然后是一个 keyup 事件,最后释放该键。

于 2012-11-10T16:19:40.193 回答