HOW-TO: Sending real keystrokes to another application

Apr 27 2008 4:09 PM
Hey everybody,

I have been struggeling a lot lately with finding a convenient and reliable solution for my problem.
My  little voice recognition program handles my speech inputs quite properly and according to the speech command I give I want it to send defined keystrokes (associated to the speech command) to a target windows process e.g "Play" focuses Windam and sends a "X" char for playing. This all works kinda ok with SendKeys.SendWait("X"). But I have figured that its kinda unreliable because of the timing issues involved in bringing the application window to the foreground to send the keystroke via SendKeys.SendWait (this method only supports sending to the active application). This becomes even more apparent when during gameplay.

Right now I am using a bunch of code snippets like

[DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

to bring the target window to foreground;
To send the keys the code is here:
        private void sendKeystroke(IntPtr HWnd, string translatedKeystroke)
        {
            IntPtr cwHandle = Win32.GetForegroundWindow();

            if (HWnd != IntPtr.Zero)
            {
                    Win32.SetForegroundWindow(HWnd);
                    SendKeys.Send(translatedKeystroke);
                    Win32.SetForegroundWindow(cwHandle);
            }
        }

HWnd being the targetProcessHandle; translatedKeystroke is the format SendKeys.Send() requires. I switch to the targetApp, send the key, then back again. SendWait() didnt improve the situtation!

This all kinda works but not reliably... (SendKeys.Send() doesnt support the NUMPAD keys for example) so I was looking around for better solutions. I came across the whole

[DllImport("user32.dll",CharSet=CharSet.Auto)]
        public static extern int SendMessage(IntPtr hWnd, int wMsg, char wParam, IntPtr lParam);

dilemma which gives me a headache now for a couple of days. Is there anyone out there who can explain to me how to send KeysStrokes likes ALT+L to another application via the whole SendMessage + VirtualKeyscodes, wParam,. lParam chaos? Yes I was able to make SendMessage work with WM_CLOSE for example to close an app but its different with emulating real keystrokes imho.

I believe an app requires 3 messages to process a char. WM_KEYDOWN, WM_CHAR, WM_KEYUP. Now my question is how to format the SendMessages to make that happen.
Please anyone point me to the right direction so that I can get this blocker out of my way.

Please anyone... I am really desperate now ;(
Thanks & Regards Sören




Answers (6)