Использование SendMessage для ввода текста в элемент управления редактирования, принадлежащий другому процессу - PullRequest
3 голосов
/ 03 апреля 2012

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

HWND hWnd = FindWindow(NULL,"Game");
HWND edit = FindWindowEx(hWnd, NULL, "Edit", NULL);

SendMessage(edit, WM_CHAR, (TCHAR) 'H', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'E', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'L', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'L', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'O', 0);

это не работает для меня .... но некоторые, как когда-то работали.Я думаю, что я что-то неправильно понял, может быть, он должен сосредоточиться на контроле редактирования, затем установить курсор, затем вставить текст, а затем отключить фокус ... Я действительно не знаю много ... пожалуйста, сэкономьте свое время и нервы, скажите мне, как это сделатьработает ....

Я тоже пробовал, и не работает:

SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"text");

hwnd правильный, но текст не обновляется ... он отправляется на правильный дескриптор, но не обновляется.... Я думаю, что мне нужно как-то сфокусироваться или обновить, как только оно обновится успешно, но я не понял, что случилось ... поэтому код работал один раз, но больше не работал ... почему один раз он работал?

Ответы [ 2 ]

4 голосов
/ 04 апреля 2012

Ваш вопрос - деньги! Серьезно . Допустим, маленькая птичка рассказала мне, какая игра вас интересует (начинается с S ). Я сам потратил несколько часов на эту проблему и добился определенного успеха, поэтому я поделюсь им с вами.

Существует инструмент с именем Spy ++ (от Microsoft), который позволяет вам просматривать сообщения, отправляемые в окно / класс. Это отлично подходит для отладки, поскольку позволяет отслеживать сообщения, которые отправляются в поле РЕДАКТИРОВАНИЯ при нажатии клавиши на клавиатуре, поэтому вы можете узнать точные вызовы и параметры, которые отправляются в игру для имитации этой операции.

Используйте spy ++, чтобы открыть игровой процесс, и как только вы войдете в окно входа в игру, вы увидите, что spy ++ сообщает о нескольких потоках, открытых в этом процессе, но только у одного потока будет 3 блока РЕДАКТИРОВАНИЯ. Это тема, которая вас интересует!

Также обратите внимание, что ни в одном из полей EDIT нет заголовка, поэтому следующий код никогда не будет работать:

HWND edit = FindWindowEx(hWnd, NULL, "Edit", NULL);

и, между прочим, всегда проверяйте, что FindWindowEx() возвращает что-то действительное, иначе как вы узнали бы, что ему удалось найти окно редактирования?

Вместо этого вы должны сделать следующее:

HWND edit = FindWindowEx(hWnd, NULL, "", NULL);
if (!edit)
{
    // report error
}

И это найдет первое поле РЕДАКТИРОВАТЬ. Это поле соответствует имени пользователя. В игре используются 3 PostMessage() звонка для имитации нажатия клавиши, а не SendMessage(), как вы пытались:

// "..." means you need to find out the other parameters
PostMessage(edit, WM_KEYDOWN, ...); 
PostMessage(edit, WM_CHAR, ...); 
PostMessage(edit, WM_KEYUP, ...); 

Spy ++ покажет другие параметры, не волнуйтесь. Вероятно, вы потратите некоторое время на выяснение того, как построен последний параметр вызова (потому что это маска).

Я не смог отправить ключи в игру, если она была свернута или не была сфокусирована. Вам придется выяснить это. В целях тестирования используйте команду SetForegroundWindow(window_hwnd); и еще кое-что для фокусировки окна.

2 голосов
/ 03 апреля 2012

Ищите исходный код для Autoit. Autoit может отправлять ключи / мышь практически на что угодно. При установке более новых версий Антивируса Касперского он сталкивается с ошибками типа SendMessage|SendInput между процессами.

Edit: Для тех, кто отмечает, что Autoit - это огромный кусок кода, который нужно изучить для выполнения этой задачи:

Autoit может отправлять ввод в фоновые приложения, которые не хотят видеть введенный ввод. Это не простая задача, которую легко выполнить. Есть игры, которые не хотят видеть какой-либо сценарий ввода любой формы, и они стараются изо всех сил, чтобы предотвратить это. Кроме того, в дикой природе существуют AV-решения, которые блокируют межпроцессное внедрение ввода. Autoit так или иначе работает вокруг блоков во многих случаях.

...