使用 C#/Windows API 的虚拟键盘 - 发送键输入,但不获取焦点

Posted

技术标签:

【中文标题】使用 C#/Windows API 的虚拟键盘 - 发送键输入,但不获取焦点【英文标题】:Virtual Keyboard using C#/Windows API - send key input, but don't grab focus 【发布时间】:2013-01-03 14:55:30 【问题描述】:

我正在用 C# 构建一个自定义的虚拟键盘。

重点是将特定的按键发送到当前具有焦点的窗口。但是,通常情况下,虚拟键盘上的键在按下后会获取焦点。

我假设应该为此目的使用某种 Windows API。如果是,是哪一种,如果不是,正确的做法是什么?

【问题讨论】:

处理此类问题的最佳方法是提供一种方法来选择要将输入发送到的进程。 【参考方案1】:

这里有一个很好的资源:@​​987654321@

基本上,创建一个表单并为键使用标签而不是按钮。您将需要覆盖 CreateParams 以设置正确的样式。您还必须覆盖 WndProc 并过滤掉通常将焦点发送到表单的消息。然后将点击事件添加到您的标签并使用SendKeys.Send(keyPressed); 将实际的击键发送到具有焦点的窗口。

以下是链接中的相关代码:

    private const int WS_EX_NOACTIVATE = 0x08000000;

    protected override CreateParams CreateParams
    
        get
        
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle = createParams.ExStyle | WS_EX_NOACTIVATE;
            return createParams;
        
    

    private const int WM_MOUSEACTIVATE = 0x0021;
    private const int MA_NOACTIVATE = 0x0003;
    protected override void WndProc(ref Message m)
    
        //If we're being activated because the mouse clicked on us...
        if (m.Msg == WM_MOUSEACTIVATE)
        
            //Then refuse to be activated, but allow the click event to pass through (don't use MA_NOACTIVATEEAT)
            m.Result = (IntPtr)MA_NOACTIVATE;
        
        else
            base.WndProc(ref m);
    

【讨论】:

【参考方案2】:

我在面板 (The keyb) 中使用面板(用于键)和自定义绘制例程来在中心绘制文本。

点击事件为 SendKeys.Send("1");等等。

这是一个 10 键控制,所以连接事件非常容易。

不必处理任何窗口消息,而且效果很好。我的 10 键没有任何焦点问题,输入会发送到光标所在的位置。很简单。

【讨论】:

以上是关于使用 C#/Windows API 的虚拟键盘 - 发送键输入,但不获取焦点的主要内容,如果未能解决你的问题,请参考以下文章

C 虚拟键盘输入有选择地工作

如何监听windows虚拟键盘

使用 32 位 JRE 打开 64 位 windows 虚拟键盘

在 Windows 10 上具有多个虚拟桌面的 C# UI 自动化 API

Windows 10 上 TabTip.exe(虚拟键盘)的大小和位置?

win7系统下如何调出虚拟键盘