ConstVoidPtr
ConstVoidPtr

Reputation: 53

MFC: Why is the Accelerator not working?

I am trying to use an accelerator in a class that inherits from CFrameWnd, which itself is used in a class that inherits from CWinApp. For some reason the shortcuts I defined in the accelerator just don't want to work.

There are two classes: CMyFrame (inherits from CFrameWnd) and CMyApp (inherits from CWinApp).

Relevant functions:

BOOL CMyApp::InitInstance() {
    m_hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));

    CMyFrame *Frame = new CMyFrame();
    m_pMainWnd = Frame;

    Frame->ShowWindow(SW_NORMAL);
    Frame->UpdateWindow();

    return TRUE;
}

BOOL CMyApp::ProcessMessageFilter(int code, LPMSG Msg) {
    if (m_hAccel) {
        if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccel, Msg)) {
            return TRUE;
        }
    }
    return CWinApp::ProcessMessageFilter(code, Msg);
}

BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
    ON_COMMAND(ID_FILE_NEW, &CMyFrame::OnFileNew)
    ON_COMMAND(ID_FILE_SAVE, &CMyFrame::OnFileSave)
    ON_COMMAND(ID_EDIT_CUT, &CMyFrame::OnEditCut)
    ON_COMMAND(ID_EDIT_COPY, &CMyFrame::OnEditCopy)
    ON_COMMAND(ID_EDIT_PASTE, &CMyFrame::OnEditPaste)
END_MESSAGE_MAP()

void CMyFrame::OnFileNew() {
    MessageBox(L"OnFileNew", L"Event", MB_OK);
}

void CMyFrame::OnFileSave() {
    MessageBox(L"OnFileSave", L"Event", MB_OK);
}

void CMyFrame::OnEditCut() {
    MessageBox(L"OnEditCut", L"Event", MB_OK);
}

void CMyFrame::OnEditCopy() {
    MessageBox(L"OnEditCopy", L"Event", MB_OK);
}

void CMyFrame::OnEditPaste() {
    MessageBox(L"OnEditPaste", L"Event", MB_OK);
}

I included afxwin.h and resource.h. The accelerator itself is loaded correctly (I checked the return value using another messagebox. It was always 1 and MSDN states that every value except for 0 means success). Also when I do not load the accelerator the menu items are greyed out. The items themselves are also working correctly. When I click them the corresponding messagebox pops up. The header of CMyFrame contains the DECLARE_MESSAGE_MAP().

Upvotes: 2

Views: 1348

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

CFrameWnd has its own CFrameWnd::LoadAccelTable method. Add this line:

Frame->LoadAccelTable(MAKEINTRESOURCE(IDR_ACCELERATOR1));

CWinThread::ProcessMessageFilter will process accelerator messages if MFC dialog box is active. But the way it is set up in your code, it will pass the accelerator to the main frame, not dialog box.

Upvotes: 3

Related Questions