• 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);
  • 相关阅读:
    内存中的线程
    python高级线程、进程和进程池
    生产者以及消费者模式(进程池)
    生产者以及消费者模式(多进程)
    生产者以及消费者模式
    全局解释器锁(GIL)
    JoinableQueue队列实现消费之生产者模型
    什么是Sikuli?
    协程基础
    装饰器
  • 原文地址:https://www.cnblogs.com/dyfisgod/p/9474220.html
Copyright © 2020-2023  润新知