gpt4 book ai didi

c# - 使用 C# 的 SendInput 模拟按键事件

转载 作者:行者123 更新时间:2023-11-30 17:12:49 27 4
gpt4 key购买 nike

遵循此线程的建议:distinguish between keyboard's Real and Virtual key presses

我正在尝试创建一个程序,它将使用 SendInput() 方法发送键盘的按键事件。

但是,问题是当我尝试模拟按键事件时 - 什么也没有发生。到目前为止,这是我的代码:

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

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

[StructLayout(LayoutKind.Explicit)]
struct INPUT
{
[FieldOffset(0)] public int type;
[FieldOffset(8)] public KEYBDINPUT ki; //x64 - 8, x32 - 4
}

const int KEYEVENTF_DOWN = 0; //key UP
const int KEYEVENTF_EXTENDEDKEY = 0x0001;
const int KEYEVENTF_KEYUP = 0x0002; //key UP
const int KEYEVENTF_UNICODE = 0x0004;
const int KEYEVENTF_SCANCODE = 0x0008; // scancode

public void Send_Key(short Keycode)
{
INPUT[] InputData = new INPUT[1];
InputData[0].type = 1;
InputData[0].ki.wScan = Keycode;
InputData[0].ki.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE;
InputData[0].ki.time = 0;
InputData[0].ki.dwExtraInfo = IntPtr.Zero;
SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));
}

为了破译扫描码,我下载了该线程中建议的程序:

https://superuser.com/questions/293609/windows-7-tool-to-capture-keyboard-scan-codes

根据这个程序 - 我键盘的“a”键代码是“65”

我的程序应该在文本框文本更改时触发按键事件,因此如果我们输入“q” - 文本应更改为“q”加上 send_key() 的结果,即“qa”:

    private void textBox2_TextChanged(object sender, EventArgs e)
{
Send_Key(0x0065); // nothing happens (0x65 also fails)
}

我做错了什么?将来我将更改此代码,以便我可以指定按键保持时间(在 DOWN 和 UP 事件之间)。但现在,出于测试目的,我只模拟 keyUP 事件。

编辑:汉斯,根据您的建议,这里是编辑 - 但不幸的是它不起作用。

 public void Send_Key(short Keycode)
{
INPUT[] InputData = new INPUT[1];
InputData[0].type = 1;
InputData[0].ki.wScan = Keycode;
InputData[0].ki.dwFlags = KEYEVENTF_DOWN;
InputData[0].ki.time = 0;
InputData[0].ki.dwExtraInfo = IntPtr.Zero;

uint intReturn = SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));

if (intReturn == 0) //!=1
{
throw new Exception("Could not send keyDOWN: " + Keycode);
}

INPUT[] InputData2 = new INPUT[1];
InputData2[0].type = 1;
InputData2[0].ki.wScan = Keycode;
InputData2[0].mi.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE;
InputData2[0].ki.time = 0;
InputData2[0].ki.dwExtraInfo = IntPtr.Zero;

uint intReturn2 = SendInput(1, InputData2, Marshal.SizeOf(typeof(INPUT)));

if (intReturn2 == 0) //!=1
{
throw new Exception("Could not send keyUP: " + Keycode);
}
}

没有错误..也没有输出。

最佳答案

but for now, for testing purposes I'm simulating only keyUP event

我想这没问题,但这不会让 Windows 执行任何操作。要生成击键,您必须首先发送 KEYDOWN。 “保持时间”没有任何有用的效果,所以只需将两个 SendInput 调用放在同一个方法中即可。

您应该添加错误检查,winapi 调用不会产生任何异常。如果函数返回 0,则抛出 Win32Exception。并使用 SetLastError = true 修复 [DllImport] 声明。

您可以通过设置 ki.wVk 字段并省略 KEYEVENTF_SCANCODE 标志来避免使用您在 superuser.com 上找到的那个程序。这样您就可以指定虚拟键而不是扫描码。 .NET Keys enumeration type给你你需要的值(value)。像 Keys.A 一样为 A 键生成按键。

关于c# - 使用 C# 的 SendInput 模拟按键事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10375264/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com