【问题标题】:MFC: Accelerators for Ctrl-Shift don't work?MFC:Ctrl-Shift 的加速器不起作用?
【发布时间】:2020-11-18 21:59:29
【问题描述】:

我配置了一些加速器,如果只使用Ctrl 键它工作正常,但如果我让它Shift+Ctrl 它不起作用(甚至不显示为 MFC 中的快捷方式Ctrl 版本的菜单)。我用大写和小写字母尝试过的条目没有区别。加速器中的条目如下所示:

"R",            ID_R1,        VIRTKEY, CONTROL, NOINVERT
"R",            ID_R2,        VIRTKEY, SHIFT, CONTROL, NOINVERT

我做错了什么?

编辑:我在上面写了“R”大写,因为两个答案都在谈论这个问题,但我最初有“R”,只是在放弃并在这里询问之前改为“r”。但是“R”对 Ctrl-Shift-R 也不起作用,而 Ctrl-R 可以正常工作吗?

编辑:使用 Spy x64 并检查主窗口,永远不会发送命令。如果我转到拆分器窗口右侧的列表视图并按此顺序按 Ctrl-Shift-R,则生成的唯一内容是:

<000041> 00000000002100D6 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000042> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000043> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000044> 00000000002100D6 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000045> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000046> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000047> 00000000002100D6 P WM_KEYUP nVirtKey:'R' cRepeat:1 ScanCode:13 fExtended:0 fAltDown:0 fRepeat:0 fUp:1
<000048> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000049> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000050> 00000000002100D6 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<000051> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000052> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000053> 00000000002100D6 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1

编辑:

更多数据,我在 thrdcore.cpp 中的第 178 行放置了一个条件断点,其中消息循环所在的位置(行为 if (pState-&gt;m_msgCur.message != WM_KICKIDLE &amp;&amp; !AfxPreTranslateMessage(&amp;(pState-&gt;m_msgCur))))。断点是:pState-&gt;m_msgCur.message==0x0100 &amp;&amp; pState-&gt;m_msgCur.wParam==0x52(R 的 WM_KEYDOWN)。当按下RCtrl-R 时断点命中,当按下Ctrl-Shift-R 时断点不会发生。在 spy trace 之上,R 从来没有 WM_KEYDOWN,只有一个 up?

编辑:

现在真的越来越奇怪了。我决定进入 VS2017 的键盘设置,看看是否有分配给 Ctrl-Shift-R 的东西,我按下它并没有任何反应,我尝试任何其他字母,如 Ctrl-Shift-T,它工作正常。可以通过我的键盘吗?还是 Win10 x64 中更深层次的东西,当按下 Ctrl-Shift 时,它正在为 R 吃掉 WM_KEYDOWN?

谢谢。

【问题讨论】:

  • 虚拟键代表物理键,而不是字符。键盘上没有“小写 r”键。键盘上的键是一个大写的 R。当你按下它时它恰好会产生一个小写的 r,但这不是虚拟键所代表的。
  • 我原本有“R”,但作为测试改为“r”。但是“R”版本也不起作用。它也不会显示在可用的 MFC 菜单中,只有 Ctrl-R 版本。 Ctrl-Shift 版本应该是“VIRTKEY”还是其他?
  • @RaymondChen 使用间谍和条件断点更新原始消息。 WM_KEYDOWN 只为 R 没收到过吗?关于寻找什么的任何提示?
  • 另一个讨论说 Ctrl+Shift+N 有效。这表明某些程序已将 Ctrl+Shift+R 注册为全局热键,它会覆盖您的加速键。
  • @RaymondChen 有没有办法(甚至没有记录)找到该键序列注册的内容?

标签: winapi acceleratorkey


【解决方案1】:

快捷键和菜单项的标题名称没有更新的原因是注册表信息没有更新。

有两种解决方案供您参考:

首先,您可以手动删除注册表中的信息。您可以进入注册表区域:

HKEY_CURRENT_USER\SOFTWARE\Local AppWizard 生成的应用程序

然后删除你当前应用名称的注册表信息,重新编译程序后就可以正常工作了。

在第二种方法中,可以通过在ExitInstance()函数中添加CleanState()函数来清除注册表信息。重启程序后,会更新当前程序的按键信息和菜单栏信息。

可以参考:

int CMFCApplication1App::ExitInstance()
{
    //TODO: handle additional resources you may have added
    AfxOleTerm(FALSE);
    this->CleanState();
    return CWinAppEx::ExitInstance();
}

这两种解决方案都对我有用。

【讨论】:

  • 是的,现在菜单项旁边显示了 Ctrl-Shift-R,但是按下这些键仍然不起作用,而 Ctrl-R 可以。它是一个拆分器窗口,左侧是 CTreeView,右侧是 CListView,顶部还有 CMFCToolBar 和 CMFCToolBar。 MessageMap 在 CMainFrame 内。在拆分器窗口下使用 Shift-Ctrl 是否有问题?我已经尝试过将活动窗格设置为一个或另一个,并且从未使用加速器获得 OnID2 调用。
  • 我在上面的原始问题中添加了间谍数据,还添加了 WM_KEYDOWN 从未收到的条件断点结果,用于 Ctrl-Shift-R 上的 R。
  • @user3161924 Ctrl-Shift-R 在我测试后对我有用,你测试过其他键是否正常工作吗?
【解决方案2】:

您应该在快捷键表中使用大写字符:

"R",            ID_R2,        VIRTKEY, SHIFT, CONTROL, NOINVERT

要在菜单上显示快捷键,你必须修改菜单项本身,比如更改

MENUITEM "&New\tCtrl+N",                ID_FILE_NEW

MENUITEM "&New\tCtrl+Shift+N",          ID_FILE_NEW

【讨论】:

  • 我刚刚修改了向导创建的应用程序,File New 命令与"N", ID_FILE_NEW, VIRTKEY, SHIFT, CONTROL, NOINVERT;它现在适用于Shift+Ctrl+N,不适用于默认的Ctrl+N。你一定是做错了什么
  • 菜单项现在已按应有的方式列出(在 MFC 中是自动的),但按下该键仍然不起作用。按下组合键时,原始问题会使用间谍数据更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 2020-03-17
  • 2011-09-22
相关资源
最近更新 更多