C++实现程序处于焦点时禁用Windows键功能
仅在程序焦点状态下禁用Windows键(基于低级键盘钩子扩展)
核心思路
低级键盘钩子本身是全局生效的,但可以在钩子回调里增加窗口焦点判断逻辑:只有当你的程序窗口处于前台激活状态时,才拦截Windows键的按键消息;否则直接传递消息给下一个钩子,不做任何拦截处理。
实现步骤
1. 保存程序主窗口句柄
在程序初始化阶段,获取并保存你的主窗口句柄:
- 若为Win32 GUI程序,可直接使用
CreateWindow返回的句柄,或在WM_CREATE消息中赋值 - 若为控制台程序,调用
GetConsoleWindow()获取控制台窗口句柄
2. 在钩子回调中添加焦点判断逻辑
在LowLevelKeyboardProc回调函数里,先通过GetForegroundWindow()获取当前前台激活的窗口句柄,再和你保存的程序窗口句柄做对比:
- 若两者不匹配:直接调用
CallNextHookEx并返回结果,不拦截按键 - 若两者匹配:判断当前按键是否为左右Windows键(虚拟键码
VK_LWIN或VK_RWIN),若是则返回1拦截消息,否则继续传递
3. 关键代码示例(C++)
#include <Windows.h> // 全局变量:存储程序主窗口句柄 HWND g_hMainWindow = nullptr; // 低级键盘钩子回调 LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= 0) { KBDLLHOOKSTRUCT* pKeyData = (KBDLLHOOKSTRUCT*)lParam; // 获取当前前台激活窗口 HWND hForegroundWnd = GetForegroundWindow(); // 仅当本程序窗口处于焦点时,才处理Windows键拦截 if (hForegroundWnd == g_hMainWindow) { // 拦截左右Windows键 if (pKeyData->vkCode == VK_LWIN || pKeyData->vkCode == VK_RWIN) { return 1; // 返回1表示已处理该消息,阻止系统响应 } } } // 非本程序焦点或非Windows键,传递消息给下一个钩子 return CallNextHookEx(nullptr, nCode, wParam, lParam); } // 设置钩子的示例代码 void SetupKeyboardHook() { HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(nullptr), 0); // 消息循环(GUI程序若已有消息循环可省略此部分) MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } UnhookWindowsHookEx(hHook); }
注意事项
- 确保
g_hMainWindow正确初始化:避免因句柄为空导致判断失效 - 多窗口程序优化:可通过
GetWindowThreadProcessId(hForegroundWnd, nullptr)获取前台窗口线程ID,再和当前程序线程ID(GetCurrentThreadId())对比,提升判断准确性 - 资源释放:程序退出前务必调用
UnhookWindowsHookEx释放钩子资源
内容的提问来源于stack exchange,提问作者Joseph Katrinka
相关产品推荐
相关产品推荐

