MFC 可以设置背景色、字体、字体颜色、透明背景的 Static 静态文本控件
2015-07-07 08:56
831 查看
转自:http://blog.csdn.net/cashey1991/article/details/7545614
MFC库里没有符合这个条件的控件,于是我自己写了一个,初步测试有效。
注:可以设置透明背景,但还不能做到透明度设置(如50%透明度)
如果设置了背景色,就不保留透明背景
默认背景色是透明的
[cpp] view
plaincopy
// 设置背景色(若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)
源码:
[cpp] view
plaincopy
#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; // 保存背景用的位图对象
BOOL m_selfCreated;
public:
// 设置背景色(若clr为CLR_NONE,则背景透明)
void SetBackgroundColor(COLORREF clr){m_clrBackground = clr;}
// 设置文字前景色
void SetTextColor(COLORREF clr){m_clrText = clr;}
// 设置文字字体
void SetFont(CString strFaceName, LONG nHeight);
public:
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};
[cpp] view
plaincopy
// RichStatic.cpp : 实现文件
//
#include "stdafx.h"
#include "RichStatic.h"
// CRichStatic
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)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
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)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
m_hFont = hFont;
m_selfCreated = FALSE; // 标记字体非自己创建
}
void CRichStatic::SetFont(const CFont *pFont)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
m_hFont = (HFONT)pFont->m_hObject;
m_selfCreated = FALSE; // 标记字体非自己创建
}
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 // 将主框显示的内容拷贝回去
{
CRect Rect;
GetClientRect(Rect);
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);
pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBmp);
MemDC.DeleteDC(); // 删除内存DC,否则内存泄漏
}
}
return TRUE;
}
LRESULT CRichStatic::OnSetText(WPARAM wParam,LPARAM lParam)
{
LRESULT Result = Default();
Invalidate();
UpdateWindow();
return Result;
}
MFC库里没有符合这个条件的控件,于是我自己写了一个,初步测试有效。
注:可以设置透明背景,但还不能做到透明度设置(如50%透明度)
如果设置了背景色,就不保留透明背景
默认背景色是透明的
[cpp] view
plaincopy
// 设置背景色(若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)
源码:
[cpp] view
plaincopy
#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; // 保存背景用的位图对象
BOOL m_selfCreated;
public:
// 设置背景色(若clr为CLR_NONE,则背景透明)
void SetBackgroundColor(COLORREF clr){m_clrBackground = clr;}
// 设置文字前景色
void SetTextColor(COLORREF clr){m_clrText = clr;}
// 设置文字字体
void SetFont(CString strFaceName, LONG nHeight);
public:
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};
[cpp] view
plaincopy
// RichStatic.cpp : 实现文件
//
#include "stdafx.h"
#include "RichStatic.h"
// CRichStatic
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)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
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)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
m_hFont = hFont;
m_selfCreated = FALSE; // 标记字体非自己创建
}
void CRichStatic::SetFont(const CFont *pFont)
{
if (m_selfCreated && m_hFont != NULL)
{
DeleteObject(m_hFont); // 若字体对象为对象自己创建并且不为NULL,则销毁掉以释放内核对象
}
m_hFont = (HFONT)pFont->m_hObject;
m_selfCreated = FALSE; // 标记字体非自己创建
}
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 // 将主框显示的内容拷贝回去
{
CRect Rect;
GetClientRect(Rect);
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);
pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBmp);
MemDC.DeleteDC(); // 删除内存DC,否则内存泄漏
}
}
return TRUE;
}
LRESULT CRichStatic::OnSetText(WPARAM wParam,LPARAM lParam)
{
LRESULT Result = Default();
Invalidate();
UpdateWindow();
return Result;
}
相关文章推荐
- CSS透明度设置支持IE,Chrome,Firefox浏览器
- C scanf()
- 消费者最关心的就是你的用户体验,以及保证产品品质,保证价格和服务
- Spring基于注解@AspectJ的AOP
- 【原创】原来callback函数就是lambda
- Win10 RTM正式版首个候选版Build 10176编译完成
- 《统计学习方法》笔记(十)--SVM(2)
- 深入了解 Java HelloWorld
- [Cocos2d-x]在Cocos2d-x 3.x如何通过版本号WebSocket连接server数据的传输
- 按照我们对零售行业的理解,按照我们自己的步骤,专心致志地做电商
- 薛蛮子爆料:马云蔡文胜创业最狠的一面 孙正义是学习的“疯子”
- 27、chmod命令
- ceph存储 git查看某个文件修改历史Linux下的命令
- 黑马程序员---OC基础---有、无参方法的声明及实现
- 配置相关
- 跨浏览器用javascript获取窗口的位置和大小
- WPF图片浏览器(显示大图、小图等)
- 第8章Cocos2D-X中的瓦片地图集(总结)8.1 瓦片地图集及编辑器简介
- 什么是程序?
- WPF图片浏览器(显示大图、小图等)