• 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方法,空闲时执行

  • 相关阅读:
    multipart/form-data同时传递文本和多文件参数controller接收
    sonar配置记录一下经常找不到
    神经网络分类知识蒸馏
    jconsole监听JVM
    Cocos2dx在安卓平台下获取到assets目录下文件的绝对路径
    打印100以内的质数及优化
    VBA调用百度翻译API
    VBA调用百度智能云的文字识别获取图片中的数字
    象棋的思考方法讨论
    やさしい日本語2019 学习方法
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2131182.html
Copyright © 2020-2023  润新知