Имитация нажатия клавиш в неактивных окнах - PullRequest
0 голосов
/ 22 января 2019

Я хотел бы имитировать «реальные» нажатия клавиш в неактивном окне.После некоторых исследований я нашел 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 (): они равны обоим вышеописанным случаям, но действие выполняется.Я не могу объяснить это поведение.

...