2

I am trying to make a program that would simulate holding down a keyboard button.

This program is supposed to work in games, where holding down buttons such as W,A,S,D is required. I tested the program both in Grand Theft Auto V and Garry's Mod, but it didn't work in either of them.

I tried using SendInput and keybd_event functions for emulating the input with no luck.

#include <windows.h>
#define VK_W 0x57

using namespace std;

int main(){
    while(1){
        keybd_event(VK_W, 0, 0, 0);
        Sleep(3000);  //should hold W for 3 seconds
        keybd_event(VK_W, 0, KEYEVENTF_KEYUP, 0);
        Sleep(1000);
    }
    return 0;
}

I've created macros using Razer's keyboard software, which work perfectly, so there must be a way to simulate the key hold input.

I also tried creating an AutoHotkey script, which does work in Garry's Mod, but not in Grand Theft Auto V:

w::
SendInput {w down}
Sleep 3000
SendInput {w up}

This script holds W for 3 seconds when W is pressed.

I tried searching the web, but didn't find any working implementation.

EDIT: I searched around some more and found this: https://stackoverflow.com/a/3647975/1587051

It turns out I was using Unicode instead of keyboard scan codes combined with KEYEVENTF_SCANCODE flag. DirectInput games are now receiving the keystrokes correctly.

Community
  • 1
  • 1
ShiiNko
  • 25
  • 2
  • 8
  • Have you tried in an app with a message loop? For functions related to input events, it's not crazy to think a message loop is required to complete the process. – tenfour Jun 19 '15 at 11:22
  • I'm not familiar with a message loop, could you elaborate? – ShiiNko Jun 19 '15 at 11:25
  • 4
    Most games use DirectInput or the likes and don't respond to window messages. That means that `keybd_event`, `SendMessage` and related don't work. – MicroVirus Jun 19 '15 at 11:36
  • 2
    *"I've created macros using Razer's keyboard software [...] so there must be a way to simulate the key hold input."* Of course there is: Write yourself a mouse driver that pretends that the user did produce mouse input, like the Razer software does. – IInspectable Jun 19 '15 at 11:48
  • 1
    Writing a driver seems like an overkill for such a task. I tried doing it again with SendInput, this time with Unicode - no luck. – ShiiNko Jun 19 '15 at 12:03
  • @MicroVirus is there a way, without writing a driver, to force keystrokes into DirectInput application? – ShiiNko Jun 19 '15 at 12:06
  • Like @MicroVirus said, such games, especially in full-screen mode just ignore Windows messages and take input directly from the mouse/keyboard. Your only way to simulate that is by writing a modified driver. Have a look at : http://stackoverflow.com/questions/3644881/simulating-keyboard-with-sendinput-api-in-directinput-applications – Hatted Rooster Jun 19 '15 at 12:36
  • @JameyD Thanks, this is exactly what I already had a look at (see Edit), and it solved my problem. – ShiiNko Jun 19 '15 at 12:46

1 Answers1

2

For reference sake, as it has already been answered in the comments, you have to use SendInput rather than SendMessage, when filling the INPUT structure required for the SendInput function make sure you combine your Flags with KEYEVENTF_SCANCODE to send hardware signals instead of virtual ones. These will be handled by DirectInput. Source : Simulating Keyboard with SendInput API in DirectInput applications

Community
  • 1
  • 1
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122