Duilib 原始碼分析(四)控制元件繪製
阿新 • • 發佈:2021-01-30
技術標籤:Duilib
渲染引擎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