Имитация нажатия клавиш в неактивных окнах

Я хотел бы имитировать "реальные" нажатия клавиш в неактивном окне. После некоторых исследований я нашел API Windows. Так как я привык к Java, я быстро нашел JNA, который реализует winapi. Я написал некоторый код, который может имитировать нажатия клавиш в активном окне с помощью метода sendInput(). Окно не обнаружило виртуальные коды клавиш. После некоторого поиска окна с прямым входом нуждаются в сканкодах. И это работало со следующим кодом:

import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;

int KEYEVENT_SCANCODE = 0x0008;
int KEYEVENT_UP = 0x0002;
WinUser.INPUT input = new WinUser.INPUT();

input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
input.input.setType("ki");
input.input.ki.wVk = new WinDef.WORD(0);// 0 cause scancodes are used
input.input.ki.time = new WinDef.DWORD(0);
input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR(0);

input.input.ki.wScan = new WinDef.WORD(0x2C); // scancode for 'y'
input.input.ki.dwFlags = new WinDef.DWORD(KEYEVENT_SCANCODE); // keydown

User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());

input.input.ki.wScan = new WinDef.WORD(0x2C);
input.input.ki.dwFlags = new WinDef.DWORD(KEYEVENT_SCANCODE | KEYEVENT_UP); // keyup

User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());

Теперь я хотел, чтобы оно было "плавным", чтобы окно могло быть на заднем плане или свернуто. Я нашел методы SendMessage() и PostMessage() и подумал, что понял их концепции. Вы передаете обработчик окна, сообщение ( wm_keydown и wm_keyup, кажется, хорошо для задачи) и его конкретные параметры.

Я попробовал это, но это не сработало. (то же самое для postMessage).

User32.INSTANCE.SendMessage(handler, WinUser.WM_KEYDOWN, new   WinDef.WPARAM(0x5A), new WinDef.LPARAM(0x002C0001));
Thread.sleep(100); //tried with and without
User32.INSTANCE.SendMessage(handler, WinUser.WM_KEYUP, new WinDef.WPARAM(0x5A), new WinDef.LPARAM(0xC02C0001)); 

Затем я попробовал WM_CHAR, и это сработало частично. Это работало в чате окна, но не вызывало горячие клавиши. После некоторых исследований люди говорят, что вы должны использовать ловушки directinput (?), Так как некоторые окна не распознают сообщения от winapi, а мои, очевидно, сделали из sendInput и sendMessage с WM_CHAR.

Я передал неправильные параметры? Что это значит, что wm_char повторно зарегистрирован, а wm_keydown и wm_keyup нет?

Я уже нашел много примеров, материалов о работе над контентом и в Интернете, но это не очень помогло. Спасибо за чтение и ответ.

@update Я использовал инструмент для обнаружения сообщений. Сообщения, созданные реальными нажатиями клавиш, и сообщения, созданные из кода, равны:

В обоих случаях есть WM_keydown, затем WM_char и WM_keyup. Каждый параметр каждого сообщения равен. В дополнение к этому, как я уже сказал, если чат открыт, есть написанные символы, но действия не будут выполняться, когда чат закрыт. Я проверил, какие сообщения отправляются методом sendInput(): они равны обоим вышеописанным случаям, но действие выполняется. Я не могу объяснить это поведение.

0 ответов

Другие вопросы по тегам