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