How to send continuous keypress to a program?

6

I have been using SendKeys.Send() & SendKeys.SendWait() to send keys to the foreground program (a program different from the application written).

I tried sending a continuous key-press by sending repeatedly the same key with a certain delay between them but the effect was not the same as a continuous keypress in that application.

My question is: How can I send a continuous key-press to a program? The effect of that keypress must be the same as pressing myself that key continuously in the application.

SOLUTION EDIT

The solution was to call the method:

[DllImport("User32.dll")]
static extern int SendMessage(IntPtr hWnd, uint wMsg, UIntPtr wParam, IntPtr lParam);

with the parameters obtained from:

public System.Diagnostics.Process[] p = System.Diagnostics.Process.GetProcessesByName("process");

p[0].MainWindowHandle is hWnd

and using Spy on the window:

right clicking on a message line in Spy shows the wMsg, wParam and lParam (all 3 in hexadecimal)

SendMessage(p[0].MainWindowHandle, (uint)0x0100, (UIntPtr)0x00000041, (IntPtr)(0x001E0001));

By sending only one WM_KEYDOWN message the effect is as the key is pressed continuously. To stop the program acting as the key is continuously pressed i have to press that key on the keyboard and release it, so that WM_KEYUP is generated. Sending WM_KEYUP in the code gives an System.OverFlow "Arithmetic operation resulted in an overflow." exception. Any ideea why that might happen?

Thanks for your replies: Ation and takrl

c#
winforms
console
asked on Stack Overflow Jul 11, 2011 by Răzvan Flavius Panda • edited Jul 11, 2011 by Răzvan Flavius Panda

2 Answers

3

Try to use Win API SendMessage with WM_KEYDOWN and WM_KEYUP. Proper delay should be between this messaging. Also you could use PostMessage for async sending.

[DllImport("User32.dll")]
            public static extern int SendMessage(IntPtr hWnd, uint msg, int wparam, int lparam);
answered on Stack Overflow Jul 11, 2011 by Ation
2

If I get this right, you want to imitate the effect of pressing a key within an application, and then keep it pressed until the OS starts repeating the keystrokes? If that's it, an API approach like @Ation suggested is the way to go.

You should, however, analyze what the application receives, by using a tool like Spy++ or similar. For an OS-repeated keystroke, I believe there's no WM_KEYUP until the key is actually being released. And I don't think you can replicate this behavior by either using SendKeys.Send or SendKEys.SendWait.

EDIT

Here's an excerpt of a Spy++ log, taken of a TextBox control when the letter A is pressed:

<00168> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00173> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00182> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00187> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00196> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00201> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00210> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:4 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00215> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:4 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00224> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00229> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00238> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:4 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00243> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:4 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00252> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00257> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:3 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00266> 00010590 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00271> 00010590 P WM_CHAR chCharCode:'97' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:0
<00280> 00010590 P WM_KEYUP nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:1

As you can see, there's several WM_KEYDOWN followed by WM_CHAR (this may be only relevant to the TextBox I used for this, I'm not sure about that), and a WM_KEYUP at the very end of it. The log had several other messages that didn't seem to be related to pressing the key (they're continuously numbered), but this may vary depending on your app or control you're going to use this for.

Notice the fRepeat:1 on the WM_KEYUP and all previous WM_KEYDOWN except the first one, that seems to denote it's an automatic repetition.

answered on Stack Overflow Jul 11, 2011 by takrl • edited Jul 11, 2011 by takrl

User contributions licensed under CC BY-SA 3.0