Duilib 源码分析之 CLabelUI 篇

本帖基于的 Duilib 版本为 “Duilib 开源项目圈2群” 中下载的版本,和大家使用的可能有些出入。我曾使用过的一个版本的 Duilib 中的 CLabelUI 实现的内容较少,本帖中的 CLabelUI 功能都相当于我曾经使用的 CTextUI 了,但这个区别没有关系,大家只需要了解各个功能是如何实现的就可以了,具体使用的时候参考自己使用的 Duilib 版本,稍看下源码,就知道自己使用的控件具体支持哪些属性了

我的习惯是,接触一个新的控件时,首先去查看 SetAttribute 方法,因为在这个方法中明确写出的属性往往都是相对于父类多出来的属性,然后搜索一下各个属性使用的地方,就大概明白各个功能如何使用了。

闲话到此结束,现在开始介绍 CLabelUI ,直接看成员变量:

  • DWORD m_dwTextColor 文字的颜色,最终会传入到 GDI+ 中的 Gdiplus::SolidBrush 对象中,或者 GDI 中的 SetTextColor(_In_ HDC hdc, _In_ COLORREF color) 函数中。 可以通过 textcolor 属性控制
  • DWORD m_dwDisabledTextColor 当控件 enable=false 时的文字颜色
  • int m_iFont 字体,关于字体的内容可以参考:Duilib 源码分析之字体篇
  • UINT m_uTextStyle 绘制文字时的样式,请考考 Duilib 源码分析之 文字样式(m_uTextStyle) 篇
  • RECT m_rcTextPadding 实际绘制文字的矩形和传入的矩形的外间距
  • bool m_bShowHtml true 的情况下会根据传入的 html 文本来进行解析后绘制。但是这里的 html 文本格式和平时使用的并不一致,详细可参考 DrawHtmlText 方法中的注释部分
  • bool m_bAutoCalcWidth 是否自动计算宽度,true 的情况下计算控件宽度时会根据当前文字的宽度进行设置

CLableUI 的用法比较简单,这里大家先关注一下以下内容就可以了:

  • m_uTextStyle 默认属性为 DT_VCENTER | DT_SINGLELINE, 垂直居中和单行显示的。若有多行显示的需求或者需改变对齐方式,可以通过对应的属性来修改
  • void DoEvent(TEventUI& event) 这个控件只负责显示文字,所以在 DoEvent 中只对焦点进行了处理。不过焦点问题在基类 CControlUI 中也有处理,所以我认为直接使用基类的方法即可
  • void PaintText(HDC hDC) 核心成员方法。稍作解释:
    • 未设置文字颜色时使用默认的文字颜色
    • 设置了 m_rcTextPadding 的情况下,需要把当前控件的矩形区域减掉四周的边距后,剩下的矩形区域作为文字绘制区域
    • Enable 的情况下使用正常的文字颜色,否则使用禁用状态下的文字颜色
    • m_bShowHtml 为 true 的情况下进行 html 的解析后绘制文字
  • void SetText(LPCTSTR pstrText)

    CControlUI::SetText(pstrText);
        if(GetAutoCalcWidth()) {
            NeedParentUpdate();
        }  

    注意这个方法内的 NeedParentUpdate(), 有些版本的 Duilib 中这段代码没有这行代码,这样的话只有在第一次计算控件位置时才会动态的根据当前文字计算宽度,之后若再修改文字,m_rcItem不会更改。 调用了 NeedParentUpdate 后,会更新父控件,重新计算父控件的所有子控件的位置。


以上内容仅是我使用的 Duilib 版本中 CLabelUI 的所有内容。另外有些版本,像 https://github.com/duilib/duilib 中的 CLabelUI 支持更多的功能,这些更多的功能是使用 GDI+ 来实现的。支持颜色渐变、阴影、重影、发光效果 (我自己起的效果名字,权当代号~~)。 不过发光效果我通过代码测试未发现效果,而且发光效果的代码也没有理解,因为我也没有使用过 GDI+ 绘制过复杂的效果。

阴影效果 颜色渐变 重影效果

  • 阴影效果
    其实相当于绘制两次文字,但对于底层的所谓”阴影”文字可以设置 m_ShadowOffset 实现一些阴影文字的错位,这样的话就可以实现阴影效果。上图1中,我设置了阴影颜色为红色,且设置了 m_GradientAngle=50 改变了颜色渐变方向为右上到坐下,默认情况是垂直的,垂直的情况下若前景文字颜色不透明则不会看到阴影。

  • 颜色渐变
    上图 2 我设置了绿色到蓝色渐变,且渐变方向仍用 m_GradientAngle 控制

  • 重影效果
    如上图 3 ,除了阴影效果,前景文字效果,多了重影效果。

    LinearGradientBrush nLineGrBrushStroke(Point(GetGradientAngle(),0),Point(0,rc.bottom-rc.top+2),ARGB2Color(GetStrokeColor()),ARGB2Color(GetStrokeColor()));
    nRc.Offset(-1,0);
                nGraphics.DrawString(m_sText,m_sText.GetLength(),&nFont,nRc,&format,&nLineGrBrushStroke);
    nRc.Offset(2,0);
                nGraphics.DrawString(m_sText,m_sText.GetLength(),&nFont,nRc,&format,&nLineGrBrushStroke);
    nRc.Offset(-1,-1);
                nGraphics.DrawString(m_sText,m_sText.GetLength(),&nFont,nRc,&format,&nLineGrBrushStroke);
    nRc.Offset(0,2);
                nGraphics.DrawString(m_sText,m_sText.GetLength(),&nFont,nRc,&format,&nLineGrBrushStroke);
    nRc.Offset(0,-1);

    这段代码比较好理解,实际上就是在原始绘制文字的矩形的上下左右各差1像素的地方共绘制 4 次后,再绘制阴影和前景文字。这样背景就显得非常”厚重”

  • 发光效果
    源码中发光效果的代码因为本人还未理解,无法给出解释了,若以后有新的认识会更新此贴。 若有哪位大侠知道原理的,希望留言予以解答,不胜感激。
    源码中贴出了做法的参考原贴:http://bbs.csdn.net/topics/390346428

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
duilib是一个开源的C++图形界面库,它提供了丰富的控件和布局管理功能,以及良好的跨平台支持。下面我将对duilib源码进行简要分析。 1. 基础架构:duilib源码采用了模块化的设计,主要分为“Core”和“UI”两个部分。其中,“Core”模块是duilib的核心部分,提供了基础的窗口、消息循环等功能;而“UI”模块则提供了各种控件和布局管理等高级功能。 2. 控件类别:duilib提供了丰富的控件类别,包括基础的窗口类(如窗口、对话框)、容器类(如水平布局、垂直布局)、常用控件类(如按钮、文本框)、自定义控件类等。每个控件类都有相应的成员函数和消息处理函数,以便实现对控件的创建、设置属性和处理事件等操作。 3. 消息处理机制:duilib使用了消息映射的机制来处理控件的事件。每个控件类都有自己的消息映射表,用于将消息和相应的处理函数关联起来。当控件接收到特定的消息时,duilib会根据映射表找到对应的处理函数进行处理。 4. 布局管理:duilib提供了灵活且强大的布局管理功能,可以通过设置布局属性实现控件的自动适应和自动排列。布局管理器可以根据指定的规则对子控件进行自动布局,以适应不同的窗口尺寸。 5. 绘制引擎:duilib使用了自定义的绘制引擎来实现界面绘制。该绘制引擎可以根据控件的属性和状态来决定绘制的方式,以实现不同的视觉效果。 总结来说,duilib源码分析涉及到基础架构、控件类别、消息处理机制、布局管理和绘制引擎等方面。通过深入研究这些内容,我们可以更好地理解duilib的设计理念和工作原理,以便能够更好地使用和定制duilib提供的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值