Skip to main content
GameDev.net gamedev.net
🔒 Locked

Help Needed - DirectX and SendKeys

Started by DaphydTheBard Jan 16, 2006 at 10:22 AM 14 replies 14.3k views
Original Post
DaphydTheBard
DaphydTheBard
Hi everyone I'm having a real nightmare with a little project I'm trying to create and wondered if I could get you guys here to scratch your heads on my behalf. Basically, I'm writing a little program similar to Game Commander. The idea is that the program recognises spoken commands, and can then generate keypress events in response. In principle, the program works. I have the voice recognition working (using the Sphinx engine), and it will happily send keystrokes to windows programs such as notepad, word etc. However, the game I'm trying to send commands to (X3:Reunion) uses DirectX to control the keyboard. I've trawled the net for days trying to find a way to simulate keystrokes that DirectInput will "see" but I can't find anything anywhere. If anyone here can help me out I'll be very grateful. I'm writing my application in VB6 so VB code samples would be preferred! :) Does anyone know of a way to send keystrokes to a directx application? Many thanks in advance. Daphyd
Armadon
Armadon
I don't know if this might be usefull but if your program can emulate keystrokes it should be a matter of reading the config of the particular game or check the config in the game itself and then map those keys to voice commands. Let's say you take for example a game like Need for speed. Mapping the arrow keys (default keys) to your application via voice commands.

I hope this helps.
Take care.
DaphydTheBard
DaphydTheBard
Thanks for your reply Armadon, but I don't think you've understood my question.

The problem is not figuring out which keys do what, or even transmitting them.

The problem is that DirectInput interfaces with the keyboard at driver level, whereas SendKeys and SendInput communicate with *windows* at API level.

So, to use your example to elaborate, if Need for Speed used the UP arrow for accelerate, it doesn't matter how many times I get my program to transmit the up arrow key, the game will ignore it. Other programs like word, excel, or notepad will happily except and use the up arrow, but games that use DirectInput ignore these conventional methods of keypress emulation.

What I need is a way of generating keypresses at a low system level that other running directx applications "listening" for keypresses will hear and interpret as if the person playing the game had physically pressed a key.

jollyjeffers
jollyjeffers
Okay, from the outset - what you're doing is not exactly common, nor is it trivial [smile]

As you've correctly realised - DInput is a low-level API, thus it would require a suitably low-level entry point for your application. I'm pretty sure that, by design, such a thing doesn't exist..

I've seen various people post on these forums about similar things, and a lot of them end up on very dubious legal territory - game modification and reverse engineering is usually an infringement of the licence OR the applicable laws [oh]

One possibility that I can think of is to try something similar to Muhammad's D3D Device Hooking sample. Try and inject your code into a layer above IDirectInputDevice8 and then inject your own key codes into the buffered/polling sections.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
Muhammad Haggag
Muhammad Haggag
Quote:
Original post by jollyjeffers
As you've correctly realised - DInput is a low-level API, thus it would require a suitably low-level entry point for your application. I'm pretty sure that, by design, such a thing doesn't exist..

I used to think so until someone said in one of the threads here that SendKeys is actually lower level than DInput, and that he used it successfully. I've also seen Dustin say, more than once, that DInput on XP is no longer that low-level. So perhaps this only works under XP?

jollyjeffers
jollyjeffers
Quote:
Original post by Muhammad Haggag
Quote:
Original post by jollyjeffers
As you've correctly realised - DInput is a low-level API, thus it would require a suitably low-level entry point for your application. I'm pretty sure that, by design, such a thing doesn't exist..

I used to think so until someone said in one of the threads here that SendKeys is actually lower level than DInput, and that he used it successfully. I've also seen Dustin say, more than once, that DInput on XP is no longer that low-level. So perhaps this only works under XP?

Yeah, I've heard some mixed things about how low DInput is... I eventually came to the conclusion that it might not be low-level, but it's still "partitioned" in a way that to external API's/applications it still is. I suppose this partitioning is important in the sense that Win32 and DInput are seperate enough such that you're unlikely to be able to find regular Win32 calls that can interact with DInput.

Maybe digging around in some of the low-level hardware stuff is a good bet - dig up the DDK and see if you can get right down to the driver level without too much hassle.

Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
DaphydTheBard
DaphydTheBard
I think that this might be a little over my head :-)

I don't suppose one of you could write me a little DLL that can hook into Direct Input in another process and inject keypresses into it?

Thanks for all the replies.
Muhammad Haggag
Muhammad Haggag
Quote:
Original post by DaphydTheBard
I don't suppose one of you could write me a little DLL that can hook into Direct Input in another process and inject keypresses into it?

You know, that officially counts as seduction [lol]

I'll try to do an example in the next couple of days.

Muhammad Haggag
Muhammad Haggag
Ok, today I converted the D3D-hook sample into another one which does DInput hooking. I've not added exemplary key injectino code yet, so I'll probably release this tomorrow, God-willing.

load_bitmap_file
load_bitmap_file
Quote:
Original post by Muhammad Haggag
Quote:
Original post by jollyjeffers
As you've correctly realised - DInput is a low-level API, thus it would require a suitably low-level entry point for your application. I'm pretty sure that, by design, such a thing doesn't exist..

I used to think so until someone said in one of the threads here that SendKeys is actually lower level than DInput, and that he used it successfully. I've also seen Dustin say, more than once, that DInput on XP is no longer that low-level. So perhaps this only works under XP?


I found this nice SendKeys wrapper, but it doesn't seem to work with any games that use DirectInput on a XP Home* machine.

*stop laughing :P
DaphydTheBard
DaphydTheBard
Muhammad,

If you can get this working for me you'll be my new bestest friend, for ever :)

I'm prepared to pay for this code, if necessary, not sure how things work here as I've not been registered here long. :-)

In an idea world what I need is something like this:

A DLL that exposes a COM interface that I can reference through my VB project.

Ideally, all of the wrapper DirectInput code is hidden away in the DLL and happens transparently (ie. functions such as directinputcreate etc. are automated and passed back to the hooked app seamlessly), and the only methods I need exposed to my application are along these lines:

HookIntoApp (hWnd As long)
OR
HookIntoApp (AppTitle As String)

So that I can hook up to the game in question.

Then I simply need function that behaves like SendKeys, so I can do stuff like:

DInputSendKeys("^C") 'Send Shift + C
DInputSendKeys("{F 4}") 'Send F key 4 times

That sort of thing.

I would imagine the SendKeys function would simply buffer the keys I want to transmit until the next time the hooked application called a GetDeviceStateKeyBoard call, at which point the DLL would "inject" my additional keypresses on top of any "real" keypresses.

If you can get this working, you'll make a LOT of people happy, myself being one of them :)

I shall keep checking this thread in very eager anticipation of any results.

Thanks muchly for volunteering to help!

PS: Hope I'm not asking too much :-)

[Edited by - DaphydTheBard on January 18, 2006 7:59:17 AM]
Muhammad Haggag
Muhammad Haggag
Ok, I got a proof-of-concept up and running today, but:
1) It's still ugly
2) It doesn't allow sending arbitrary keys yet (i.e. keys to send are hardwired - you have to write the sending loop yourself).

I'm not doing this COM-style, but it should still be accessible to you via VisualBasic (Sockets or command-line control). You can add me on MSN if you wish to discuss things further. (mhaggag at google's beta mail service)

LetsKillDave
LetsKillDave
One thing you might want to investigate is Microsoft Active Accessibility. It was actually designed for this, althought I can't say if it will work with games. Of course, Muhammad's example may suit your needs perfectly, but I at least wanted to point you to an alternative...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/accessibility.asp
David "LetsKillDave" WellerNVIDIA Developer Programs ManagerPersonal blog http://letskilldave.comPersonal Twitterfeed: letskilldaveNVIDIA Developer Announcements Twitterfeed: nvidiadeveloper (clever name, eh? :-)
DaphydTheBard
DaphydTheBard
Cheers David.

I had a look through the link you sent me (what I could understand) and it eventually came in a big circle and back to .....SendInput :P

I've tried this out again just for the sake of absolute certainty that it definately doesn't work with DirectX....and it doesn't :(

So looks like I'm still waiting apprehensively for Mr M's code!

(Which I REALLY am anxious to get my hands on!)
-Fruz-
-Fruz-
this is just what i was looking for too!
I hope you can share your code with me too Muhammad,
I've been looking for how to do this for some time now.
I saw some suggestion that suggested to create a device driver,
but I think that is kind of out reach from my coding knowledge.
jollyjeffers
jollyjeffers
Quote:
Original post by -Fruz-
this is just what i was looking for too!
I hope you can share your code with me too Muhammad

Point your browser here and pass on your thanks to Muhammad for a job well done [grin]

Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.