天天看點

MFC 可以設定背景色、字型、字型顔色、透明背景的 Static 靜态文本控件

MFC庫裡沒有符合這個條件的控件,于是我自己寫了一個,初步測試有效。

注:可以設定透明背景,但還不能做到透明度設定(如50%透明度)

        如果設定了背景色,就不保留透明背景

        預設背景色是透明的

// 設定背景色(若clr為CLR_NONE,則背景透明)  

void SetBackgroundColor(COLORREF clr){m_clrBackground = clr;}  

// 設定文字前景色  

void SetTextColor(COLORREF clr){m_clrText = clr;}  

// 設定文字字型  

void SetFont(CString strFaceName, LONG nHeight);  

如何使用:

    1.先将RichStatic.h和RichStatic.cpp添加入工程

    2.對話框添加Static控件後,增加一個控件變量,類型設定為CRichStatic(或手動添加,在對話框類DoDataExchange中添加DDX_Control)

源碼:

#pragma once  

// CRichStatic  

class CRichStatic : public CStatic  

{  

    DECLARE_DYNAMIC(CRichStatic)  

public:  

    CRichStatic();  

    virtual ~CRichStatic();  

protected:  

    afx_msg BOOL OnEraseBkgnd(CDC* pDC);  

    afx_msg LRESULT OnSetText(WPARAM,LPARAM);  

    DECLARE_MESSAGE_MAP()  

    virtual void PreSubclassWindow();  

private:  

    COLORREF m_clrText;          // 文字前景色  

    COLORREF m_clrBackground;    // 文字背景色  

    CFont *m_pTextFont;          // 文字字型  

    CBitmap m_Bmp;               // 儲存背景用的位圖對象  

    // 設定背景色(若clr為CLR_NONE,則背景透明)  

    void SetBackgroundColor(COLORREF clr){m_clrBackground = clr;}  

    // 設定文字前景色  

    void SetTextColor(COLORREF clr){m_clrText = clr;}  

    // 設定文字字型  

    void SetFont(CString strFaceName, LONG nHeight);  

    virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);  

};  

// RichStatic.cpp : 實作檔案  

//  

#include "stdafx.h"  

#include "RichStatic.h"  

IMPLEMENT_DYNAMIC(CRichStatic, CStatic)  

CRichStatic::CRichStatic():  

    m_clrText(0), m_clrBackground(CLR_NONE), m_hFont(NULL), m_selfCreated(FALSE),   

    m_xAlignment(X_LEFT), m_yAlignment(Y_TOP)  

}  

CRichStatic::~CRichStatic()  

    if (m_selfCreated && m_hFont != NULL)  

    {  

        DeleteObject(m_hFont);    // 若字型對象為對象自己建立并且不為NULL,則銷毀掉以釋放核心對象  

    }  

BEGIN_MESSAGE_MAP(CRichStatic, CStatic)  

   ON_MESSAGE(WM_SETTEXT,OnSetText)  

   ON_WM_ERASEBKGND()  

END_MESSAGE_MAP()  

// CRichStatic 消息處理程式  

void CRichStatic::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  

    if (m_clrBackground != CLR_NONE)    // 若背景色不為CLR_NONE(CLR_NONE表示無背景色),則繪制背景  

        RECT rect;  

        GetWindowRect(&rect);  

        CBrush brush;  

        brush.CreateSolidBrush(m_clrBackground);  

        ::SelectObject(lpDrawItemStruct->hDC, brush.m_hObject);    // 設定畫刷顔色  

        ::SelectObject(lpDrawItemStruct->hDC, GetStockObject(NULL_PEN));    // 設定筆為空筆(不繪制邊界)  

        Rectangle(lpDrawItemStruct->hDC, 0, 0,rect.right - rect.left, rect.bottom - rect.top);  

    CString strCaption;    // 标題文字  

    GetWindowText(strCaption);  

    if (m_hFont != NULL)  

        ::SelectObject(lpDrawItemStruct->hDC, m_hFont);  

    // 計算輸出字串的橫縱坐标   

    int x = 0, y = 0;  

    if (X_LEFT != m_xAlignment || Y_TOP != m_yAlignment)    // 不是左對齊或不是頂對齊  

        CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);  

        CRect crect;  

        GetWindowRect(&crect);  

        CSize size = pDC->GetTextExtent(strCaption);  

        if (X_RIGHT == m_xAlignment)    // 右對齊  

        {  

            x = crect.Width() - size.cx;  

        }  

        else if (X_CENTER == m_xAlignment)   // X居中對齊  

            x = (crect.Width()- size.cx) / 2;  

        if (Y_BOTTOM == m_yAlignment)   // 頂對齊  

            y = crect.Height() - size.cy;  

        else if (Y_CENTER == m_yAlignment)   // Y居中對齊  

            y = (crect.Height() - size.cy) / 2;  

    // 設定dc字串顔色  

    ::SetTextColor(lpDrawItemStruct->hDC, m_clrText);  

    TextOut(lpDrawItemStruct->hDC, x, y, strCaption, strCaption.GetLength());  

void CRichStatic::PreSubclassWindow()  

    CStatic::PreSubclassWindow();  

    ModifyStyle(0, SS_OWNERDRAW);  

void CRichStatic::SetFont(CString strFaceName, LONG nHeight)  

    CFont cfont;  

    LOGFONT lf;  

    memset(&lf, 0, sizeof lf);    // 清空LOGFONT結構體,之後對其指派  

    lf.lfHeight = nHeight;  

    _tcscpy_s(lf.lfFaceName, strFaceName.GetBuffer());    // 将字型名拷貝到LOGFONT結構體中  

    VERIFY(cfont.CreateFontIndirect(&lf));    // 建立新的字型  

    m_hFont = (HFONT)cfont.m_hObject;  

    m_selfCreated = TRUE;    // 标記字型為自己建立的  

void CRichStatic::SetFont(HFONT hFont)  

    m_hFont = hFont;  

    m_selfCreated = FALSE;   // 标記字型非自己建立  

void CRichStatic::SetFont(const CFont *pFont)  

    m_hFont = (HFONT)pFont->m_hObject;  

BOOL CRichStatic::OnEraseBkgnd(CDC* pDC)  

    // 當背景色為透明時,需要儲存與拷貝顯示主框的顯示區域  

    if (m_clrBackground == CLR_NONE)  

        if (m_Bmp.GetSafeHandle() == NULL)  

            CRect Rect;  

            GetWindowRect(&Rect);  

            CWnd *pParent = GetParent();  

            ASSERT(pParent);  

            pParent->ScreenToClient(&Rect);  // 将坐标轉換為與主對話框相對應  

            // 拷貝對應區域主框顯示的内容  

            CDC *pDC = pParent->GetDC();  

            CDC MemDC;  

            MemDC.CreateCompatibleDC(pDC);  

            m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());  

            CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);  

            MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);  

            MemDC.SelectObject(pOldBmp);  

            MemDC.DeleteDC();    // 删除記憶體DC,否則記憶體洩漏  

            pParent->ReleaseDC(pDC);  

        else // 将主框顯示的内容拷貝回去  

            GetClientRect(Rect);  

            pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);  

    return TRUE;  

LRESULT CRichStatic::OnSetText(WPARAM wParam,LPARAM lParam)  

    LRESULT Result = Default();  

    Invalidate();  

    UpdateWindow();  

    return Result;  

}  

from:http://blog.csdn.net/cashey1991/article/details/7545614

繼續閱讀