Перехват и отмена событий нажатия клавиш для игры DirectX

0

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

Я мог бы найти множество вариантов симуляции нажатия клавиш, но каковы варианты, когда дело доходит до отмены нажатия клавиши перед тем, как игра читает его?

Язык не имеет особого значения, хотя я бы предпочел решение С# или C++ или просто толчок в правильном направлении :)

Заранее спасибо!

  • 0
    Является ли игра DirectX вашей или сторонней (то есть у вас есть исходный код)? Кроме того, какую ОС вы используете?
  • 0
    @parrowdice Нет, игра не моя, и у меня нет исходного кода. Это сторонняя игра. Я на винде.
Показать ещё 1 комментарий
Теги:
directx
keystroke

1 ответ

2

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

Плохая новость в том, что это не просто. Для этого требуется много сложного кода, и, скорее всего, потребуется много времени, но я объясню, как вы можете это сделать.

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

Таким образом, вы хотите изменить поток:

Raw Input --> Game

в

Raw Input --> Your Code --> Game

Не имея доступа к исходному коду игры, вы должны найти способ вставить свой код.

Когда есть доступ к клавиатуре, игра вызовет функцию GetRawInputData WinAPI, которая расскажет об этом событии клавиатуры. В идеале, мы хотим, когда игра вызывает эту функцию, она фактически называет наш код вместо функции WinAPI. Затем мы можем решить, что сказать игре о событии клавиатуры, мы могли бы сказать все, что захотим (например, игнорировать F12). Звучит здорово? Здесь, где это становится интересным...

Мы можем использовать то, как окна загружают исполняемые файлы в память. Как правило, программа использует (или "импорт") вызовы функций в других DLL (таких как GetRawInputData, в User32.dll). Когда программа загружается в память, Windows будет заполнять таблицу (Import Address Table (IAT)) указателями на исполняемый код в соответствующих DLL. Это означает, что когда программа вызывает функцию, она запускается в исполняемый код в User32.dll в памяти для ее запуска.

Было бы здорово, если бы мы могли написать/исправить адрес одной из наших функций в эту таблицу, так что, когда игра вызывает GetRawInputData, она фактически направляется на нашу функцию для обработки? Ну, мы можем! Он назывался "Исправление адресной таблицы адресов".

Там довольно хорошая статья об этом здесь с некоторым рабочим кодом в C++. Сначала вы должны прочитать это, чтобы более подробно понять, как это работает, а затем вы можете изменить его, чтобы поддержать ваши потребности. Он будет работать, но я знаю, что это, вероятно, больше работы (гораздо больше работы), чем вы бы надеялись, но по сути вы взломали приложение, которое никогда не бывает легко сделать.

Это стоит того, чтобы просто лучше понять Windows за кулисами.

Удачи!

РЕДАКТИРОВАТЬ

Как сказал Саймон, Windows Hooks - гораздо более простой способ сделать это, если игра не использует исходный вход. DirectX Games - это особый случай, который не слишком хорошо работает со стандартными Крюками, поскольку они используют специальные методы для получения ввода от пользователя. Во что бы то ни стало отдать ему ход, это будет намного проще, если он сработает.

  • 0
    Ух, спасибо за потрясающе подробный ответ! Вы действительно заинтересовали меня нижними уровнями Windows. Например, исправление IAT звучит потрясающе. Я дам Хуксу попытку, как вы и предлагали, однако, даже если Хукс выполнит свою работу, я постараюсь реализовать ваш метод просто так. Это будет действительно хорошее учебное упражнение. Еще раз спасибо: D

Ещё вопросы

Сообщество Overcoder
Наверх
Меню