通过 win32API 调用 SendInput 时这些额外的参数是什么
What are these extra parameters when calling SendInput via win32API
我有兴趣使用 win32API 通过 Ruby 发送键输入。
我找到了我想调用的函数:SendInput
MSDN对签名的描述如下:
UINT WINAPI SendInput(
_In_ UINT nInputs,
_In_ LPINPUT pInputs,
_In_ int cbSize
);
INPUT 看起来像
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
} INPUT, *PINPUT;
所以我需要一个整数来显示输入类型。
由于我对键盘事件感兴趣,所以我查看了 KEYBDINPUT
结构
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
还有另外 5 个参数:两个 16 位整数和三个 32 位整数。
现在,根据我收集到的信息,SendInput
接受一个整数、一个指向 INPUT 结构的指针和一个表示 INPUT 结构大小的整数。创建 Win32API
对象看起来像
SendInput = Win32API.new("User32", "SendInput", "LPL", "L")
INPUT_KEYBOARD = 1
现在我构建我的 INPUT 结构:
input = [INPUT_KEYBOARD, 0x5A, 0, 0, 0, 0].pack('ISSIII')
第一个参数是输入类型,接下来是 KEYBDINPUT
结构的五个参数:我要按下的键的虚拟键码,以及一些我不需要用于测试目的的其他标志.
所以我运行它:
SendInput.call(1, input, input.size)
没有任何反应。
当我检查 GetLastError 时,它 returns 一个 error code of 87,这意味着存在无效参数。
然后我决定四处搜索,发现其他人正在像这样构建他们的输入结构:
input = [INPUT_KEYBOARD, 0x5A, 0, 0, 0, 0, 0, 0].pack('ISSIIIII')
我试过 运行ning 它,它执行成功!
区别?输入有两个额外的参数。
现在我很困惑:输入结构的这两个额外参数是什么?
我在阅读文档时是否遗漏了什么?
我认为它可能与 ULONG_POINTER
类型有关,但当我查找数据类型时,它是一个 32 位整数。
参考:http://www.dsprobotics.com/support/viewtopic.php?p=7110&sid=cd256b848d00e64a2e74e093863f837f#p7110
函数调用采用 union
这些结构,我敢打赌它与此有关。
看起来 MOUSEINPUT
大于 KEYBOARDINPUT
:
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;
当然不知道,这似乎是一种非常可怕的方式来桥接这些电话!
编辑:是的,看起来像使用那个 MOUSEINPUT
大小,你最终将 w/28 字节的数据发送到函数,这就是 pack('ISSIIIII')
会给你带来的。
我有兴趣使用 win32API 通过 Ruby 发送键输入。 我找到了我想调用的函数:SendInput
MSDN对签名的描述如下:
UINT WINAPI SendInput(
_In_ UINT nInputs,
_In_ LPINPUT pInputs,
_In_ int cbSize
);
INPUT 看起来像
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
} INPUT, *PINPUT;
所以我需要一个整数来显示输入类型。
由于我对键盘事件感兴趣,所以我查看了 KEYBDINPUT
结构
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
还有另外 5 个参数:两个 16 位整数和三个 32 位整数。
现在,根据我收集到的信息,SendInput
接受一个整数、一个指向 INPUT 结构的指针和一个表示 INPUT 结构大小的整数。创建 Win32API
对象看起来像
SendInput = Win32API.new("User32", "SendInput", "LPL", "L")
INPUT_KEYBOARD = 1
现在我构建我的 INPUT 结构:
input = [INPUT_KEYBOARD, 0x5A, 0, 0, 0, 0].pack('ISSIII')
第一个参数是输入类型,接下来是 KEYBDINPUT
结构的五个参数:我要按下的键的虚拟键码,以及一些我不需要用于测试目的的其他标志.
所以我运行它:
SendInput.call(1, input, input.size)
没有任何反应。
当我检查 GetLastError 时,它 returns 一个 error code of 87,这意味着存在无效参数。
然后我决定四处搜索,发现其他人正在像这样构建他们的输入结构:
input = [INPUT_KEYBOARD, 0x5A, 0, 0, 0, 0, 0, 0].pack('ISSIIIII')
我试过 运行ning 它,它执行成功!
区别?输入有两个额外的参数。 现在我很困惑:输入结构的这两个额外参数是什么? 我在阅读文档时是否遗漏了什么?
我认为它可能与 ULONG_POINTER
类型有关,但当我查找数据类型时,它是一个 32 位整数。
参考:http://www.dsprobotics.com/support/viewtopic.php?p=7110&sid=cd256b848d00e64a2e74e093863f837f#p7110
函数调用采用 union
这些结构,我敢打赌它与此有关。
看起来 MOUSEINPUT
大于 KEYBOARDINPUT
:
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;
当然不知道,这似乎是一种非常可怕的方式来桥接这些电话!
编辑:是的,看起来像使用那个 MOUSEINPUT
大小,你最终将 w/28 字节的数据发送到函数,这就是 pack('ISSIIIII')
会给你带来的。