WTL学习笔记(1)基础

WTL基于ATL,并做了简化和封装

不同点

1.DECLARE_FRAME_WND_CLASS

原ATL:DECLARE_WND_CLASS封装了一个ATL::CWndClassInfo结构

DECLARE_FRAME_WND_CLASS封装了一个WTL::CFrameWndClassInfo,多了一个资源字段,可以加载菜单

2.BEGIN_MSG_MAP_EX

添加IsMsgHandled和SetMsgHandled方法.

3.MSG_WM_CREATE

MSG_WM_CREATE与BEGIN_MSG_MAP_EX连用,其内部会调用SetMsgHandled和IsMsgHandled.

#define MSG_WM_CREATE(func) \
    if (uMsg == WM_CREATE) \
    { \
        SetMsgHandled(TRUE); \
        lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \
        if(IsMsgHandled()) \
            return TRUE; \
    }

默认情况下会直接返回,这样就会阻止基类执行此消息,在必要时调用SetMsgHandled方法传入false参数,这样基类也可以处理此消息.当然前提是不要忘了消息链CHAIN_MSG_MAP

LRESULT OnCreate ( LPCREATESTRUCT lpcs )
{
    SetTimer ( 1, 1000 );
    SetMsgHandled(false);
    return 0;
}

可以注意到OnCreate函数的参数只有一个,进行了简化.

也可以用回原ATL提供的宏,注意BEGIN_MSG_MAP和MESSAGE_HANDLER也是连用的

BEGIN_MSG_MAP(CMainFrame)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()

4.COMMAND_ID_HANDLER_EX

#define COMMAND_HANDLER_EX(id, code, func) \
    if (uMsg == WM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \
    { \
        SetMsgHandled(TRUE); \
        func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \
        lResult = 0; \
        if(IsMsgHandled()) \
            return TRUE; \
    }

其内部也会调用SetMsgHandled和IsMsgHandled方法

5.CMessageLoop

CMessageLoop的Run方法封装了消息循环

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);

    CMainFrame wndMain;

    if(wndMain.CreateEx() == NULL)
    {
        ATLTRACE(_T("Main window creation failed!\n"));
        return 0;
    }

    wndMain.ShowWindow(nCmdShow);

    int nRet = theLoop.Run();

    _Module.RemoveMessageLoop();
    return nRet;
}
int Run()
{
    BOOL bDoIdle = TRUE;
    int nIdleCount = 0;
    BOOL bRet;

    for(;;)
    {
        …
        if(!PreTranslateMessage(&m_msg))
        {
            ::TranslateMessage(&m_msg);
            ::DispatchMessage(&m_msg);
        }
       …
     }

    return (int)m_msg.wParam;
}

6.CMessageFilter

重写PreTranslateMessage方法返回TRUE时用于过滤消息,

7.CIdleHandler

重写OnIdle方法,空闲时执行

原文地址:https://www.cnblogs.com/Clingingboy/p/2131182.html