wpf 虚拟键盘 对外部程序
对外部程序,以记事本为例,xaml中设置模拟按键的控件 Focusable="False":
/// <summary> /// 发送按键 /// </summary> /// <param name="asiiCode">键盘ascii码</param> private void SendKey(byte asiiCode) { try { int getFocus = 0; AttachThreadInput(true, ref getFocus); Win32API.SetForegroundWindow((IntPtr)getFocus); Win32API.Keybd_event(asiiCode, 0x45, 0x1 | 0, 0);//keydowm Win32API.Keybd_event(asiiCode, 0x45, 0x1 | 0x2, 0);//keyup AttachThreadInput(false, ref getFocus); //取消线程亲和的关联 } catch (Exception ex) { MessageBox.Show("SendKey:" + ex.ToString()); } } /// <summary> /// 设置线程亲和,附到前台窗口所在线程,只有在线程内才可以获取线程内控件的焦点 /// </summary> /// <param name="b">是否亲和</param> private void AttachThreadInput(bool b,ref int hwnd) { try { Process[] processes = Process.GetProcessesByName("notepad"); if (processes.Length == 0) { return; } int processId = processes[0].Id; hwnd = processes[0].MainWindowHandle.ToInt32(); Win32API.AttachThreadInput( processId, Win32API.GetCurrentThreadId(), Convert.ToInt32(b)); } catch (Exception ex) { MessageBox.Show("AttachThreadInput:" + ex.ToString()); } }
对内部窗口(可引用该虚拟键盘组件的),不用考虑焦点问题(焦点在哪就在哪输出),做好Keybd_event就行了
不推荐SendMessage、PostMessage等方法发送按键,实在不行推荐使用SendWait
以上相关底层调用方法:
[DllImport("user32.dll", EntryPoint = "keybd_event")] public static extern void Keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll")] public static extern int AttachThreadInput( int idAttach, int idAttachTo, int fAttach); [DllImport("kernel32.dll")] public static extern int GetCurrentThreadId(); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);