Какое WM_Message использовать?

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

Я сделал печатную часть своего кода следующим образом:

[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

//Send each character of string one at a time
foreach(Char c in Input)
    PostMessage(mainwnd, (uint)WM.CHAR, c, 1);
//Send final enter key to send message in game
PostMessage(mainwnd, (uint)WM.CHAR, 0x0D, 1);

Это прекрасно работает, но есть две вещи, которые он не учитывает.

  1. В игре вам необходимо нажать клавишу ввода перед вводом, чтобы открыть чат
  2. Есть горячие клавиши для открытия меню

Я пробовал такие вещи, как PostMessage(mainwnd, (uint)WM.CHAR, 0x0D, 1);, чтобы отправить начальный ключ ввода, но игра его не обрабатывает. То же самое происходит, если я использую PostMessage, чтобы попытаться открыть меню. Ничто не анализируется, если окно чата уже не открыто перед отправкой сообщения.

Я полагаю, что использую не тот WM_Message, но не могу найти нужный. Я пытался:

  1. WM_CHAR
  2. WM_SYSCHAR
  3. WM_MENUCHAR
  4. WM_HOTKEY
  5. WM_APPCOMMAND
  6. WM_KEYDOWN, за которым следует WM_KEYUP

И, может быть, несколько других, но не повезло. Кто-нибудь знает, какая команда может работать?


person ozdrgnaDiies    schedule 28.12.2011    source источник


Ответы (2)


Вам должно повезти, чтобы это сработало. Ввод с клавиатуры — это не просто сообщение. Это также влияет (среди прочего) на GetKeyboardState и GetAsyncKeyState -- и имитация ввода с их помощью нетривиальна. И если фокус клавиатуры находится в другом месте, это может все испортить.

Вы можете попробовать опубликовать WM_KEYDOWN и WM_KEYUP для создания сообщения более низкого уровня.

Нижний уровень по-прежнему SendInput< /a>, который имитирует ввод с драйвера клавиатуры. Фокус клавиатуры должен быть в правильном месте, иначе ввод будет отправлен не в то окно.

person tenfour    schedule 28.12.2011
comment
SendInput кажется лучшим выбором, но, глядя на параметры, он не принимает дескриптор окна. Причина, по которой мне нужен PostMessage, заключается в том, что я могу отправлять данные, когда экран свернут. Может быть, я неправильно читаю, но SendInput, кажется, нуждается в полном фокусе экрана. - person ozdrgnaDiies; 28.12.2011
comment
Вы не понимаете; основное внимание уделяется тому, как работает ввод с клавиатуры. Одновременно только одно окно может получать сообщения ввода с клавиатуры: окно с фокусом клавиатуры. Если вы пытаетесь отправить ввод с клавиатуры в не сфокусированное окно, то вы играете в азартные игры, и в этом случае это звучит так, как будто вы проиграли. - person tenfour; 28.12.2011
comment
Другой способ объяснить это... если вы можете указать окно, вы плохо справляетесь с имитацией ввода с клавиатуры. Драйвер клавиатуры ничего не знает об дескрипторах окна. - person tenfour; 28.12.2011
comment
Дело в том, что если для этого требуется, чтобы окно не было свернуто, то оно не соответствует моим потребностям. SendInput из того, что я тестировал, требует, чтобы вы вызывали SetForegroundWindow, прежде чем он действительно сможет отправить какие-либо данные клиенту. Хотя PostMessage не полностью соответствует моим потребностям, он все же может отправлять сообщения со свернутым клиентом. Даже если я сейчас печатаю в блокноте, клиент получает ввод из PostMessage. Единственная проблема, опять же, в том, что некоторые клавиши не распознаются, пока окно чата клиента не открыто. Дело не в потере ввода, а в том, чтобы заставить клиента распознать его. - person ozdrgnaDiies; 28.12.2011
comment
Я хочу сказать, что вам может не повезти. Вы надеетесь, что приложение будет реагировать на бессмысленный ввод с клавиатуры (сообщения о вводе с клавиатуры, пока оно не имеет фокуса). - person tenfour; 28.12.2011
comment
Но это так. Я не думаю, что вы понимаете всю проблему. Я могу использовать PostMessage для отправки любого текста, и клиент примет его, даже если он свернут, пока окно чата открыто. Таким образом, он ДЕЙСТВИТЕЛЬНО принимает ввод, хотя и сведен к минимуму. В клиенте нажатие i, например, открывает экран инвентаря, если окно чата НЕ открыто. Однако PostMessaging, когда чат не работает, не дает такого же результата. Назвать это бессмысленным вкладом — значит просто сдаться. Я уверен, что PostMessage может работать, так как он уже работает для половины из них. SendInput вне уравнения. - person ozdrgnaDiies; 28.12.2011
comment
Вы не можете просто отправлять случайные WM_KEYDOWN сообщения в приложение и ожидать, что все будет работать правильно. SendInput — это то, что вы ищете, вам просто нужно убедиться, что приложение сфокусировано. Либо это, либо пользовательское сообщение Windows, которое вы затем обрабатываете и реагируете по своему усмотрению. - person Cody Gray; 28.12.2011
comment
Если действительно есть способ заставить его работать, вы не найдете ответа на SO, и этот вопрос следует закрыть как слишком локализованный. В этом случае вам нужно просто отладить целевое приложение и выяснить, почему оно ведет себя по-другому. Не существует обобщенного ответа на эту чрезвычайно узкую ситуацию (приложение X ведет себя Y-образно при очень специфическом условии Z). - person tenfour; 28.12.2011

Попробуйте WM_KEYDOWN, а затем WM_KEYUP. С кодом VK_ENTER (кажется).

person Steve Wellens    schedule 28.12.2011
comment
Я забыл упомянуть, что я пробовал их тоже. Это была моя вторая догадка после того, как Чар не сработал. Добавлю в список. - person ozdrgnaDiies; 28.12.2011