zoukankan      html  css  js  c++  java
  • Duilib 源码分析(四)控件绘制

    渲染引擎CRenderEngine:封装GDI

    //duilib-masterDuiLibCoreUIRender.h
    class DUILIB_API CRenderEngine
    {
        DrawLine      //绘制直线
        DrawRect      //绘制直角边框
        DrawRoundRect //绘制圆角边框
        DrawImage     //绘制图片
        DrawColor     //绘制纯色
        DrawGradient  //绘制渐变色
        DrawText      //绘制普通文本
        DrawHtmlText  //绘制HTML文本
    }
    
    //duilib-masterDuiLibCoreUIRender.cpp
    void CRenderEngine::DrawLine( HDC hDC, const RECT& rc, int nSize, DWORD dwPenColor, int nStyle)
    {
        ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);
        // 使用操作系统提供的GDI接口进行绘制
        LOGPEN lg;
        lg.lopnColor = RGB(GetBValue(dwPenColor), GetGValue(dwPenColor), GetRValue(dwPenColor));
        lg.lopnStyle = nStyle;
        lg.lopnWidth.x = nSize;
        HPEN hPen = CreatePenIndirect(&lg);
        HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
        POINT ptTemp = { 0 };
        ::MoveToEx(hDC, rc.left, rc.top, &ptTemp);
        ::LineTo(hDC, rc.right, rc.bottom);
        ::SelectObject(hDC, hOldPen);
        ::DeleteObject(hPen);
    }
    

    绘制刷新流程

    // 设置控件无效
    void CControlUI::Invalidate()
    {
        m_pManager->Invalidate(invalidateRc);
    }
    
    //设置一个无效区域,并且发送WM_PAINT消息
    void CPaintManagerUI::Invalidate(RECT& rcItem)
    {
      ::InvalidateRect(m_hWndPaint, &rcItem, FALSE);
    }
    
    //处理WM_PAINT消息
    bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes)
    {
        case WM_PAINT:
            int iSaveDC = ::SaveDC(m_hDcPaint);
            m_pRoot->Paint(m_hDcPaint, rcPaint, NULL);
            ::RestoreDC(m_hDcPaint, iSaveDC);
    }
    
    //进行绘制
    bool CControlUI::Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
    {
        OnPaint(this)
        DoPaint(hDC, rcPaint, pStopControl)
    }
    
    //真正进行绘制
    bool CControlUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
    {
        // 绘制循序:背景颜色->背景图->状态图->文本->边框
        PaintBkColor(hDC);
        PaintBkImage(hDC);
        PaintStatusImage(hDC);
        PaintText(hDC);
        PaintBorder(hDC);
    }
    
    //背景颜色
    void CControlUI::PaintBkColor(HDC hDC)
    {
        // 渐变色
        CRenderEngine::DrawGradient
        // 纯色
        CRenderEngine::DrawColor
    }
    
    //背景图
    void CControlUI::PaintBkImage(HDC hDC)
    {
        CRenderEngine::DrawImage
    }
    //状态图
    void CControlUI::PaintStatusImage(HDC hDC)
    {
        CRenderEngine::DrawImage
    }
    
    //文本
    void CControlUI::PaintText(HDC hDC)
    {
        CRenderEngine::DrawText
    }
    
    //边框
    void CControlUI::PaintBorder(HDC hDC)
    {
        //画圆角边框(边框圆角属性大于0)
        if( m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0 )
            CRenderEngine::DrawRoundRect
      
        //画直角边框(四条边框的宽度一样)
        if (m_rcBorderSize.right == m_rcBorderSize.left && m_rcBorderSize.top == m_rcBorderSize.left && m_rcBorderSize.bottom == m_rcBorderSize.left)
            CRenderEngine::DrawRect
      
        //画四条直线(四条边框的宽度不同)
        if(m_rcBorderSize.left > 0)  CRenderEngine::DrawLine
        if(m_rcBorderSize.top > 0)   CRenderEngine::DrawLine
        if(m_rcBorderSize.right > 0) CRenderEngine::DrawLine
        if(m_rcBorderSize.bottom > 0)CRenderEngine::DrawLine
    }
    

    控件基类UIControl

    //duilib-masterDuiLibCoreUIControl.h
    class DUILIB_API CControlUI
    {
        //初始化
        virtual void Init();
        virtual void DoInit();
    
        //事件
        virtual void Event(TEventUI& event);
        virtual void DoEvent(TEventUI& event);
      
        //绘制
        virtual bool Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl=NULL);
        virtual bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
    
        //名字
        virtual CDuiString GetName() const;
        virtual void SetName(LPCTSTR pstrName);
    
        //文本
        virtual CDuiString GetText() const;
        virtual void SetText(LPCTSTR pstrText);
      
        //图像
        DWORD GetBkColor() const;
        void SetBkColor(DWORD dwBackColor);
        LPCTSTR GetBkImage();
        void SetBkImage(LPCTSTR pStrImage);
        bool IsColorHSL() const;
        void SetColorHSL(bool bColorHSL);
        SIZE GetBorderRound() const;
        void SetBorderRound(SIZE cxyRound);
    
        //边框
        DWORD GetBorderColor() const;
        void SetBorderColor(DWORD dwBorderColor);
        RECT GetBorderSize() const;
        void SetBorderSize(RECT rc);
        int GetBorderStyle() const;
        void SetBorderStyle(int nStyle);
      
        //位置
        virtual const RECT& GetPos() const;
        virtual void SetPos(RECT rc, bool bNeedInvalidate = true);
      
        //提示
        virtual CDuiString GetToolTip() const;
        virtual void SetToolTip(LPCTSTR pstrText);
    
        //快捷键
        virtual TCHAR GetShortcut() const;
        virtual void SetShortcut(TCHAR ch);
    
        //菜单
        virtual bool IsContextMenuUsed() const;
        virtual void SetContextMenuUsed(bool bMenuUsed);
    }
    

    标签控件CLabelUI

    // 继承CControlUI
    // duilib-masterDuiLibControlUILabel.h
    class DUILIB_API CLabelUI : public CControlUI
    {
        //设置属性
        void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
      
        //文本属性
        void SetTextStyle(UINT uStyle);
        UINT GetTextStyle() const;
        bool IsMultiLine();
        void SetMultiLine(bool bMultiLine = true);
        void SetTextColor(DWORD dwTextColor);
        DWORD GetTextColor() const;
        void SetFont(int index);
        int GetFont() const;
      
        //文本绘制
        void PaintText(HDC hDC);
    }
    

    按钮控件CButtonUI

    // 继承CLabelUI
    // duilib-masterDuiLibControlUIButton.h
    class DUILIB_API CButtonUI : public CLabelUI
    {
        //按钮激活
        bool Activate();
    
        //事件处理
        void DoEvent(TEventUI& event);
      
        //状态图片
        LPCTSTR GetXXXImage();
        void SetXXXImage(LPCTSTR pStrImage);
      
        //绘制文本
        void PaintText(HDC hDC);
    
        //绘制状态图片
        void PaintStatusImage(HDC hDC);
    }
    

      
    小结
      控件绘制,最底层还是操作系统提供的GDI接口。渲染引擎CRenderEngine对GDI进一步的封装,方便调用。而控件则根据自身的类型使用CRenderEngine进行绘制。

      
    Duilib技术交流群:799142530
    源码地址:https://github.com/KongKong20/DuilibTutor

  • 相关阅读:
    [IOS]《A Swift Tour》翻译(一)
    Android Property Animation动画
    [Android]AndroidBucket增加碎片SubLayout功能及AISubLayout的注解支持
    使用spin.js优化等待ajax返回时的页面效果
    用adb命令组装PowerShell实用小工具——Android测试小助手
    测试团队专业化建设规范建议与素质养成指南
    用Python脚本在豆瓣音乐人小站上下载未开放下载的歌曲
    Java调用Python脚本工具类
    Python爬网——获取安卓手机统计数据
    JIRA REST java client API实际应用
  • 原文地址:https://www.cnblogs.com/wwgk/p/14344698.html
Copyright © 2011-2022 走看看