0

当我尝试使用SendInput发送单个按键和组合按键时,我无法让我的程序按住键盘按钮,直到被命令释放。使用下面的代码,我可以通过先点击发送字符'a', 和。但是,我无法让它永远按住按钮。'A'shift'a'

public static void KeyDown()
{
    SwitchWindow(Process.GetProcessesByName("notepad").FirstOrDefault().MainWindowHandle);
    INPUT[] inputs = new INPUT[1];
    KEYBDINPUT kb = new KEYBDINPUT();

    //Set up generic keyboard event
    inputs[0].type = INPUT_KEYBOARD;
    kb.wScan = 0; // hardware scan code for key
    kb.time = 0;
    kb.dwExtraInfo = IntPtr.Zero;

    kb.dwFlags = 0; // 0 for key press

    //Press shift
    kb.wVk = (ushort)KeyCode.SHIFT;
    inputs[0].ki = kb;
    SendInput(1, inputs, Marshal.SizeOf(inputs[0]));

    //Press 'a' key
    kb.wVk = (ushort)0x41; // virtual-key code for the "a" key
    inputs[0].ki = kb;
    SendInput(1, inputs, Marshal.SizeOf(inputs[0]));

    //Release 'a' key
    kb.dwFlags = KEYEVENTF_KEYUP;
    kb.wVk = (ushort)0x41; // virtual-key code for the "a" key
    inputs[0].ki = kb;
    SendInput(1, inputs, Marshal.SizeOf(inputs[0]));

    //Release 'shift' key
    kb.dwFlags = KEYEVENTF_KEYUP;
    kb.wVk = (ushort)KeyCode.SHIFT; // virtual-key code for the "a" key
    inputs[0].ki = kb;
    SendInput(1, inputs, Marshal.SizeOf(inputs[0]));
}

知道为什么,如果我删除最后两个SendInputs,它不只是按住'A'吗?

4

1 回答 1

1

为了其他正在寻找如何在 C# 中使用 SendInput() 的人的利益,请参阅以下说明。

1) 使用 SendInput() 发送击键有两种方法,使用扫描码或虚拟键码

2) 如果您打算将击键发送到从 Direct 3D(或其他 DirectInput 环境)获取输入的游戏或其他应用程序,则需要将击键作为扫描码发送,因此您指定 wScan 字段,并将 wVk 留空。在此处查看信息:KEYBDINPUT

3) 请记住在发送击键之前将焦点窗口切换到要发送击键的应用程序。例子:

MemoryHandler.SwitchWindow(Process.GetProcessesByName("notepad").FirstOrDefault().MainWindowHandle);

4)最终代码:

    public static void PressKey(char ch, bool press)
    {
        byte vk = MemoryApi.VkKeyScan(ch);
        PressKey((MemoryApi.KeyCode)vk, press);
    }

    public static void PressKey(MemoryApi.KeyCode vk, bool press)
    {
        ushort scanCode = (ushort)MemoryApi.MapVirtualKey((ushort)vk, 0);

        //Console.WriteLine("SendInput:: VK: " + (ushort)vk + " (" + vk + ") <-> SC: " + (ushort)(scanCode & 0xff));

        if (press)
            KeyDown(scanCode);
        else
            KeyUp(scanCode);
    }

    public static void KeyDown(ushort scanCode)
    {
        //Console.WriteLine("Key Down (SC): " + (ushort)(scanCode & 0xff));
        MemoryApi.INPUT[] inputs = new MemoryApi.INPUT[1];

        inputs[0].type = MemoryApi.INPUT_KEYBOARD;
        inputs[0].ki.wScan = (ushort)(scanCode & 0xff);
        inputs[0].ki.dwFlags = MemoryApi.KEYEVENTF_SCANCODE;
        inputs[0].ki.time = 0;
        inputs[0].ki.dwExtraInfo = IntPtr.Zero;

        uint intReturn = MemoryApi.SendInput(1, inputs, Marshal.SizeOf(inputs[0]));
        if (intReturn != 1)
        {
            throw new Exception("Could not send key: " + scanCode);
        }
    }

    public static void KeyUp(ushort scanCode)
    {
        //Console.WriteLine("Key Up (SC): " + scanCode);
        MemoryApi.INPUT[] inputs = new MemoryApi.INPUT[1];

        inputs[0].type = MemoryApi.INPUT_KEYBOARD;
        inputs[0].ki.wScan = (ushort)(scanCode & 0xff);
        inputs[0].ki.dwFlags = MemoryApi.KEYEVENTF_SCANCODE | MemoryApi.KEYEVENTF_KEYUP;
        inputs[0].ki.time = 0;
        inputs[0].ki.dwExtraInfo = IntPtr.Zero;

        uint intReturn = MemoryApi.SendInput(1, inputs, Marshal.SizeOf(inputs[0]));
        if (intReturn != 1)
        {
            throw new Exception("Could not send key: " + scanCode);
        }
}
于 2014-04-30T14:46:31.210 回答