我正在开发一个项目,在这个项目中,有必要模拟按键以在不同的应用程序中引起特定的行为。
使用正在导入的keybd_event函数(可能有更好的方法,但它运行正常),所有运行正常且运行正常。
现在我想为所有小键盘添加特定的支持。
看e。 G。在这里http://msdn.microsoft.com/en-us/library/dd375731(v=VS.85).aspx或在System.Windows.Input.Key命名空间中,我可以轻松找到Num0..Num9以及NumLock的键。但是......我找不到Num /,Num +,NumEnter等的任何东西。
我写了一个快速的应用程序来捕捉keydown事件,输出事件参数,并得到了一些有趣的结果:
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None
e.KeyCode Return e.KeyData Return e.KeyValue 13 e.Modifiers None
Num + Key(依此类推)似乎是Windows调用功能键的键(如Num +键的F18)。所以..这很奇怪,但还可以。
但是......我无法区分Enter-Key和NumEnter Key。这些与我的应用程序不同,因此我必须为两者发送特定的密钥代码。
这就是我的问题:如何发送普通的回车密钥以及如何发送NumEnter密钥?
(我不知道它是否有任何区别,我使用的是德语键盘布局。)
任何想法的Thx!
答案 0 :(得分:3)
我发现这个here 对我有用!
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);
}
}
答案 1 :(得分:1)
感谢andreas提供解决方案的开始。这是一个更完整的版本:
[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
}
答案 2 :(得分:0)
既然你正在谈论一个其他方式的解决方案,检测事件,我想提高它,我甚至不必覆盖WndProc。我可以简单地发送自己的消息。
从您的解决方案中,我查看了SendMessage / PostMessage,然后是WM_KEYDOWN和WM_KEYUP。文档实际上为您提供了信息(如果您看起来真的很难)。
http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms646281(v=vs.85).aspx
所以我的解决方案(编译,现在找到正确的窗口(在哪里输入文本))是这样的:
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
希望它对其他人也有用。正如Vendetta对我的提示一样。
并且..如果你有更好的解决方案,请说出来!