自动化与SendInput按键 [英] Automating Key Presses with SendInput

查看:279
本文介绍了自动化与SendInput按键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用 SendInput 派单按键和组合按键,我不能让我的计划,抓住键盘按钮,直到命令被释放。随着下面的代码我冷杉发送字符'A''A',通过点击<大骨节病>移第一。但是,我不能让它保持永久的'A'按钮。

When I attempt to use SendInput to send single key presses, and combined keypresses, I can't get my program to hold the keyboard button until commanded to be released. With the code below I am ables to send the character 'a', and 'A', by hitting shift first. However, I cannot get it to hold the 'a' button in perpetuity.

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]));
}



任何想法,为什么,如果我删除最后两个 SendInput S,它不只是持有'A'下来?

Any idea why, if I remove the last two SendInputs, it doesn't just hold 'A' down?

推荐答案

有关他人正在寻找如何在C#中使用SendInput()的利益,请参见下面的说明。

For the benefit of others that are searching for how to use SendInput() in C#, please see the below description.

1)有两种方式与SendInput()发送击键,或者使用一个扫描码或的虚拟键码

1) There are two ways to send the key stroke with SendInput(), either using a Scancode or a virtual-key code

2)如果你打算送击键游戏或其他应用程序需要从输入的Direct 3D(或其他DirectInput的环境),您需要发送击键的扫描码,并为此指定wScan场,并留下空白WVK。见信息在这里: KEYBDINPUT

2) If you intend to send keystrokes to a game or another application that takes input from Direct 3D (or another DirectInput environment), you need to send the key strokes as scancodes, and therefor you specify the wScan field, and leave wVk blank. See info here: KEYBDINPUT

3)记住要在焦点切换窗口要发送键击到应用程序,发送击键。例如:

3) Remember to switch the window in focus to the application you want to send keystrokes to, before sending the keystroke. Example:

MemoryHandler.SwitchWindow(。Process.GetProcessesByName(记事本)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);
        }
}

这篇关于自动化与SendInput按键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆