Introduction
I searched and searched the CodeProject but never found an example on using accelerators and WTL dialogs. I have used accelerators in MFC dialogs extensively, but couldn't figure out how to add this functionality to WTL dialogs. Like a lot of things, it is very easy to do once you have figured it out. Well, here goes....
Using the code
Declare a handle to the accelerator, and add the CMessageFilter
if it has not been done already.
#pragma once
class CMainDlg : public CDialogImpl<CMainDlg>,
public CUpdateUI<CMainDlg>,
public CMessageFilter,
public CIdleHandler
{
private:
HACCEL m_haccelerator;
};
Then in your OnInitDialog
, assign the m_haccelerator
variable to the accelerator resource, which in this example is IDR_MAINFRAME
.
LRESULT CMainDlg::OnInitDialog(UINT , WPARAM ,
LPARAM , BOOL& )
{
m_haccelerator = AtlLoadAccelerators(IDR_MAINFRAME);
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
return TRUE;
}
Then we need to overload the PreTranslateMessage
function...
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)
{
if(m_haccelerator != NULL)
{
if(::TranslateAccelerator(m_hWnd, m_haccelerator, pMsg))
return TRUE;
}
return CWindow::IsDialogMessage(pMsg);
}
Also, in you constructor, initialize the handle to the accelerator.
CMainDlg::CMainDlg()
{
m_haccelerator = NULL;
}
If the dialog wasn't made to be modeless, it needs to be for the PreTranslateMessage
to work. This is easily done by...
int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE , LPTSTR lpstrCmdLine, int nCmdShow)
{
_Module.Init(NULL, hInstance);
CMessageLoop myMessageLoop;
_Module.AddMessageLoop(&myMessageLoop);
CMainDlg dlgMain;
dlgMain.Create(NULL);
dlgMain.ShowWindow(nCmdShow);
int retValue = myMessageLoop.Run();
_Module.RemoveMessageLoop();
_Module.Term();
return retValue;
}
And make sure you include atlmisc.h.