Here is my code that I use to simulate a tab-keypress in a certain process:
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
public Form1()
{
PostMessage(MemoryHandler.GetMainWindowHandle(),
(int)KeyCodes.WMessages.WM_KEYDOWN,
(int)KeyCodes.VKeys.VK_TAB, 0);
InitializeComponent();
}
Is there any way to extend it so that it presses the key for (example) 1 second, instead of just tapping it?
Please note that I'm not interested in a Thread.Sleep()
solution that blocks the UI thread.
To simulate native-language keystrokes, you can also use the [Xnn] or [Dnn] constants in the string passed to the Keys method. nn specifies the virtual-key code of the key to be “pressed”. For instance, [X221]u[X221]e will “type” the u and e characters with the circumflex accent.
You'll need to start by downloading and installing AutoHotkey, which is a simple scripting language that allows you to create easy scripts. Once you do that, right-click anywhere and choose New –> AutoHotkey Script. This simple script will wait every 30 minutes and press the Spacebar.
The repeating of a keystroke when you hold it down is a feature that's built into the keyboard controller. A microprocessor that's built into the keyboard itself. The 8042 microcontroller was the traditional choice, the keyboard device driver still carries its name.
So, no, this is not done by Windows and PostMessage() is not going to do it for you. Not exactly a problem, you can simply emulate it with a Timer.
If you want to simulate what Windows does with messages, you likely want to find out how fast the key repeat rate is. That can be found at HKEY_CURRENT_USER\Control Panel\Keyboard\KeyboardSpeed
. there's also the KeyboardDelay
value.
What Windows does is send a WM_KEYDOWN
and a WM_CHAR
when a key is initially pressed. Then, if the key is still pressed after KeyboardDelay
time span, the WM_KEYDOWN
and WM_CHAR
pair are repeated every KeyboardSpeed
until the key is depressed--at which point WM_KEYUP
is sent.
I would suggest using a Timer
to send the messages at a specific frequencies.
for example:
int keyboardDelay, keyboardSpeed;
using (var key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Keyboard"))
{
Debug.Assert(key != null);
keyboardDelay = 1;
int.TryParse((String)key.GetValue("KeyboardDelay", "1"), out keyboardDelay);
keyboardSpeed = 31;
int.TryParse((String)key.GetValue("KeyboardSpeed", "31"), out keyboardSpeed);
}
maxRepeatedCharacters = 30; // repeat char 30 times
var startTimer = new System.Windows.Forms.Timer {Interval = keyboardSpeed};
startTimer.Tick += startTimer_Tick;
startTimer.Start();
var repeatTimer = new System.Windows.Forms.Timer();
repeatTimer.Interval += keyboardDelay;
repeatTimer.Tick += repeatTimer_Tick;
//...
private static void repeatTimer_Tick(object sender, EventArgs e)
{
PostMessage(MemoryHandler.GetMainWindowHandle(),
(int)KeyCodes.WMessages.WM_KEYDOWN,
(int)KeyCodes.VKeys.VK_TAB, 0);
PostMessage(MemoryHandler.GetMainWindowHandle(),
(int)KeyCodes.WMessages.WM_CHAR,
(int)KeyCodes.VKeys.VK_TAB, 0);
counter++;
if (counter > maxRepeatedCharacters)
{
Timer timer = sender as Timer;
timer.Stop();
}
}
private static void startTimer_Tick(object sender, EventArgs eventArgs)
{
Timer timer = sender as Timer;
timer.Stop();
PostMessage(MemoryHandler.GetMainWindowHandle(),
(int)KeyCodes.WMessages.WM_KEYDOWN,
(int)KeyCodes.VKeys.VK_TAB, 0);
PostMessage(MemoryHandler.GetMainWindowHandle(),
(int)KeyCodes.WMessages.WM_CHAR,
(int)KeyCodes.VKeys.VK_TAB, 0);
}
When holding a key down on a physical keyboard, repeated keystrokes are passed to the active window. This is not built into the keyboard, but is a Windows feature.
You can simulate this by doing the following steps in order:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With