You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用SendKeys开发屏幕键盘时鼠标被后台抢占如何解决

问题核心原因

你遇到的异常和SendKeys.Send/SendKeys.SendWait接口本身无关,核心差异在窗口行为:

  • 你自己开发的自定义键盘窗口在点击按键时,会自动成为前台激活窗口,原本运行的CNC配套程序失去输入焦点后,触发了程序内置的焦点保护逻辑,直接抢占鼠标/输入控制权,导致后续无法操作键盘。
  • 微软自带OSK在窗口创建时就配置了特殊扩展属性,永远不会抢占前台焦点,所有按键发送过程中目标CNC程序始终持有输入焦点,自然不会触发控制权抢占逻辑。
对齐OSK行为的实现方案

不要用「点击按键后手动把焦点切回CNC程序」的临时方案,这种方式会出现窗口闪烁、焦点切换延迟,在工业控制场景下容易触发误操作,直接按照OSK的原生实现逻辑修改窗口属性即可。

第一步:给键盘窗口添加不抢焦点的扩展样式

WinForm 项目实现

直接在自定义键盘的窗体类中重写相关逻辑:

// Windows API 常量定义
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int WS_EX_TOOLWINDOW = 0x00000080;
private const int WS_EX_TOPMOST = 0x00000008;
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATE = 0x0003;

// 重写窗口参数配置
protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        // 核心配置:窗口永远不会被激活,和OSK核心行为对齐
        cp.ExStyle |= WS_EX_NOACTIVATE;
        // 可选配置:设为工具窗口,不在Alt+Tab切换列表、任务栏中显示多余项
        cp.ExStyle |= WS_EX_TOOLWINDOW;
        // 可选配置:窗口置顶,避免被CNC程序界面遮挡
        cp.ExStyle |= WS_EX_TOPMOST;
        return cp;
    }
}

// 重写窗口消息处理,拦截鼠标点击时的激活请求
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_MOUSEACTIVATE)
    {
        m.Result = (IntPtr)MA_NOACTIVATE;
        return;
    }
    base.WndProc(ref m);
}

WPF 项目实现

在窗体的SourceInitialized事件中添加扩展样式配置:

// Windows API 定义
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int GWL_EXSTYLE = -20;
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

private void CustomKeyboardWindow_SourceInitialized(object sender, EventArgs e)
{
    WindowInteropHelper interopHelper = new WindowInteropHelper(this);
    int currentExStyle = GetWindowLong(interopHelper.Handle, GWL_EXSTYLE);
    // 添加强制不激活样式
    SetWindowLong(interopHelper.Handle, GWL_EXSTYLE, currentExStyle | WS_EX_NOACTIVATE);
    // 配置窗口置顶
    this.Topmost = true;
    this.ShowInTaskbar = false;
}

第二步:输入发送的兼容配置

  1. 权限对齐:如果CNC配套程序是以管理员权限运行的,你的自定义键盘程序也需要以管理员身份启动,否则Windows UIPI权限机制会拦截跨权限的输入消息,导致按键发送失效。
  2. 稳定性优化:如果遇到SendKeys在部分场景下偶发失效,可以替换为user32.dll提供的SendInput接口模拟按键,这个接口是底层输入接口,模拟的按键和物理键盘触发的输入链路完全一致,对工业类程序的兼容性比SendKeys更好。

效果验证

配置完成后运行程序,点击自定义键盘按键时,通过任务管理器可以看到前台进程始终是CNC配套程序,你的键盘窗口不会抢到输入焦点,和官方OSK的行为完全一致,CNC程序不会触发控制权抢占逻辑,可正常连续操作。

内容的提问来源于stack exchange,提问作者AB Studio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:33:12