Accelerators and WTL Dialogs
Author: Rory Buchanan Date: 2006 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 /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // ....... //Bind keys... m_haccelerator = AtlLoadAccelerators(IDR_MAINFRAME); // register object for message filtering and idle updates 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 /*hPrevInstance*/, 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.