• Duilib实现GroupBox控件


    转载:http://blog.csdn.net/asd313346541/article/details/47055113

    原作者的源码上说:右边线和下边线显示不出来:

    后来经过调试研究测试猜测应该是没有给控件设置borderround属性,后来设置后出来效果:

    最后放上源码(稍微做了修改):

    .h文件

     1 #ifndef _UIGROUPBOX_H_
     2 #define _UIGROUPBOX_H_
     3 
     4 #define  GROUPBOX_TEXT_OFFSET        40        //定义GroupBox中的Text相对于左边的偏移
     5 
     6 class CGroupBoxUI :public CContainerUI
     7 {
     8 public:
     9     CGroupBoxUI();
    10 
    11     ~CGroupBoxUI();
    12 
    13     virtual LPCTSTR GetClass() const;
    14 
    15     virtual LPVOID GetInterface(LPCTSTR pstrName);
    16 
    17     virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
    18 
    19     void PaintText(HDC hDC);
    20 
    21     void PaintBorder(HDC hDC);
    22 
    23     void SetTextColor(DWORD dwTextColor);
    24 
    25     void SetFont(int iFont);
    26 
    27     void SetShowHtml(bool bShowHtml);
    28 
    29 private:
    30     DWORD    m_dwTextColor;        ///字休颜色
    31     int        m_iFont;            ///字体号,大小
    32     bool    m_bShowHtml;        ///是否显示HTML代码
    33     int        m_iTextWidth;        ///Text文字宽
    34     int        m_iTextHeigh;        ///Text文字高
    35 };
    36 
    37 #endif//_UIGROUPBOX_H_

    .cpp文件

      1 #include "stdafx.h"
      2 #include "UIGroupBox.h"
      3 
      4 CGroupBoxUI::CGroupBoxUI() :m_iFont(-1), m_bShowHtml(false)
      5 {
      6 
      7 }
      8 
      9 
     10 CGroupBoxUI::~CGroupBoxUI()
     11 {
     12 }
     13 
     14 ///    @return LPCTSTR 返回控件类名
     15 ///    @note    本函数返回控件类,格式为LPCTSTR
     16 LPCTSTR CGroupBoxUI::GetClass() const
     17 {
     18     return TEXT("GroupBoxUI");
     19 }
     20 
     21 
     22 /// @return LPVOID类型
     23 ///    @note 获取接口
     24 LPVOID CGroupBoxUI::GetInterface(LPCTSTR pstrName)
     25 {
     26     if (_tcscmp(pstrName, TEXT("GroupBox")) == 0)
     27     {
     28         return static_cast<CGroupBoxUI*>(this);
     29     }
     30     
     31     return CContainerUI::GetInterface(pstrName);
     32 }
     33 
     34 
     35 ///    设置控件属性
     36 /// @param pstrname        欲设置的属性名称,LPCTSTR类型
     37 /// @param pstrValue    欲设置的属性值,LPCTSTR类型
     38 /// @see                CControlUI::SetAttribute()
     39 /// @note                重载基类,增加部分基类没有的属性
     40 void CGroupBoxUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
     41 {
     42     if (_tcscmp(pstrName, _T("font")) == 0) SetFont(_ttoi(pstrValue));
     43     else if (_tcscmp(pstrName, _T("textcolor")) == 0) 
     44     {
     45         if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
     46         LPTSTR pstr = NULL;
     47         DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
     48         SetTextColor(clrColor);
     49     }
     50     else if (_tcscmp(pstrName, _T("showhtml")) == 0) 
     51         SetShowHtml(_tcscmp(pstrValue, _T("true")) == 0);
     52 
     53     else CControlUI::SetAttribute(pstrName, pstrValue);
     54 }
     55 
     56 /// 设置控件文字颜色
     57 /// @param    dwTextColor        欲设置的文字颜色
     58 /// @note    设置文字颜色,并立即刷新
     59 void CGroupBoxUI::SetTextColor(DWORD dwTextColor)
     60 {
     61     m_dwTextColor = dwTextColor;
     62     Invalidate();
     63 }
     64 
     65 
     66 /// 设置控件字体
     67 /// @param    iFont        欲设置的字体号
     68 /// @note    设置字体,并立即刷新
     69 void CGroupBoxUI::SetFont(int iFont)
     70 {
     71     m_iFont = iFont;
     72     Invalidate();
     73 }
     74 
     75 
     76 void CGroupBoxUI::SetShowHtml(bool bShowHtml)
     77 {
     78     if (m_bShowHtml == bShowHtml) return;
     79 
     80     m_bShowHtml = bShowHtml;
     81     Invalidate();
     82 }
     83 
     84 
     85 /// 关键部分
     86 void CGroupBoxUI::PaintText(HDC hDC)
     87 {
     88     //如果没有设置字体颜色,则用默认设置
     89     if (m_dwTextColor == 0)
     90     {
     91         m_dwTextColor = m_pManager->GetDefaultFontColor();
     92     }
     93 
     94 
     95     RECT rc;        //文字输出位置
     96     rc = GetPos();
     97 
     98     rc.left = rc.left + m_cxyBorderRound.cx + GROUPBOX_TEXT_OFFSET;    //这个地方采用了硬编码的方式,不知道怎么计算文字应该放的位置
     99         
    100     HFONT hOldFont = (HFONT)::SelectObject(hDC, m_pManager->GetFont(m_iFont));
    101     Gdiplus::Graphics graphics(hDC);
    102     Gdiplus::Font font(hDC);
    103     graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintSystemDefault);
    104     graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
    105     graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
    106     Gdiplus::RectF rectF((Gdiplus::REAL)rc.left, (Gdiplus::REAL)rc.top, (Gdiplus::REAL)(rc.right - rc.left), (Gdiplus::REAL)(rc.bottom - rc.top));
    107     Gdiplus::SolidBrush brush(Gdiplus::Color(254, GetBValue(m_dwTextColor), GetGValue(m_dwTextColor), GetRValue(m_dwTextColor)));
    108 
    109     Gdiplus::StringFormat stringFormat = Gdiplus::StringFormat::GenericTypographic();
    110     Gdiplus::RectF bounds;
    111     graphics.MeasureString(m_sText, -1, &font, rectF, &stringFormat, &bounds);
    112     
    113     // MeasureString存在计算误差,这里加一像素
    114     rc.bottom = rc.top + (long)bounds.Height + 1;        //这两句是从UIRender.cpp中DrawText()中拷出来的,不知道意义何在
    115     rc.right = rc.left + (long)bounds.Width + 1;
    116     
    117     m_iTextWidth = (int)bounds.Width;
    118     m_iTextHeigh = (int)bounds.Height;
    119     
    120     graphics.DrawString(m_sText, -1, &font, rectF, &stringFormat, &brush);
    121 
    122     ::SelectObject(hDC, hOldFont);
    123 }
    124 
    125 
    126 void CGroupBoxUI::PaintBorder(HDC hDC)
    127 {
    128     RECT rc = GetPos();        //画框框时的位置
    129 
    130     rc.top += (m_iTextHeigh * 1) / 2;        //最顶部的线移到Text的中下部
    131 
    132     int nSize = m_nBorderSize;
    133     //DWORD dwPenColor = m_dwBorderColor;
    134     Gdiplus::Graphics graphics(hDC);
    135 
    136     //消除锯齿
    137     graphics.SetSmoothingMode(SmoothingModeHighQuality);   
    138     //const Gdiplus::Pen pen(Gdiplus::Color::Red, 1.0f);
    139 
    140     DWORD dwPenColor = GetAdjustColor(m_dwBorderColor);
    141     ASSERT(::GetObjectType(hDC) == OBJ_DC || ::GetObjectType(hDC) == OBJ_MEMDC);
    142     HPEN hPen = ::CreatePen(PS_SOLID | PS_INSIDEFRAME, nSize, RGB(GetBValue(dwPenColor), GetGValue(dwPenColor), GetRValue(dwPenColor)));
    143     HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
    144     ::SelectObject(hDC, ::GetStockObject(HOLLOW_BRUSH));
    145 
    146     //定位四个圆角的位置
    147     RECT rcTopLeftCorner = { rc.left, rc.top, rc.left + 2 * m_cxyBorderRound.cx, rc.top + 2 * m_cxyBorderRound.cy };
    148     RECT rcTopRightCorner = { rc.right - 2 * m_cxyBorderRound.cx, rc.top, rc.right, rc.top + 2 * m_cxyBorderRound.cy };
    149     RECT rcBottomLeftCorner = { rc.left, rc.bottom - 2 * m_cxyBorderRound.cy, rc.left + 2 * m_cxyBorderRound.cx, rc.bottom };
    150     RECT rcBottomRightCorner = { rc.right - 2 * m_cxyBorderRound.cx, rc.bottom - 2 * m_cxyBorderRound.cy, rc.right, rc.bottom };
    151 
    152     //画四个圆角
    153     const Gdiplus::Pen pen(Gdiplus::Color(GetBValue(dwPenColor), GetGValue(dwPenColor), GetRValue(dwPenColor)), (float)m_nBorderSize);
    154     graphics.DrawArc(&pen, rcTopLeftCorner.left, rcTopLeftCorner.top, rcTopLeftCorner.right - rcTopLeftCorner.left, rcTopLeftCorner.bottom - rcTopLeftCorner.top, 180.0f, 90.0f);//左上角
    155     graphics.DrawArc(&pen, rcTopRightCorner.left, rcTopRightCorner.top, rcTopRightCorner.right - rcTopRightCorner.left, rcTopRightCorner.bottom - rcTopRightCorner.top, 270.0f,90.0f);//右上角
    156     graphics.DrawArc(&pen, rcBottomLeftCorner.left, rcBottomLeftCorner.top, rcBottomLeftCorner.right - rcBottomLeftCorner.left, rcBottomLeftCorner.bottom - rcBottomLeftCorner.top, 90.0f, 90.0f);//左下角
    157     graphics.DrawArc(&pen, rcBottomRightCorner.left, rcBottomRightCorner.top, rcBottomRightCorner.right - rcBottomRightCorner.left-1, rcBottomRightCorner.bottom - rcBottomRightCorner.top-1, 0.0f, 90.0f);//右下角
    158 
    159 
    160     //画线----GDI
    161     MoveToEx(hDC, rc.left, rc.top + m_cxyBorderRound.cy, NULL);            //左边线
    162     LineTo(hDC, rc.left, rc.bottom - m_cxyBorderRound.cy);
    163 
    164     MoveToEx(hDC, rc.left + m_cxyBorderRound.cx, rc.top, NULL);            //上第一条线
    165     LineTo(hDC, rc.left + m_cxyBorderRound.cx + GROUPBOX_TEXT_OFFSET - 5, rc.top);        //-5 是为了给Text增加左边间距
    166 
    167     MoveToEx(hDC, rc.left + m_cxyBorderRound.cx + GROUPBOX_TEXT_OFFSET + m_iTextWidth + 5, rc.top, NULL);        //上第二条线,+5是为了给Text增加右边间距
    168     LineTo(hDC, rc.right - m_cxyBorderRound.cx, rc.top);
    169 
    170     MoveToEx(hDC, rc.right, rc.top + m_cxyBorderRound.cy, NULL);        //右边线
    171     LineTo(hDC, rc.right, rc.bottom - m_cxyBorderRound.cy);
    172 
    173     MoveToEx(hDC, rc.left + m_cxyBorderRound.cx, rc.bottom, NULL);     //下边线
    174     LineTo(hDC, rc.right - m_cxyBorderRound.cx, rc.bottom);
    175 
    176 
    177     ::SelectObject(hDC, hOldPen);
    178     ::DeleteObject(hPen);    
    179 }

    xml布局:

    1 <GroupBox text="测试"  textcolor="#FF989898"  float="true" pos="125,55,0,0" width="256" height="80" bordercolor="#FF989898" bordersize="1"  borderround="4,4" font="1"/>

    在窗口中自定义控件:

    1 CControlUI* CFrameWnd::CreateControl(LPCTSTR pstrClass)
    2 {
    3     if (_tcscmp(pstrClass,_T("GroupBox")) == 0)
    4     {
    5         return new CGroupBoxUI;
    6     }
    7     return NULL;
    8 }

    源码demo:GroupBox控件

  • 相关阅读:
    Java基础——面向对象(继承应用)
    Java基础——数组例题&二维数组
    Java基础——面对对象-继承
    Java基础——this构造器转发 & 实例块、静态块
    spring mvc 映射与适配器
    Spring component-scan 标签的实现
    DUBBO 服务导出实现
    Idea
    ReentrantLock 实现
    C 语言程序设计
  • 原文地址:https://www.cnblogs.com/chechen/p/5985521.html
Copyright © 2020-2023  润新知