Reputation: 53
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
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