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

C#如何实现全局禁用Windows键但当前WinForm窗口内可正常触发

解决方案

实现逻辑

低级键盘钩子触发时新增当前激活窗口判断:

  • 若当前前台窗口属于你自己的程序,Win键不拦截,正常向下传递给WebBrowser内的Guacamole远程桌面
  • 若当前前台窗口是其他程序窗口,直接拦截Win键实现全局禁用效果

代码修改步骤

  1. 新增必要的Win32 API声明,放在你的其他DllImport代码块内:
// 获取当前激活的前台窗口句柄
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
// 获取窗口所属的进程ID(用于容错判断)
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
  1. 修改captureKey方法内的Win键拦截逻辑:
    原逻辑是只要检测到Win键就直接返回1拦截,现在新增窗口所属进程判断:
private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
{
    if (nCode >= 0)
    {
        KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
        // 检测是否为Win键
        if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin)
        {
            IntPtr currentForegroundWindow = GetForegroundWindow();
            GetWindowThreadProcessId(currentForegroundWindow, out uint activePid);
            uint currentPid = (uint)Process.GetCurrentProcess().Id;
            // 仅当前台窗口不属于本程序时,才拦截Win键
            if (activePid != currentPid)
            {
                return (IntPtr)1;
            }
        }
    }
    return CallNextHookEx(ptrHook, nCode, wp, lp);
}

效果验证

修改完成后重新编译运行:

  • 切到其他程序窗口按Win键,不会弹出开始菜单,全局禁用生效
  • 切回你的远程桌面窗口按Win键,按键事件会正常传递给Guacamole,可触发远端桌面的Win快捷键操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:36:03