渲染引擎CRenderEngine:封裝GDI
//duilib-master\DuiLib\Core\UIRender.h
class DUILIB_API CRenderEngine
{
DrawLine //繪制直線
DrawRect //繪制直角邊框
DrawRoundRect //繪制圓角邊框
DrawImage //繪制圖片
DrawColor //繪制純色
DrawGradient //繪制漸變色
DrawText //繪制普通文本
DrawHtmlText //繪制HTML文本
}
//duilib-master\DuiLib\Core\UIRender.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-master\DuiLib\Core\UIControl.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-master\DuiLib\Control\UILabel.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-master\DuiLib\Control\UIButton.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