C++ MFC 键盘加速器

Posted

技术标签:

【中文标题】C++ MFC 键盘加速器【英文标题】:C++ MFC Keyboard Accelerators 【发布时间】:2014-02-10 21:52:20 【问题描述】:

我有一个CWinAppEx 派生类和一个CFrameWndEx 派生类,但我终生无法理解如何使用键盘加速器。

我有一个带加速器的加速器表:

ID:       ID_CLOSE_FOCUSED_WINDOW
Modifier: Ctrl
Key:      W
Type:     VIRTKEY

我的CFrameWndEx 派生类的消息映射中有这一行:

ON_COMMAND(ID_CLOSE_FOCUSED_WINDOW, CloseLastFocusedWindow)

我尝试在CFrameWndEx 派生类和PreTranslateMessage 调用TranslateAccelerators 中覆盖PreTranslateMessage,但我仍然没有收到与加速器表中的ID 相同的命令 - 没有点击CloseLastFocusedWindow 函数中的断点。

有人能解释一下吗?我觉得我正确地遵循了文档,但它对我不起作用。

提前致谢

【问题讨论】:

我认为加速器的资源 ID(例如:IDR_MAINFRAME)应该与用于加载帧的资源 ID 匹配 感谢 Edward,我的资源 ID 与用于加载框架的 ID 匹配。 【参考方案1】:

几个想法。您确定 CloseLastFocusedWindow 的签名正确吗?

应该相当于:

afx_msg void CloseLastFocusedWindow();

另外,DECLARE_MESSAGE_MAP() 是否出现在上述声明之前?

我认为 CFrameWndEx 默认会为您调用 TranslateAccelerator。一般来说,您只需要关注 LoadAccelerators 和 TranslateAccelerator 在不自动处理它们的地方(例如对话窗口等)。

编辑

还要注意框架构造的方式很重要。例如,如果您通过 CSingleDocTemplate 构造一个框架窗口,那么传递给 CSingleDocTemplate 构造函数的第一个参数将控制加载哪个加速器表。

例子:

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CMyDoc),
    RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    RUNTIME_CLASS(CMyView));

在上面的代码中,将加载 IDR_MAINFRAME 加速器表,并且应在此处输入任何所需的加速器。

【讨论】:

嗨,马克,感谢您的回复。 CloseLastFocusedWindow 具有确切的签名,包括 afx_msg。并且消息映射也正确形成 - 我正在使用它来捕获许多其他命令消息。我想知道它是否会为我调用 TranslateAccelerator,因为它肯定会调用 LoadAccelerators(如果我自己调用 LoadAccelerators 则断言,因为它不止一次调用该函数)。 你是如何创建框架窗口的? 我更新了我的答案以讨论框架窗口构造注意事项。让我知道这是否有帮助。 好点,但不幸的是,IDR_MAINFRAME 是资源 ID,我有 LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);加载 CFrameWndEx 类。【参考方案2】:

我现在遇到了类似的问题:除了默认视图(在 CSingleDocTemplate 中指定的那个)之外,我还以非标准方式创建了另一个视图。在处理了关闭非标准视图的 Ctrl+W 组合后,主菜单停止工作。后来发现我忘记设置一个新的活动视图。这样做的副作用是,文档没有收到任何命令,例如从提到的主菜单中。

所以我的建议是:当您关闭(非标准创建的)视图时,不要忘记致电 CFrameWnd::SetActiveView

【讨论】:

以上是关于C++ MFC 键盘加速器的主要内容,如果未能解决你的问题,请参考以下文章

带有 Visual Studio 2010 的 MFC-SDI 应用程序:新的键盘快捷键不起作用

如何将加速键赋予键盘退格键

MFC 加速器资源 ID 冲突?

哪个更适合 MFC 应用程序热键或加速器?

MFC CEdit 控件在添加到加速器后不处理 Key Pressed

MFC:你能在 CDateTimeCtrl 中改变旋转的加速度吗?