Accelerators and WTL Dialogs

时间:2024-3-9    作者:benojan    分类: c/c++


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.

标签: WTL Accelerators Modeless