3
votes

What step am I missing?

I have an accelerator table:

Accelerator Table

I have added a member variable to my app class:

HACCEL m_hAccel;

I have added the following override:

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);
}

I am only using the popup message box for debugging and it confirms that the key press is being detected.

My menu resource is setup correctly:

Menu

So my menu is operation with menu handlers. And I have set up the program to load the accelerator table. If I press, for example Ctrl+Shift+X whilst it is detected by the accelerator table why doesn't my popup dialog actually process it?

I should point out that my main app dialog displays one of two editors. So when a editor is displayed I load the accelerator table for that editor.

What step am I missing? Why is the dialog not processing the accelerator?

Update

I found this answer How to make child control handle accelerator command of parent CView.

I found that if I add a HACCEL directly to my popup dialog and then just use PreTranslateMessage:

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

It works.

1

1 Answers

5
votes

For keyboard accelerators in dialogs I do this:

In 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);
}

In OnDestroy

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

Message map:

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

Command handlers

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

void CMyDlg::OnDoSomething() 
{
  ...
}

Accelerator table in .rc file

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

That's all.