在Direct3D游戏上重新映射键

时间:2013-01-21 17:43:08

标签: c keyboard directx simulate sendinput

我正在尝试重新映射游戏的一些键(Elsword)。

首先,我使用此代码来模拟按下的键:

#define WINVER 0x0500

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "dinput.h"

int main()
{
    HWND hWndMain = FindWindow(0, "Elsword");
    SetForegroundWindow(hWndMain);

    Sleep(3000);

    INPUT input[2];

    input[0].type=INPUT_KEYBOARD;
    input[0].ki.wScan = DIK_V; // direct-input scancode for key '1'
    input[0].ki.dwFlags=KEYEVENTF_SCANCODE;

    input[1].type=INPUT_KEYBOARD;
    input[1].ki.wScan = DIK_V; // direct-input scancode for key '1'
    input[1].ki.dwFlags=KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

    SendInput(2,input,sizeof(INPUT));

    Sleep(1000);
    return 0;
}

在所有其他应用程序中它工作正常,但在游戏窗口中它什么都不做......

1 个答案:

答案 0 :(得分:1)

请注意,挂钩Direct3D只能访问与图形相关的功能,而不是与输入相关的功能。要挂钩使用Direct3D的游戏,您需要挂钩DirectInput(如果游戏使用它),或者使用SentInput或PostMessage。如今大多数游戏都使用鼠标的标准Windows消息,以及DirectInput或他们自己的自定义键盘实现。另请注意,SendInput API是系统范围的,并且需要正确的目标窗口才能获得焦点。此外,一些游戏创建了一个额外的窗口,作为D3D窗口的客户区域上的不可见层,导致混淆哪个窗口句柄是发送输入消息的正确窗口句柄。

要检查您的游戏是否使用Windows消息进行输入,请打开Spy ++并以窗口模式运行游戏。单击“进程”按钮,右键单击游戏进程并选择“消息”。然后单击“记录选项”按钮并切换到“消息”选项卡。从这里,您可以选择“键盘”和“鼠标”,或按住CTRL键并从列表中选择/取消选择单个消息。之后,点击“确定”并在目标应用程序中测试键盘和鼠标。如果您看到任何与鼠标相关的消息,那么您就知道SendInput,PostMessage,SetWindowsHookEx以及可能的mouse_event()将适用于鼠标。如果您看到任何与键盘相关的消息,那么您就知道SendInput,PostMessage,SetWindowsHookEx以及可能的keyb_event()将适用于键盘。

如果您没有看到键盘的任何消息,那么最有可能采取的措施是检查进程是否曾加载dinput.dll或dinput8.dll,如果有,请安装一个钩子(google“directinput”挂钩“)。如果没有,那么你可以检查Dependency Walker,IDA或OllyDbg中的每个加载的模块,看看他们是否已经实现了自己的键盘处理程序,但事情变得相当复杂,需要大量的ASM知识和逆向工程技术。但是,如果您熟悉开发驱动程序,那么这可能有所帮助:SendInput Not working for Games