【问题标题】:Handling accelerator in a dialog在对话框中处理加速器
【发布时间】:2018-01-15 08:28:06
【问题描述】:

我错过了什么步骤?

我有一个加速器表:

我在我的应用类中添加了一个成员变量:

HACCEL m_hAccel;

我添加了以下覆盖:

BOOL CMeetingScheduleAssistantApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
    if (m_hAccel)
    {
        if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccel, lpMsg))
        {
            AfxMessageBox(_T("Found"));
            return(TRUE);
        }
    }

    return CWinAppEx::ProcessMessageFilter(code, lpMsg);
}

我只是使用弹出消息框进行调试,它确认正在检测到按键。

我的菜单资源设置正确:

所以我的菜单是使用菜单处理程序操作的。我已经设置了加载加速器表的程序。如果我按下,例如 Ctrl+Shift+X 而它被加速器表检测到为什么我的弹出对话框实际上不处理它?

我应该指出,我的主应用程序对话框显示两个编辑器之一。因此,当显示编辑器时,我会加载该编辑器的加速器表。

我错过了什么步骤?为什么对话框不处理加速器?

更新

我找到了这个答案How to make child control handle accelerator command of parent CView

我发现如果我将HACCEL 直接添加到我的弹出对话框中,然后只需使用PreTranslateMessage

if (m_hAccelTable)
{
    if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
        return TRUE;
}

有效。

【问题讨论】:

    标签: mfc acceleratorkey


    【解决方案1】:

    对于对话框中的键盘加速器,我这样做:

    在 OnInitDialog 中

    BOOL CMyDlg::OnInitDialog()
    {
       ...
       m_hAccel = LoadAccelerators ( AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_DLGACCEL));
       ...
    }
    

    PreTranslateMessage

    BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
    {
      if (m_hAccel)
      {
        if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
          return(TRUE);
        else
          return CDialog::PreTranslateMessage(pMsg);
      }
      else
        return CDialog::PreTranslateMessage(pMsg);
    }
    

    在 OnDestroy 中

    void CMyDlg::OnDestroy()
    {
      ...
      VERIFY(DestroyAcceleratorTable(m_hAccel)) ;
      CDialog::OnDestroy();
    }
    

    消息图:

    BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
      ...
      ON_COMMAND(IDC_SOMECOMMANDID, OnDoSomething)
      ON_UPDATE_COMMAND_UI(IDC_SOMECOMMANDID, OnUpdateDoSomething)
      ...
    END_MESSAGE_MAP()
    

    命令处理程序

    void CMyDlg::OnUpdateDoSomething(CCmdUI* pCmdUI) 
    {
      ...
      pCmdUI->Enable(...) ;
    }
    
    void CMyDlg::OnDoSomething() 
    {
      ...
    }
    

    .rc 文件中的加速器表

    IDR_DLGACCEL ACCELERATORS
    BEGIN
        "A",            IDC_SOMECOMMANDID,         VIRTKEY, CONTROL, NOINVERT  // Ctrl+A
        ...
    END
    

    就是这样。

    【讨论】:

    • 谢谢。有趣的是您也有更新处理程序。我一直不得不通过手动方法来完成菜单状态,因为CDialog 项目不支持开箱即用的更新机制。但那是另一个话题。感谢您的明确答复。最有用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    相关资源
    最近更新 更多