Имитация щелчка клавиатуры в GTA:SA

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

IntPtr calculatorHandle = FindWindow(null, "GTA:SA:MP");
if (calculatorHandle == IntPtr.Zero)
{
    MessageBox.Show("GTA:SA:MP isn't running");
    return;
}
SetForegroundWindow(calculatorHandle);
SendKeys.SendWait("T123");

Я был бы рад, если бы вы сказали, если что-то не так с моим кодом. Спасибо!

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

Это мой код после добавления кода Нила:

IntPtr calculatorHandle = FindWindow(null, "GTA:SA:MP");
if (calculatorHandle == IntPtr.Zero)
{
    MessageBox.Show("GTA:SA:MP isn't running");
    return;
}
SetForegroundWindow(calculatorHandle);
short key = 0x14;
WindowsMessageService.SendKey(key, KeyFlag.KeyDown);
Thread.Sleep(10);
WindowsMessageService.SendKey(key, KeyFlag.KeyUp);

person Omer Aviv    schedule 04.03.2015    source источник


Ответы (1)


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

[StructLayout(LayoutKind.Sequential)]
struct MouseInput
{
    public int dx;
    public int dy;
    public int mouseData;
    public int dwFlags;
    public int time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct KeyboardInput
{
    public short wVk;      //Virtual KeyCode (not needed here)
    public short wScan;    //Directx Keycode 
    public int dwFlags;    //This tells you what is use (Keyup, Keydown..)
    public int time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct HardwareInput
{
    public int uMsg;
    public short wParamL;
    public short wParamH;
}

[StructLayout(LayoutKind.Explicit)]
struct Input
{
    [FieldOffset(0)]
    public int type;
    [FieldOffset(4)]
    public MouseInput mi;
    [FieldOffset(4)]
    public KeyboardInput ki;
    [FieldOffset(4)]
    public HardwareInput hi;
}

[Flags]
public enum KeyFlag
{       
    KeyDown = 0x0000,
    ExtendedKey = 0x0001,
    KeyUp = 0x0002,
    UniCode = 0x0004,
    ScanCode = 0x0008
}

public static class WindowsMessageService
{
    [DllImport("user32.dll")]
    private static extern UInt32 SendInput(UInt32 nInputs,[MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] Input[] pInputs, Int32 cbSize);

    public static void SendInput(short keycode, KeyFlag keyFlag)
    {
        var inputData = new Input[1];

        inputData[0].type = 1;
        inputData[0].ki.wScan = keycode;
        inputData[0].ki.dwFlags = (int)keyFlag;
        inputData[0].ki.time = 0;
        inputData[0].ki.dwExtraInfo = IntPtr.Zero;

        SendInput(1, inputData, Marshal.SizeOf(typeof(Input)));
    }

    public static void SendKey(short keyCode, KeyFlag keyFlag)
    {
        SendInput(keyCode, keyFlag | KeyFlag.ScanCode);
    }
}

Пример использования:

short key = 0x3B; // F1 key

WindowsMessageService.SendKey(key, KeyFlag.KeyDown);

Thread.Sleep(10);

WindowsMessageService.SendKey(key, KeyFlag.KeyUp);
person Community    schedule 04.03.2015
comment
Я только что попробовал это с помощью short key = 0x14; (клавиша T), но это тоже не работает. - person Omer Aviv; 04.03.2015
comment
Вы уверены, что у вас есть указатель на MainWindow процесса GTA? - person ; 04.03.2015
comment
Что я сделал, так это сам запустил игру, используя ProcessStartInfo и Process.Start. Экземпляр процесса предоставляет свойство MainWindow, которое необходимо использовать для SetForegroundWindow перед отправкой ключей. Или вы можете использовать: Process.GetProcessesByName(processName).FirstOrDefault() для подключения к запущенному процессу игры. - person ; 04.03.2015
comment
Я отредактировал свой пост с новым кодом, что-то не так? - person Omer Aviv; 04.03.2015
comment
Ничего, я разобрался. Это не сработало, потому что я запускаю GTA от имени администратора, поэтому мне также приходится запускать программу от имени администратора. Теперь мой вопрос: можно ли отправить последовательность клавиш из строки. Как перевести символы в их коды? - person Omer Aviv; 04.03.2015
comment
У меня есть класс, который предоставляет сопоставления, но не работает. Чтобы отправить последовательность строк, вам нужно перебрать символы в строке и отправить каждый по отдельности. - person ; 04.03.2015
comment
Можно ли выбрать, хочу ли я отправить ключ «а» или «А»? - person Omer Aviv; 04.03.2015
comment
Да, но нужно смотреть код Shift. Я опубликую материал завтра, если вы можете подождать, иначе вам придется гуглить ???? - person ; 04.03.2015