通过 TranslateAccelerator 检测快捷方式时忽略 Shift 键的状态

Posted

技术标签:

【中文标题】通过 TranslateAccelerator 检测快捷方式时忽略 Shift 键的状态【英文标题】:Ignoring the status of Shift key when detecting shortcuts via TranslateAccelerator 【发布时间】:2019-07-04 19:10:08 【问题描述】:

我卡住了:如何防止在加速器翻译过程中考虑虚拟 Shift 键?例如,如果我的快捷键表包含 Ctrl+A 的单个条目(例如,选择当前聚焦窗口中的所有内容),那么我希望检测到相应的命令当 Ctrl+A 被按下以及如果 Ctrl+Shift+A被按下(但相反,我仍然希望 Alt 键发挥作用,所以 Ctrl+Shift+A 不应该翻译成我的命令)。

This post 没有帮助。我想我正在调用TranslateAccelerator 函数,而我仍在消息循环中(请参阅下面的代码,如果我错了,请纠正我)。

当我看到WM_KEYDOWN 消息时,我试图通过获取当前键盘状态来超越 Windows,手动将虚拟 Shift 键状态更改为“未按下”,进行加速器转换,并恢复我的手动修改。在代码中:

BOOL CHexaEditor::PreTranslateMessage(PMSG pMsg)
    // pre-processing the Message
    if (::GetFocus()==m_hWnd) // I'm not sure if this is mandatory in MFC
        if (pMsg->message==WM_KEYDOWN)
            BYTE keyboardState[256];
            ::GetKeyboardState(keyboardState);
            const BYTE shiftState0=keyboardState[VK_SHIFT];
            keyboardState[VK_SHIFT]=0; // 0 = "not pressed"
                const BOOL result=::TranslateAccelerator(m_hWnd,hDefaultAccelerators,pMsg);
            keyboardState[VK_SHIFT]=shiftState0;
            ::SetKeyboardState(keyboardState);
            return result;
        else
            return ::TranslateAccelerator(m_hWnd,hDefaultAccelerators,pMsg);
    else
        return FALSE;

到目前为止没有成功,非常感谢任何帮助。谢谢:-)

【问题讨论】:

你能把Ctrl+ACtrl+Shift+A 的条目都放在快捷键表中吗?我不会像您在帖子中那样尝试破解。 嗯,这可能是一种方式,谢谢 - 我还没有想到这个 :-) 但我宁愿想要一个“更干净的黑客”而不是这个 - 我(或其他任何人,因为它是一个开源项目)可以从 MFC 类派生,并且他们需要坚持为每个加速器提供“Shift-version”的规则。好吧,否则,他们需要遵守规则,不要在他们的加速器中使用 Shift,但这已经更容易管理了 (imo)。 调用SetKeyboardState 之后 TranslateAccelerator 不会做任何事情。请记住,keyboardState 只是一个本地副本。 我太笨了,非常感谢! 恕我直言,@PaulSanders "hack" 是最干净的 hack。只需添加一个快捷键表条目,为什么还要编写代码? 【参考方案1】:

所以正确答案是(感谢上面的ybungalobill):

BOOL CHexaEditor::PreTranslateMessage(PMSG pMsg)
    // pre-processing the Message
    if (::GetFocus()==m_hWnd)
        if (pMsg->message==WM_KEYDOWN)
            BYTE keyboardState[256];
            ::GetKeyboardState(keyboardState);
            const BYTE shiftState0=keyboardState[VK_SHIFT];
            keyboardState[VK_SHIFT]=0;
/* --> */   ::SetKeyboardState(keyboardState); // this line was missing
                const BOOL result=::TranslateAccelerator(m_hWnd,hDefaultAccelerators,pMsg);
            keyboardState[VK_SHIFT]=shiftState0;
            ::SetKeyboardState(keyboardState);
            return result;
        else
            return ::TranslateAccelerator(m_hWnd,hDefaultAccelerators,pMsg);
    else
        return FALSE;

【讨论】:

我认为您需要if (result) return TRUE;,然后在所有其他情况下返回CWnd::PreTranslateMessage(pMsg)

以上是关于通过 TranslateAccelerator 检测快捷方式时忽略 Shift 键的状态的主要内容,如果未能解决你的问题,请参考以下文章

OCR技术在机动车检测(综检安检环检三合一系统)中应用

毕业课题之------------车辆阴影特征检測的两种方法

用于检索子进程输出的python代码(linux ps命令)

图像边缘检測小结

OpenCV图像处理篇之边缘检測算子

不断发展的X光安检图像识别基于深度学习的智能识别设计与实现