【问题标题】:How can I disable specific Windows hotkeys from inside a software using C++?如何使用 C++ 从软件内部禁用特定的 Windows 热键?
【发布时间】:2012-07-06 07:55:57
【问题描述】:

我想在软件中放入必要的代码,以禁用 Windows(Xp、Vista,特别是 7 和后续版本)热键,从而使用户能够摆脱软件。

详情:

  • 命令必须仅在软件运行时有效;当它没有运行时,必须启用 Windows 热键(因此:如果用户启动软件,热键将被禁用;如果他关闭它,则必须重新启用)。
  • 我不想禁用所有 Windows 热键(某些键热键,例如 ctrl+alt+del 必须仍然可以使用),因此诸如禁用所有热键的某种 Windows 配置之类的解决方案对我来说毫无用处。我必须能够明确选择哪些热键我想继续工作,哪些我不想。
  • “热键”昵称包括 Windows 按钮。
  • 代码必须使用 C++ 或 Windows 函数。
  • 最好不需要终止 explorer.exe。

我确实在 stackoverflow 中看到了一篇与我的情况非常相似的帖子 (Prevent users from quitting a windows application via system hotkeys),但据我所知,所提出的解决方案都不适用于我的具体情况,我没有找到网络上的任何东西。

【问题讨论】:

  • 我不清楚:应用程序只有在获得焦点时才会获得击键...你的意思是要颠覆它吗?
  • 这听起来就像你需要一个钩子。
  • 为了让它工作,你需要移除用户改变焦点的能力,这是可能的。在百思买的笔记本电脑上想想那些愚蠢的演示应用程序。看看这个问题的答案msdn.microsoft.com/en-us/library/ms644990(v=vs.85).aspx
  • @Randy:有一些热键可以独立于应用程序的焦点启用 - alt+tab,例如。我想禁用其中的几个。
  • @chris:是的,这是网络上最常见的解决方案之一,我目前正在研究它们。独特的问题是我找到的例子在解释时并不清晰。最糟糕的是,他们都在谈论与 1 个键相关的钩子,而不是与键组合(例如 alt+tab)。

标签: c++ windows hotkeys


【解决方案1】:

好的,我知道该怎么做。该代码能够使用低级键盘钩子在没有 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 的输入。另外两个必须分别放在用户想要开始按键禁用的功能和想要停止按键的功能中。

谢谢,

莫默吉尔。

【讨论】:

  • 我看到你叫“delete str;”。这是正确的吗?我试过了,但遇到了访问冲突?
  • @BillYan:显然不对。它是指向 Windows 结构的指针,由操作系统本身分配。特别是,它不是由new 分配的(只需查看示例,找不到new tagKBDLLHOOKSTRUCT)。所以delete 是完全错误的。为什么这个答案被接受?它是自我回答的,即 Momergil 写了问题,这个答案,然后将他的自己的答案标记为正确。确实,尽管存在明显的错误。
【解决方案2】:

RegisterHotKey 也是全局禁用所有应用程序的热键,但调用 RegisterHotKey 函数的地方除外。

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

【讨论】:

    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多