Как отправить нажатия клавиш в окно, не активируя его с помощью Windows API?
Я уже сделал приложение, которое отправляет команды в активированное окно. Я хочу использовать компьютер во время работы моего процесса, потому что как только я переключаю фокус на другое окно, нажатия клавиш, отправляемые с помощью клавиш отправки, переходят в окно, на которое я только что переключился.
В настоящее время я использую FindWindow, IsIconic и ShowWindow из Windows API. Я должен проверить, есть ли окно с FindWindow и установить мой объект в конкретное окно, которое возвращается с этим вызовом, затем я проверяю, свернуто ли оно с помощью IsIconic, и вызвать ShowWindow, если оно есть, и, наконец, мне нужно вызвать Interaction.AppActivate, чтобы установить фокус на это окно. Все это делается еще до того, как я отправляю нажатия клавиш. Похоже, должен быть способ отправлять нажатия клавиш без необходимости показывать окно и активировать его. Самое главное, что пока мое приложение выполняет нажатия клавиш, я ничего не могу сделать на своем компьютере.
4 ответа
Хорошо, это несколько разочаровывает, я уверен, но вы принципиально не можете сделать это со 100% надежностью.
Windows предполагает, что активное окно является тем, которое получает ввод с клавиатуры. Правильный способ подделки ввода с клавиатуры - с SendInput, и вы заметите, что он отправляет сообщения только в активное окно.
При этом вы можете отправлять сообщения SendMessage WM_KEYUP, WM_CHAR и WM_KEYDOWN и (в зависимости от того, как их получает WndProc) могут сойти с рук. Но помните, что он сломается при некоторых обстоятельствах, точка.
Похоже, вы используете keybd_event() или SendInput(), которые оба посылают нажатия клавиш в текущее активное окно. Чтобы направить нажатия клавиш в конкретное окно, независимо от того, нацелена ли эта вдова или нет, сначала нужно найти ее дескриптор HWND, а затем публиковать в нее сообщения надлежащим образом отформатированного WM_KEYUP/DOWN и WM_CHAR.
Как только у вас есть окна HWND, вы можете напрямую отправить Message() сообщения WM_KEYDOWN и WM_KEYUP в его очередь сообщений. Окно не обязательно должно быть активным.
Однако следует понимать, что это зависит от того, как целевое приложение обрабатывает ввод с клавиатуры. Есть несколько разных способов справиться с этим.
WM_KEYUP / WM_KEYDOWN является наиболее распространенным, и некоторые приложения обрабатывают только одно или другое (обычно WM_KEYDOWN).
WM_CHAR также довольно часто
Некоторые программы используют GetAsyncKeyState, GetKeyState или GetKeyboardState. Это чрезвычайно необычно, но эффективно предотвращает инъекцию клавиш с помощью SendMessage(). Если это так, вернитесь к keybd_event(), который напрямую обрабатывается драйвером клавиатуры. Конечно, окно должно быть активным
#include <windows.h>
#include <iostream>
#include <string>
int main()
{
LPCWSTR Target_window_Name = TEXT("Untitled - Notepad"); //<- Has to match window name
HWND hWindowHandle = FindWindow(NULL, Target_window_Name);
HWND EditClass = FindWindowEx(hWindowHandle, NULL, L"Edit", NULL);
SendMessage(EditClass, WM_KEYDOWN, 0x5A, 0x002C0001);
SendMessage(EditClass, WM_CHAR, 0x7A, 0x002C0001); //"z"
SendMessage(EditClass, WM_KEYUP, 0x5A, 0xC02C0001);
return(0);
}
Этот код работает, в этом случае вам не нужно иметь активный блокнот. Это использует С ++