I am working on a project where it is necessary to simulate key-presses to cause specific behaviours in a different application.
All is running well and fine, using
Since you are talking about a the-other-way-round solution, detecting the event, and I want to raise it, I don't even have to override the WndProc. I can simply send my own messages.
From your solution, I had a look at SendMessage/PostMessage, and then WM_KEYDOWN and WM_KEYUP. The documentation actually gives you the info (if you look really really hard).
http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms646281(v=vs.85).aspx
So my solution (compiles and now with finding the right window (where to enter the text)) is like this:
bool keyDown = true; // true = down, false = up
const uint WM_KEYDOWN = 0x0100;
const uint WM_KEYUP = 0x0101;
const int VK_RETURN = 0x0D;
IntPtr handle = IntPtr.Zero;
// Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!)
IntPtr foreGroundWindow = GetForegroundWindow();
// now get process id of foreground window
uint processID;
uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID);
if (processID != 0)
{
// now get element with (keyboard) focus from process
GUITHREADINFO threadInfo = new GUITHREADINFO();
threadInfo.cbSize = Marshal.SizeOf(threadInfo);
GetGUIThreadInfo(threadID, out threadInfo);
handle = (IntPtr)threadInfo.hwndFocus;
}
int lParam = 1 << 24; // this specifies NumPad key (extended key)
lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message
PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter
Hope it is useful to someone else as well. As was Vendetta's tip to me.
And.. if you do have a better solution, please say so!
I found this here works for me !
protected override void WndProc(ref Message m)
{
if (m.Msg == 256 && m.WParam.ToInt32() == 13)
{ // WM_KEYDOWN == 256, Enter == 13
if ((m.LParam.ToInt32() >> 24) == 0)
{
MessageBox.Show("main enter pressed!");
}
else
{
MessageBox.Show("numpad enter pressed!");
}
}
else
{
base.WndProc(ref m);
}
}
thanks to andreas for providing the beginning of a solution. here's a more complete version:
[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui);
public struct GUITHREADINFO
{
public int cbSize;
public int flags;
public int hwndActive;
public int hwndFocus;
public int hwndCapture;
public int hwndMenuOwner;
public int hwndMoveSize;
public int hwndCaret;
public System.Drawing.Rectangle rcCaret;
}
private void sendNumpadEnter()
{
bool keyDown = true; // true = down, false = up
const uint WM_KEYDOWN = 0x0100;
const uint WM_KEYUP = 0x0101;
const int VK_RETURN = 0x0D;
IntPtr handle = IntPtr.Zero;
// Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!)
IntPtr foreGroundWindow = GetForegroundWindow();
// now get process id of foreground window
uint processID;
uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID);
if (processID != 0)
{
// now get element with (keyboard) focus from process
GUITHREADINFO threadInfo = new GUITHREADINFO();
threadInfo.cbSize = Marshal.SizeOf(threadInfo);
GetGUIThreadInfo(threadID, out threadInfo);
handle = (IntPtr)threadInfo.hwndFocus;
}
int lParam = 1 << 24; // this specifies NumPad key (extended key)
lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message
PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter
}