• 不在同一程序内,如何在光标处(当前有焦点的窗体输入框)输入字符


    因测试一个程序,该程序的安卓端执行扫描条码二维码操作,然后服务器端需要在PC当前处于激活状态的窗体的当前光标处显示安卓程序扫描到的条形码。这是博主“小李飞菜刀”的扫描宝服务程序。场景就是苦于手边没有扫描枪,又想测试条码扫描。“小李飞菜刀”同学使用的是 "SendKeys"的“Send”方法。这是同一应用才能有效的办法。如果需要在其他应用的光标处输入字符,就只有使用"SendMessage"的windows api了。经过一番搜索,抄到段代码,测试了一下没有效果,TNND。请围观:

            [DllImport("user32.dll")]
            public static extern IntPtr GetForegroundWindow();
    
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
            [DllImport("user32.dll")]
            static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
    
            [DllImport("user32.dll")]
            static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui);
    
    
            [StructLayout(LayoutKind.Sequential)]
            public struct GUITHREADINFO
            {
                public int cbSize;
                public int flags;
                public IntPtr hwndActive;
                public IntPtr hwndFocus;
                public IntPtr hwndCapture;
                public IntPtr hwndMenuOwner;
                public IntPtr hwndMoveSize;
                public IntPtr hwndCaret;
                public RECT rectCaret;
            }
    
            public static GUITHREADINFO? GetGuiThreadInfo(IntPtr hwnd)
            {
                if (hwnd != IntPtr.Zero)
                {
                    //Mbox.Info(GetTitle(hwnd), "O");
                    uint threadId = GetWindowThreadProcessId(hwnd, IntPtr.Zero);
    
                    GUITHREADINFO guiThreadInfo = new GUITHREADINFO();
                    guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo);
    
                    if (GetGUIThreadInfo(threadId, ref guiThreadInfo) == false)
                        return null;
                    return guiThreadInfo;
                }
                return null;
            }
    
            public static void SendText(string text)
            {
                IntPtr hwnd = GetForegroundWindow();
                if (String.IsNullOrEmpty(text))
                    return;
                Hwindow.GUITHREADINFO? guiInfo = Hwindow.GetGuiThreadInfo(hwnd);
                if (guiInfo != null)
                {
                    IntPtr ptr = (IntPtr)guiInfo.Value.hwndCaret;
                    if (ptr != IntPtr.Zero)
                    {
                        for (int i = 0; i < text.Length; i++)
                        {
                            SendMessage(ptr, Message.WM_CHAR, (IntPtr)(int)text[i], IntPtr.Zero);
                        }
                    }
                }
            }
    

     这是csdn抄的,原文:C#怎么获得当前屏幕光标的位置,然后在光标的位置上输入想输入数据

    发现RECT没办法被感知,又一番搜索发现是个结构体:

    [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                int left;
                int top;
                int right;
                int bottom;
            }
    

    加上之后可以编译成功。但是没效果,仔细调试下来对方法“SendText”进行了修改。代码的主要思路:用GetForegroundWindow找到焦点窗体,

    然后GetWindowThreadProcessId和GetGUIThreadInfo找到含有光标的控件句柄,即GUITHREADINFO中的hwndCaret,然后用该句柄发送消息。

    下面贴上修改后有效果的代码:

     [DllImport("user32.dll")]
            public static extern IntPtr GetForegroundWindow();
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
            [DllImport("user32.dll")]
            static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
            [DllImport("user32.dll")]
            static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui);
            [StructLayout(LayoutKind.Sequential)]
            public struct GUITHREADINFO
            {
                public int cbSize;
                public int flags;
                public IntPtr hwndActive;
                public IntPtr hwndFocus;
                public IntPtr hwndCapture;
                public IntPtr hwndMenuOwner;
                public IntPtr hwndMoveSize;
                public IntPtr hwndCaret;
                public RECT rectCaret;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                int left;
                int top;
                int right;
                int bottom;
            }
            public GUITHREADINFO? GetGuiThreadInfo(IntPtr hwnd)
            {
                if (hwnd != IntPtr.Zero)
                {
                    uint threadId = GetWindowThreadProcessId(hwnd, IntPtr.Zero);
                    GUITHREADINFO guiThreadInfo = new GUITHREADINFO();
                    guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo);
                    if (GetGUIThreadInfo(threadId, ref guiThreadInfo) == false)
                        return null;
                    return guiThreadInfo;
                }
                return null;
            }
    
            protected void SendText(string text)
            {
                IntPtr hwnd = GetForegroundWindow();
                if (String.IsNullOrEmpty(text))
                    return;
                GUITHREADINFO? guiInfo = GetGuiThreadInfo(hwnd);
                if (guiInfo != null)
                {
                    for (int i = 0; i < text.Length; i++)
                    {
                        SendMessage(guiInfo.Value.hwndFocus, 0x0102, (IntPtr)(int)text[i], IntPtr.Zero);
                    }
                }
            }
    

      

    主要发现 “IntPtr ptr = (IntPtr)guiInfo.Value.hwndCaret;”,这里始终是0.改成: SendMessage(guiInfo.Value.hwndFocus, 0x0102, (IntPtr)(int)text[i], IntPtr.Zero);

    hwndFocus字面意思就是当前光标处的句柄。搞定,收工!

  • 相关阅读:
    浅析软件开发项目的前期沟通工作
    .net core 和 WPF 开发升讯威在线客服系统:实现对 IE8 的完全完美支持 【干货】
    产品的定价策略(一):想通过产品挣钱,首先你产品的目标客户得不差钱
    .net core 和 WPF 开发升讯威在线客服系统:使用线程安全的 BlockingCollection 实现高性能的数据处理
    .net core 和 WPF 开发升讯威在线客服系统:使用 TCP协议 实现稳定的客服端
    .net core 和 WPF 开发升讯威在线客服系统:使用 WebSocket 实现访客端通信
    Centos上配置两层nginx转发,把请求转发到外网
    真实字节二面:什么是伪共享?
    关于MVCC,我之前写错了,这次我改好了!
    从家庭主妇到格力老总,董明珠的大女主逆袭之路
  • 原文地址:https://www.cnblogs.com/datacool/p/win_api_sendmessage_hwndFocus.html
Copyright © 2020-2023  润新知