zoukankan      html  css  js  c++  java
  • Duilib学习笔记《05》— 消息响应处理

    Duilib学习笔记《04》中已经知道了如何将窗体显示出来,而如何处理窗体上的事件、消息呢?


    一. 系统消息

    窗体显示的时候我们就已经说了,窗体是继承CWindowWnd类的,对于窗体的部分消息的处理,需要重载该类的LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 函数。在显示窗体部分我们创建窗体WM_CREATE消息以及屏蔽标题栏WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT等消息 都是在HandleMessage中进行处理:

    LRESULT CMainWndDlg::HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
        LRESULT lRes = 0;
        BOOL bHandled = TRUE;
    
        switch( uMsg ) 
        {
        case WM_CREATE:        lRes = OnCreate(uMsg, wParam, lParam, bHandled);    break;
        case WM_NCACTIVATE:    lRes = OnNcActivate(uMsg, wParam, lParam, bHandled);    break;
        case WM_NCCALCSIZE:       lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);    break;
        case WM_NCPAINT:       lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break;
        case WM_NCHITTEST:       lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled); break;
        case WM_CLOSE:           lRes = OnClose(uMsg, wParam, lParam, bHandled); break;
        case WM_DESTROY:       lRes = OnDestroy(uMsg, wParam, lParam, bHandled); break;
        case WM_SIZE:          lRes = OnSize(uMsg, wParam, lParam, bHandled); break;
        case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled); break;
        case WM_SYSCOMMAND:    lRes = OnSysCommand(uMsg, wParam, lParam, bHandled); break;
        case WM_KEYDOWN:       PostQuitMessage(0); break;
        default:
            bHandled = FALSE;
        }
    
        if( bHandled ) return lRes;
        if( m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
    
        return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
    }

    如同代码中所示,如果消息不需要框架再处理了则直接返回。如果还需要框架处理该消息,则交由父类的HandleMessge中去处理。

     

    二. 事件消息

    对于系统消息我们直接重载了HandleMessage来处理,而对于鼠标点击一类的消息呢?为此,我们的窗体除了要继承CWindowWnd外,还需要继承INotifyUI,同样的重载INotifyUI类中的void Notify(TNotifyUI& msg); 函数,由该函数来处理控件操作产生的消息。但仅仅只是继承重载了还不够,我们怎么才能确保事件消息能正常传递呢?因此,在窗体创建OnCreate的时候,我们还需要添加如下m_PaintManager.AddNotifier(this); 这样,控件消息就可以传达大duilib的消息循环中,我们也就可以通过Notify函数对消息进行处理:

    void CMainWndDlg::Notify( TNotifyUI& msg )
    {
        if( msg.sType == _T("windowinit") ) {
            OnWindowInit();
        }
        else if( msg.sType == _T("click") ) {
            if( msg.pSender == m_pCloseBtn ) {
                PostQuitMessage(0);
                return; 
            }
            else if( msg.pSender == m_pMinBtn ) { 
                SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); return; }
            else if( msg.pSender == m_pMaxBtn ) { 
                SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); return; }
            else if( msg.pSender == m_pRestoreBtn ) { 
                SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); return; }
    
            // 按钮消息
            OnLBtnClick(msg.pSender);
        }
        else if(msg.sType==_T("selectchanged"))
        {
            CDuiString name = msg.pSender->GetName();
            CTabLayoutUI* pTabSwitch = static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("tab_switch")));
            CTabLayoutUI* pDemoListSwitch = static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("demo_list_tab_switch")));
    
            if(name.CompareNoCase(_T("demo_tab")) == 0)
                pTabSwitch->SelectItem(0);
            else if(name.CompareNoCase(_T("web_tab")) == 0) 
                pTabSwitch->SelectItem(1);
    
            if(name.CompareNoCase(_T("demo_list_basic_ctrl")) == 0)
                pDemoListSwitch->SelectItem(0);
            else if(name.CompareNoCase(_T("demo_list_rich_ctrl")) == 0)
                pDemoListSwitch->SelectItem(1);
        }
    }

    在Notify函数中针对消息的不同进行不同的操作处理,比如click、selectchanged等等。对于这类duilib针对相关操作自定义的消息类型可以在duilib工程中的UIDefine.h文件中查看:

    //定义所有消息类型
    //////////////////////////////////////////////////////////////////////////
    
    #define DUI_MSGTYPE_MENU                   (_T("menu"))
    #define DUI_MSGTYPE_LINK                   (_T("link"))
    
    #define DUI_MSGTYPE_TIMER                  (_T("timer"))
    #define DUI_MSGTYPE_CLICK                  (_T("click"))
    
    #define DUI_MSGTYPE_RETURN                 (_T("return"))
    #define DUI_MSGTYPE_SCROLL                 (_T("scroll"))
    
    #define DUI_MSGTYPE_DROPDOWN               (_T("dropdown"))
    #define DUI_MSGTYPE_SETFOCUS               (_T("setfocus"))
    
    #define DUI_MSGTYPE_KILLFOCUS              (_T("killfocus"))
    #define DUI_MSGTYPE_ITEMCLICK                   (_T("itemclick"))
    #define DUI_MSGTYPE_TABSELECT              (_T("tabselect"))
    
    #define DUI_MSGTYPE_ITEMSELECT                   (_T("itemselect"))
    #define DUI_MSGTYPE_ITEMEXPAND             (_T("itemexpand"))
    #define DUI_MSGTYPE_WINDOWINIT             (_T("windowinit"))
    #define DUI_MSGTYPE_BUTTONDOWN                   (_T("buttondown"))
    #define DUI_MSGTYPE_MOUSEENTER               (_T("mouseenter"))
    #define DUI_MSGTYPE_MOUSELEAVE               (_T("mouseleave"))
    
    #define DUI_MSGTYPE_TEXTCHANGED            (_T("textchanged"))
    #define DUI_MSGTYPE_HEADERCLICK            (_T("headerclick"))
    #define DUI_MSGTYPE_ITEMDBCLICK            (_T("itemdbclick"))
    #define DUI_MSGTYPE_SHOWACTIVEX            (_T("showactivex"))
    
    #define DUI_MSGTYPE_ITEMCOLLAPSE           (_T("itemcollapse"))
    #define DUI_MSGTYPE_ITEMACTIVATE           (_T("itemactivate"))
    #define DUI_MSGTYPE_VALUECHANGED           (_T("valuechanged"))
    
    #define DUI_MSGTYPE_SELECTCHANGED            (_T("selectchanged"))
    
    //////////////////////////////////////////////////////////////////////////

    三. 消息过滤

    在实际中,我们有时候可能需要根据需要对部分消息进行分类处理。比如键盘按键消息等等。对于这类情况,我们的窗体需要继承IMessageFilterUI类,重载LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)函数,同时在窗体OnCreate创建的时候添加m_pm_.AddPreMessageFilter(this)消息通知即可。

  • 相关阅读:
    CentOS配置sshd
    求逆元 HDU 2516
    求逆元
    二分图的最大匹配
    博弈1
    几何多边形面积交模板
    LAMP服务器的搭建
    扩展欧几里得
    cf780c
    利用栈的逆波兰表达式
  • 原文地址:https://www.cnblogs.com/MrYuan/p/4972009.html
Copyright © 2011-2022 走看看