C#如何实现全局禁用Windows键但当前WinForm窗口内可正常触发
解决方案
实现逻辑
低级键盘钩子触发时新增当前激活窗口判断:
- 若当前前台窗口属于你自己的程序,Win键不拦截,正常向下传递给WebBrowser内的Guacamole远程桌面
- 若当前前台窗口是其他程序窗口,直接拦截Win键实现全局禁用效果
代码修改步骤
- 新增必要的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);
- 修改
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
相关产品推荐
相关产品推荐

