如何使用C++在软件内部禁用特定的Windows热键?

3
我希望在软件中加入必要的代码,以禁用Windows(Xp,Vista,特别是7和后继版本)热键,以防止用户从软件中退出。
细节如下:
- 命令只能在软件运行时有效;当软件不运行时,Windows热键必须启用(因此:如果用户启动软件,则热键被禁用;如果他关闭它,则必须重新启用)。 - 我不想禁用所有Windows热键(一些关键热键,如ctrl+alt+del必须仍然可操作),因此像某种禁用所有热键的Windows配置之类的解决方案对我无用。我必须能够具体选择哪些热键我想继续工作,哪些热键我不想工作。 - “热键”昵称包括Windows按钮。 - 代码必须使用C ++或Windows函数。 - 最好不需要终止explorer.exe。

我在stackoverflow上看到了一个非常类似于我的案例的帖子(防止用户通过系统热键退出Windows应用程序),但据我所理解,所提出的解决方案都不适用于我的具体情况,并且我在网络上也没有找到任何相关信息。


对我来说不太清楚:只有当应用程序具有焦点时,它才会获取按键输入...你的意思是要规避这个限制吗? - Randy
1
这听起来正是你需要一个钩子。 - chris
1
为了使这个工作正常,您需要删除用户更改焦点的能力,这是可能的。想象一下在BestBuy的笔记本电脑上的那些愚蠢的演示应用程序。请查看此问题的答案http://msdn.microsoft.com/en-us/library/ms644990(v=vs.85).aspx - 8bitwide
@chris:是的,那是网络上最常见的解决方案之一,我目前正在研究它们。唯一的问题是,我找到的示例在解释方面不是非常清晰。更糟糕的是,它们都只涉及与一个按键相关的钩子,而不是组合键(例如alt+tab)的钩子。 - Momergil
@8bitwide:如何确切地取消更改焦点的能力?那将是太好了! - Momergil
显示剩余5条评论
2个回答

5

好的,我知道该怎么做了。这段代码能够使用低级别键盘钩子而不需要DLL创建一个系统范围的钩子。以下是代码(比解释更好)(使用Qt):

//Installing the hook
SWH_return = SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,GetModuleHandle(NULL),0);

if (SWH_return != NULL)
    qDebug() << "Hook true";
else
    qDebug() << "Hook false";

//Uninstalling the hook
bool teste = false;

teste = UnhookWindowsHookEx(SWH_return);

if (teste)
    qDebug() << "Unhook: true";
else
    qDebug() << "Unhook: false";

//The function responsible for detecting the keystrokes
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
    return CallNextHookEx(NULL, nCode, wParam, lParam);

tagKBDLLHOOKSTRUCT *str = (tagKBDLLHOOKSTRUCT *)lParam;

switch(str->flags)
{
    case (LLKHF_ALTDOWN):
        qDebug() << "ALT";
        delete str;
    return 1;
}

if (wParam == WM_KEYDOWN)
{
    switch (str->vkCode)
    {
        case VK_RWIN:
        case VK_LWIN:
        case VK_LCONTROL:
        case VK_RCONTROL:
        case VK_APPS:
        case VK_SLEEP:
        case VK_MENU:
            qDebug() << "SPECIAL PRESS";
            delete str;
        return 1;
    }
}

return CallNextHookEx(NULL, nCode, wParam, lParam);
}

这个最后的函数不需要在.h或.cpp文件中进行任何声明。它会阻止Ctrl、Windows键和Alt键的输入。其他两个函数必须分别放置在用户想要开始禁用按键的功能中以及当他想要停止时。谢谢,Momergil。

我看到你调用了“delete str;”。这样做对吗?我自己尝试后得到了访问冲突的错误。 - Bill Yan
@BillYan:显然不对。它是指向Windows结构的指针,由操作系统自己分配。特别地,它不是由new分配的(只需检查示例,找不到new tagKBDLLHOOKSTRUCT)。因此,delete是完全错误的。为什么这个答案被接受了?它是自问自答的,即Momergil先写了问题和答案,然后将他自己的答案标记为正确的。尽管存在明显的错误。 - MSalters

0

RegisterHotKey是一种全局禁用热键的方法,除非在调用RegisterHotKey函数的应用程序中。

RegisterHotKey(GetSafeHwnd(), 100, 0,VK_F5); //F5 works only in our application

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接