通过win32API调用SendInput时,这些额外的参数是什么

时间:2015-01-15 20:46:00

标签: ruby winapi struct msdn

我有兴趣使用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 struct

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时,它会返回error code of 87,这意味着存在无效的参数。

然后我决定四处搜索并发现其他人正在构建他们的输入结构:

input = [INPUT_KEYBOARD, 0x5A, 0, 0, 0, 0, 0, 0].pack('ISSIIIII')

我尝试过运行它,并且执行成功!

差?输入有两个额外的参数。 现在我很困惑:输入结构的这两个额外参数是什么? 在阅读文档时,我有什么遗失的东西吗?

我认为它可能与ULONG_POINTER类型有关,但是当我查找数据类型时,它是一个32位整数。

参考:http://www.dsprobotics.com/support/viewtopic.php?p=7110&sid=cd256b848d00e64a2e74e093863f837f#p7110

1 个答案:

答案 0 :(得分:2)

函数调用需要union个结构,我打赌它与之有关。

看起来MOUSEINPUT大于KEYBOARDINPUT

typedef struct tagMOUSEINPUT {
  LONG      dx;
  LONG      dy;
  DWORD     mouseData;
  DWORD     dwFlags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;
但是,不确定Dunno,这似乎是一种非常可怕的方式来连接这些电话!

编辑:是的,看起来像使用MOUSEINPUT大小,你最终会发送到该函数的28字节数据,这就是pack('ISSIIIII')可以为你提供的。