2015-01-15 3 views
2

Я заинтересован в отправке ключевого ввода через Ruby с помощью win32API. Я нашел функцию, что я хотел бы назвать: SendInputКаковы эти дополнительные параметры при вызове SendInput через win32API

MSDN описывает подпись следующим образом:

UINT WINAPI SendInput(
    _In_ UINT nInputs, 
    _In_ LPINPUT pInputs, 
    _In_ int cbSize 
); 

И ВВОД выглядит

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_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

+0

Точно такая же ситуация у меня была, но с js-ctypes, большое спасибо за обмен !!!! – Noitidart

ответ

2

Вызов функции принимает 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').

+3

Я кратко прочитал о профсоюзах, чтобы понять, для чего они предназначены, но не читал о том, как они на самом деле реализованы. Но, думая об этом, это имеет смысл: если вы разрешаете разные типы данных в одном и том же пространстве памяти, вам понадобится хотя бы размер самого большого типа ... – MxyL

+0

@MxyL - ваш комментарий, подтвержденный кем-либо еще, как winapi эксперты? Это имеет смысл, но мне было просто интересно, подтверждено ли оно, я имел такую ​​же точную проблему и исправил ее, сделав мою структуру kyinput равной размеру, такой как mouseinput struct. – Noitidart