Jump to content
  • Advertisement
Sign in to follow this  
LostAgain

[.net] Simulate Keypress and Directx

This topic is 4215 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to write a program that will send a keypress (and eventually i will do a mouse move / press also) to an appliction. i tried using the managed sendinput and while it works in normal applications it does NOT work in Directx applications. any suggestions? i am trying to figure out the pinvoke version of SenInput but having very little luck at the moment so if you happen to know what to do in order to get this to work please help.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by LostAgain
I'm trying to write a program that will send a keypress (and eventually i will do a mouse move / press also) to an appliction. i tried using the managed sendinput and while it works in normal applications it does NOT work in Directx applications. any suggestions? i am trying to figure out the pinvoke version of SenInput but having very little luck at the moment so if you happen to know what to do in order to get this to work please help.


If it's ANY application...this should do the trick. Just be sure to modify it for what you want...it's straight out of one of my toys.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace wiseKontrol.CommandClasses
{
class InsertText : BaseCommand
{
public InsertText()
{
this.SCommandName = "InsertText";
this.SMenuItemName = "Insert Te&xt";
this.SArgumentHelp = "Enter the text to be inserted:";
}

public const ushort KEYEVENTF_KEYUP = 0x0002;
public const ushort KEYEVENTF_KEYDOWN = 0x0000;
public const ushort KEYEVENTF_SCANCODE = 0x0008;
public const ushort KEYEVENTF_UNICODE = 0x0004;

public struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public long time;
public uint dwExtraInfo;
};

[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public KEYBDINPUT ki;
};


[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

public override void executeCommand()
{
INPUT structInput;
structInput = new INPUT();
structInput.type = 1;
structInput.ki.wScan = 0;
structInput.ki.wVk = 0;
structInput.ki.time = 0;
structInput.ki.dwFlags = 0;
structInput.ki.dwExtraInfo = 0;

foreach (char c in SArgument.ToCharArray())
{
structInput.ki.dwFlags = KEYEVENTF_UNICODE;
structInput.ki.wScan = (ushort)c;
SendInput(1, ref structInput, Marshal.SizeOf(structInput));

structInput.ki.dwFlags = KEYEVENTF_UNICODE;
structInput.ki.dwFlags += KEYEVENTF_KEYUP;
structInput.ki.wScan = (ushort)c;
SendInput(1, ref structInput, Marshal.SizeOf(structInput));

}
}
}
}

Share this post


Link to post
Share on other sites
Yup. go to a text window and it works go to my directx application and it doesn't.

Anyone else have some ideas?

I was thinking maybe throwing in a windowshookex and using the journalplay think like one of the msdn files i was reading said but reading that was like slamming my face into a wall. i got nothing out of it but a headache.

Share this post


Link to post
Share on other sites
Quote:
Original post by LostAgain
Yup. go to a text window and it works go to my directx application and it doesn't.

Anyone else have some ideas?

I was thinking maybe throwing in a windowshookex and using the journalplay think like one of the msdn files i was reading said but reading that was like slamming my face into a wall. i got nothing out of it but a headache.


That's odd...I use it just fine in Warcraft III to hold down my alt key for life checking =0 Well good luck finding a solution, I just tossed it out there since I had it lying around.

Share this post


Link to post
Share on other sites
For my program that simulates key presses in games I use the KEYEVENTF_SCANCODE in the dwFlags. I had a similar problem as you but I played around for a while and found that DirectInput will only react if you add KEYEVENTF_SCANCODE and you add the scan code in wScan.

Edit: Also I should mention that just casting the char to the scan code didn't work for me, the proper scan codes can be found at Microsoft.DirectX.DirectInput.Key (I'm not sure where they are in unmanaged, sorry).

Share this post


Link to post
Share on other sites
i am relativly certai i tried this (Ox100 or Ox001 i forget which it was that it's defined as) but i will try again. i am nearlly certain what i need to do is either hook in and inject my own code (ala another post on this board from almost 2 years ago) OR provide an alternative wrapper directinput dll that emulates the current dll but with a direct pipeline to access the keystates (either of which is an inelegant time consumming and risky method of doing this)

oh well will play with it some more to try.

on the possitive side they no longer use directinput for mouse work and instead use the system mouse and htis is pretty simple to work with. so i can do that relativly easilly.

Share this post


Link to post
Share on other sites
Odd, my program works perfectly in every single game I've tried it in (about 10), and I know for sure that some of them used DI for input. I can post some sections of my app if that would help...

Share this post


Link to post
Share on other sites
i would appriciate that greatly. in exchange i will package it into a nice little .net class library along with modified send cursor and send keyboard routines making everything in nice one package. figure other people have the same issue and would definatly like this also. if you have any form of repetitive stress syndrom not having to hit a button over and over just because a developer said to is so very nice. <clutches his wrist in agony> my wrist thanks you

Share this post


Link to post
Share on other sites
Ok, here is where I define the unmanaged stuff:

[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
public UInt32 type;
//KEYBDINPUT:
public ushort wVk;
public ushort wScan;
public UInt32 dwFlags;
public UInt32 time;
public UIntPtr dwExtraInfo;
//HARDWAREINPUT:
public UInt32 uMsg;
public ushort wParamL;
public ushort wParamH;
}

enum SendInputFlags
{
KEYEVENTF_EXTENDEDKEY = 0x0001,
KEYEVENTF_KEYUP = 0x0002,
KEYEVENTF_UNICODE = 0x0004,
KEYEVENTF_SCANCODE = 0x0008,
}

[DllImport("user32.dll")]
static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);



And here is where I get the scan code. It's messy, I know, but I simply couldn't find any other way to do it.


private Key GetScanCode(char Letter)
{
switch(Letter)
{
case '0':
return Key.D0;

case '1':
return Key.D1;

case '2':
return Key.D2;

case '3':
return Key.D3;

case '4':
return Key.D4;

case '5':
return Key.D5;

case '6':
return Key.D6;

case '7':
return Key.D7;

case '8':
return Key.D8;

case '9':
return Key.D9;

case 'a':
case 'A':
return Key.A;

case 'b':
case 'B':
return Key.B;

case 'c':
case 'C':
return Key.C;

case 'd':
case 'D':
return Key.D;

case 'e':
case 'E':
return Key.E;

case 'f':
case 'F':
return Key.F;

etc...



And this is how I make the call:


INPUT[] InputData = new INPUT[1];
Key ScanCode = GetScanCode(ControllerScheme.KeyMappings[Count]);

InputData[0].type = 1; //INPUT_KEYBOARD
InputData[0].wScan = (ushort)ScanCode;
InputData[0].dwFlags = (uint)SendInputFlags.KEYEVENTF_SCANCODE;

if (SendInput(1, InputData, Marshal.SizeOf(InputData[0])) == 0)
{
System.Diagnostics.Debug.WriteLine("SendInput failed with code: " +
Marshal.GetLastWin32Error().ToString());
}



And that's all I do.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!