Jump to content

Simulation of keystrokes


Recommended Posts

Question:

Did someone ever manage a simulated keyboard input into DCS out of a LUA script or a DLL?

I want to initiate key strokes like F6, F1 (request rejoin) by a single push of a joystick button. I know, for the Thrustmaster HOTAS there is a possibility for a TARGET script. But the script does not support modifiers like Button 4 + Button 3. What I tested so far is the normal windows API with Keybd_event() and faked messages WM_KYDOWN, WM_KEYUP to the DCS message queue. Both methods are recognized in the DCS message queue. I observed this by sub-classing the DCS message queue. But the sent keystrokes are not processed in DCS. DCS obviously uses a secret method to evaluate keystrokes.

Every solution is welcome...

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

Not directly answering your question, but what do you mean about TARGET not supporting modifiers? I use modifiers extensively in my TARGET script (in my signature).

 

I can think of two ways to add a modifier to a routine (one in a MapKey statement and one in an ActKey/DeferCall subroutine).

 

If you're referring to the fact that the function keys won't work while a modifier is depressed, the workaround for that is to go into your keyboard settings for each aircraft affected and add that modifier to the function keys (e.g. add JOY_BTN_4 + F1 as another entry with F1).

Link to comment
Share on other sites

Since an early DCS beta change, passing modifier from outside DCS into the game has proven problematic. The fix is that discrete 'key down', 'pause', and then 'key up' commands must be available within the external app. For example, with my X-Keys Pro, I found that I had to use a delay of 50 ms in order to have DCS recognize the modifier being pressed and then released.

 

It's been so long since I used TARGET, though, that I can't remember if it allows delays or not. If not, maybe try Joy2Key -- it works brilliantly.

Link to comment
Share on other sites

If I say modifier, I mean a combination of device buttons. In this case I used the pinky paddle as modifier and the bomb release button as trigger.

Before I answered, I checked the TARGET software again and found a description , which obviously fulfilled my requirements. Before I started to change the example code, I made a test compile to be sure that the procedure works basically. The result after a test run was a disaster. All connected Thrustmaster devices were disconnected and could not be reconnected again. It was necessary to reinstall the entire driver software for all devices and to use a strange procedure to get the bulk drivers to work. For the MFDs I needed to start a repair by windows in addition to the reinstalled new drivers. So finally, as long as I do not know what caused this destruction, I cannot use the TARGET software. But this is not the kernel of my request. DCS does not offer a possibility to connect device buttons to the function keys shown in the Com menus. I wrote a small driver in a C++ DLL which catches the joystick buttons and filtered the required combinations I want to use. In this case the pinky paddle (button 4) as modifier and the bomb release button (button 2) as trigger. Once the combination is recognized, I try to send the keystrokes to DCS. As I stated before, the keystrokes caused the right messages in DCS . I observed WM_KEYDOWN and WM_KEYUP in the DCS message queue on each keystroke sent. But DCS does not process the keys. If there is basically a method to inject keystrokes into DSC that would be a real advantage. I plan to offer such a configuration in my radio software.

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

That is not normal TARGET behavior. If I understand you correctly all that you were trying to do is the very run of the mill stuff that you can do even with TARGET GUI very easily, TARGET can indeed send all kinds of Keystrokes to DCS.

But do realize that when you compile a TARGET script GUY or Script Editor it does disconect all TM devices in that profile and connects a simgle virtual controller. This is then reverted when you stop the script. However from your description it does not sound like this is what happened. But whatever did it sounds like a fluke behavior.

Link to comment
Share on other sites

This makes sense. I got an error message from TARGET during the test run. It reported, that the requested device cannot be found and stopped the script. It referenced an internal device name which was not found. The script was taken from the documentation without modification and should work. The compiler did not report any error. Strange...

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

If you don't run the TARGET scripts and just plug and play the HOTAS your computer will see the devices separated.

 

If you create and run a TARGET script, it combines the HOTAS into 1 virtual joystick with a different name.

 

To set up multiple key strokes in TARGET is pretty straight forward.

-Select the button you want and map a key to it.

-Add it to the list on the right (assuming you're using the GUI)

-map another key stroke and add it

-continue ad nausem

 

I don't understand what you mean by "selecting a modifier" however, if you're in the GUI and select an "Advanced" setup when creating a new file you can choose "Layer Options"

 

The layer function is used when you want to have 1 button do 3 different things depending on the layer. As an example make the Boat Switch Fwd the "Down" layer, the Boat Switch Middle the "Middle" layer, and the Boat Switch Aft the "Up" layer.

 

Using these layers we can select any botton on the joystick and make it do 3 different things. Lets choose the Trigger (for simplicity) we can map it to Bring the gear up/down, fire the cannon, or contact the tower and request a landing.

 

Trigger Press

-[D] "g"

-[M] "c"

-[M] "spacebar"

- "\"

- "F1"

- "F1"

 

 

So now if our Boat switch is forward (selecting the "Down" layer 'D') and we press the trigger, it activates the keystroke "g"

 

If the boat switch is aft (selecting the "Up" layer 'U') and we press the trigger the key stoke "backslash" will be pressed (bringing up the communications menu) then the "F1" key will be pressed contacting the nearest tower, then the "F1" key will be pressed again requesting inbound (All with 1 button press)

 

Similarly, you can create a "Shift" layer that is either "Out" [O] or "In" that works like a layer. The button can do something entirely different if you are holding "in" the shift layer. (commonly the pinkie paddle)

i7-6700K, Gigabyte GTX1080 8GB , MSI Z170A, 32GB, 750W

VFA-113

Link to comment
Share on other sites

Thank you for the info. That is exactly what I want to do. But it is still plan B.I look for a possibility to inject key stroke programmatically into DCS. The button filtering incl. modifier is already done in my DLL. I thought on TARGET because it enables at least the HOTAS Warthog to produce Keystroke which are recognized by DCS. That is what I could not get to work out of my DLL.

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

I plan to offer a simple method for a button to keyboard configuration in the Aries Radio Software. Since the community uses all kind of joysticks and throttles, I was looking for a 'universal' solution. This can be achieved with Direct Input , with the Widows API and some dirty tricks like Queue sub classing. But DCS is even uses some tricks which avoid to catch the control over the keyboard. I hoped, that anybody did the keyboard thing already. So, if not, fate...

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

Funny - I'm just about to start down the same journey, and was wondering how to get keystrokes into DCS.

 

I started on a framework to monitor multiple sticks, and are currently using that to send LUA instructions to DCS for SAS and Anti-skid buttons, but now want to add radio related functions.

 

Bit of a bummer that WM_KEYUP etc don't work. Does the same apply for SendKeys?

 

Cheers

 

Peter

Link to comment
Share on other sites

I did not use SendKeys up to now. I used keybd_event and SendInput, where the latter is the newer API function. Both methods go down up to the keyboard interrupt handler and synthesize keystrokes. Windows handles the methods in the correct way and sends the WM_KEYDOWN and WM_KEYUP messages to DCS with the correct parameters. My spy module, which is linked to the DCS message queue, reports the reception and the correct parameters in the messages. But DCS, as application, ignores the messages. They are not processed. My assumption is, that DCS goes another way to the keyboard buffer. A lot of games do that to shorten the time between a keystroke and the reaction of the application.

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

Towsim,

 

You guys should definitely try AutoHotKey scripts.

http://ahkscript.org/

 

It will give you ability to do whatever keys you want from whatever controller you want, even F13 and up...

If it only had a UI on top instead, like now editing script files, it would be awesome. However currently it is super light on memory and "just works".

 

When flying DCS, I use it mostly for PTT for voice activated commands that I have when I press down TM Warthog's MIC, emulated F14 key linked to press/release input state on throttle. MIC down command that is unused in real A-10C Warthog controller profile.

Just a fair example.

AutoHotkey scripts.rar


Edited by Shaman

51PVO Founding member (DEC2007-)

100KIAP Founding member (DEC2018-)

 

:: Shaman aka [100☭] Shamansky

tail# 44 or 444

[sIGPIC][/sIGPIC] 100KIAP Regiment Early Warning & Control officer

Link to comment
Share on other sites

Good point, I did take a look at it originally, but I couldn't send LUA commands so cut my own. But if there isn't a simple api we can use, ahk may well be plan B, do you know if it recognises joysticks buttons numbered above 32?

 

I've also pulled out an x-keys module, that should do the trick if all else fails.

 

Cheers

 

Peter

Link to comment
Share on other sites

Thanks for the response. I had a short look to the source code of AutoHotkey. It is really a mighty tool. What I found out is, that the module, which sends keystrokes, uses the same procedures as I use in my software. This confuses me a totally, because shamandgg obviously uses AutoHotkey with success. I will examine the source code more precise. If it works there it should even work in mine.

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

  • 6 years later...

I'm sure this topic has already been resolved, but I'm posting this because I've run into the same problem.

In my case, the problem was that the virtual key input from DS4Windows (by Jays2Kings) was not recognized by DCS World.

The other day, I noticed that when I enabled the Scan code option on DS4Windows, the key input was recognized by DCS World.

 

DS4Windows seems to be using Win32API's SendInput() for virtual key input.

If you specify the KEYEVENTF_SCANCODE argument, the virtual key will be input in a form that the DCS World can recognize.

In the DS4Windows code, you can use performKeyPress() and performSCKeyPress() to learn how to set the options.

Link to comment
Share on other sites

If you interface DCS from a DLL or even from any external application running on the same computer, the code shown below works very fine.

First of all, you need the window handle of the DCS window. This is done once with GetDCSwindowHandle(). The naming "DCS" and "Digital Combat Simulator" is critical because DCS changed the window name and the window class name several times over the years. The handle is used to switch the keyboard focus to the DCS window before any key is sent. In SendKeyToDCS the focus is switched to DCS first with the API function SetForegroundWindow. After that, the key can be sent with the virtual keycode VK_... and the corresponding keyboard scan code. The latter is language dependent because there are different positions for some keys on different keyboard layouts. For the proper function, the key must be sent twice. The first for a key-down and the second for a key-up signal. Between the two signals a wait of 100 ms is inserted (works even with 10 ms).

FindWindow, SetForegroundWindow, and keybd_event are windows API functions. KEYEVENTF_KEYUP is a constant defined in WinUser.h.

 

[color="DeepSkyBlue"]HWND [/color]DCSwindow = [color="Magenta"]NULL[/color];

[color="DeepSkyBlue"]BOOL [/color][color="DarkRed"]GetDCSwindowHandle[/color]()
{
[color="DeepSkyBlue"]BOOL [/color]rval = [color="Magenta"]FALSE[/color];
[color="DeepSkyBlue"]if[/color](DCSwindow = [color="darkred"]FindWindow[/color]("DCS", "Digital Combat Simulator"))
	rval = [color="magenta"]TRUE[/color];
[color="deepskyblue"]return[/color](rval);
}

[color="deepskyblue"]void [/color][color="darkred"]SendKeyDownToDCS[/color]([color="deepskyblue"]char [/color]VK_virtualCode, [color="deepskyblue"]BYTE [/color]KeyboardScanCode)
{
[color="darkred"]keybd_event[/color](VK_virtualCode, KeyboardScanCode, 0, NULL);
}

[color="deepskyblue"]void [/color][color="darkred"]SendKeyUpToDCS[/color]([color="deepskyblue"]char [/color]VK_virtualCode, [color="deepskyblue"]BYTE [/color]KeyboardScanCode)
{
[color="darkred"]keybd_event[/color](VK_virtualCode, KeyboardScanCode, KEYEVENTF_KEYUP, NULL);
}

[color="deepskyblue"]BOOL [/color][color="darkred"]SendKeyToDCS[/color]([color="deepskyblue"]char [/color]VK_virtualCode, [color="deepskyblue"]BYTE [/color]KeyboardScanCode)
{
[color="deepskyblue"]BOOL [/color]rval = [color="magenta"]FALSE[/color];
[color="deepskyblue"]if[/color](DCSwindow)
{
	[color="darkred"]SetForegroundWindow[/color](DCSwindow);
	[color="darkred"]SendKeyDownToDCS[/color](VK_virtualCode, KeyboardScanCode);
	[color="darkred"]Sleep[/color](100);
	[color="darkred"]SendKeyUpToDCS[/color](VK_virtualCode, KeyboardScanCode);
	rval = [color="magenta"]TRUE[/color];
}
[color="DeepSkyBlue"]return[/color](rval);
}

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...