Я пытаюсь сделать простую программу для ботов для игры. Я хочу, чтобы это работало, даже если игра не в фокусе или свернута. Из-за этого я не могу использовать SendInput (), поскольку он имитирует глобальные события. Я понял, что, чтобы сделать это, я должен использовать функцию PostMessage (). Я сделал тестовую программу, которая имитирует ввод в блокноте:
#include <Windows.h>
HWND handle = FindWindow(NULL,CStringW("Untitled - Notepad"));
HWND edit = FindWindowEx(handle, NULL, CStringW("Edit"), NULL);
PostMessage(edit, WM_CHAR, 'a', 0 );
В этом примере успешно имитируется нажатие кнопки «а» в блокноте, даже если блокнот не сфокусирован или свернут. Я также получил мышиные события для работы.
Однако когда я пытаюсь сделать то же самое для своей игры, я не могу опубликовать команды щелчка. После расследования я обнаружил, что исходный дескриптор получен, но в разрешении отказано, когда я вызываю FindWindowEx (), и дескриптор не возвращается.
Есть ли способ получить доступ для редактирования к другому процессу, если он блокирует эту функцию?
Конечно, Windows никогда не позволяет вам сделать это, что если вы попытаетесь украсть пароль пользователя? Вы не можете получать информацию, пока у вас нет фокуса!
Но вы можете сделать некоторые уловки здесь: вы должны написать функцию ловушки для мыши или клавиатуры, и эта функция должна быть реализована в DLL (не в вашем EXE) использовании SetWindowsHookEx чтобы установить его, а затем использовать механизм IPC в вашей DLL для отправки сообщений мыши и / или клавиатуры на ваш основной EXE-файл.
Но помимо этого: в то время как обычно работают линии
HWND handle = FindWindow(NULL,CStringW("Untitled - Notepad"));
В этом нет никакого смысла, окна должны иметь версию большинства функций, которые получают хотя бы один строковый аргумент: один для ANSI, имя которого заканчивается на A
и один для широких (UTF-16) символов, оканчивающихся на W
, У MSVC есть дополнительный слой над этим дизайном, который называется TCHAR
и используя определение, сопоставьте все такие функции с ANSI или Wide, поэтому, если вы используете эту версию API, то не стоит напрямую использовать CStringW
которые генерируют широкие строки. А так как Windows API работает с char*
а также wchar_t*
почему вы конвертируете строковый литерал в CString
а потом передать его функции? Вы должны использовать одно из этого:
// This also work with CStringA
HWND handleA = FindWindowA(NULL, "Untitled - Notepad");
// This also work with CStringW
HWND handleW = FindWindowW(NULL, L"Untitled - Notepad");
// This also work with CString
HWND handleT = FindWindow(NULL, _T("Untitled - Notepad") );
Вы уверены, что игра, в которую вы пытаетесь отправить текст, имеет элемент управления Windows Edit, который можно перечислить по дочерним элементам клиента? Вполне возможно, что элемент управления Edit, на который вы ссылаетесь, является сущностью графического контейнера Клиента. Если это так, вы можете отправить WM_KEYDOWN
а также WM_KEYUP
сообщения в само окно клиента для достижения желаемой функциональности.
Надеюсь, это поможет.