通过 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+A
和Ctrl+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 键的状态的主要内容,如果未能解决你的问题,请参考以下文章
毕业课题之------------车辆阴影特征检測的两种方法