在有背景图片的对话框中,static控件的透明显示是一个非常普通的问题。
常用的解决办法可以通过重载OnCtlColor函数设置背景透明,再返回一个空画刷来解决。
if(nCtlColor == CTLCOLOR_STATIC ) { pDC->SetBkMode(TRANSPARENT);//设置背景透明 pDC->SetTextColor(RGB(255,255,0));//设置字体为黄色 return (HBRUSH)::GetStockObject(NULL_BRUSH); }
但这种方法有一个弊端:不能动态更新static控件内容,否则输出的文字会重叠。
对于动态更新问题的解决办法就是将控件背后的对话框图片贴到控件上来,这样就可以实现static控件的动态更新了。
下面将详叙通过CTransparentStatic类来实现static控件动态的透明显示的解决方案,其中在CTransparentStatic类的OnPaint函数中实现了动态更新控件背景图片(即将将控件背后的对话框图片贴到控件上来)。
1、在头文件中为static控件增加一个变量(ID为IDC_STATIC_ELAPSETIME ),并使此变量类型为CTransparentStatic,而不是默认的CStatic
CTransparentStatic m_staEelapseTime;
2、在对话框的OnInitDialog函数中设置此控件的字体大小和颜色
m_staEelapseTime.SetFont(&m_font1); m_staEelapseTime.SetTextColor(RGB(255,255,0)); //黄色
3、在OnCtlColor函数中设置此控件透明和颜色,并返回一个空画刷。
if( pWnd ->GetDlgCtrlID() == IDC_STATIC_ELAPSETIME ) { pDC->SetBkMode(TRANSPARENT);//设置背景透明 pDC->SetTextColor(RGB(255,255,0));//设置字体为黄色 return (HBRUSH)::GetStockObject(NULL_BRUSH); }
注意,第三步必须有,否则动态显示staEelapseTime控件内容时,会先绘制windows默认的static控件,造成控件闪烁,自己试一下就知道了。
通过以上步骤,就可以实现static控件的动态透明显示了,并且连续采样时也不会出现闪烁。
下面是CTransparentStaticl类的源文件和头文件
//CTransparentStatic.h
#pragma once // CTransparentStatic class CTransparentStatic : public CStatic { DECLARE_DYNAMIC(CTransparentStatic) public: CDC m_dcBk; CBitmap m_bmpBk; CBitmap* m_pbmpOldBk; int m_nFontsize ; void SetTextColor(COLORREF TextColor); //void SetFont(int nSize) ; COLORREF m_TextColor; public: CTransparentStatic(); virtual ~CTransparentStatic(); protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnPaint(); DWORD SetBk(CDC* pDC); };
// CTransparentStatic.cpp
// TransparentStatic.cpp : implementation file // #include "stdafx.h" #include "TransparentStatic.h" // CTransparentStatic IMPLEMENT_DYNAMIC(CTransparentStatic, CStatic) CTransparentStatic::CTransparentStatic() { //TRACE("CTransparentStatic::CTransparentStatic()\n"); } CTransparentStatic::~CTransparentStatic() { //TRACE("CTransparentStatic::~CTransparentStatic()\n"); } BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic) ON_WM_PAINT() END_MESSAGE_MAP() // CTransparentStatic message handlers void CTransparentStatic::OnPaint() { //TRACE("CTransparentStatic::OnPaint()\n"); CPaintDC dc(this); // device context for painting // Where to draw text CRect client_rect; GetClientRect(client_rect); // Get the caption CString szText; GetWindowText(szText); // Get the font CFont *pFont, *pOldFont; pFont = GetFont(); pOldFont = dc.SelectObject(pFont); // Map "Static Styles" to "Text Styles" #define MAP_STYLE(src, dest) if(dwStyle & (src)) dwText |= (dest) #define NMAP_STYLE(src, dest) if(!(dwStyle & (src))) dwText |= (dest) DWORD dwStyle = GetStyle(), dwText = 0; MAP_STYLE( SS_RIGHT, DT_RIGHT ); MAP_STYLE( SS_CENTER, DT_CENTER ); MAP_STYLE( SS_CENTERIMAGE, DT_VCENTER | DT_SINGLELINE ); MAP_STYLE( SS_NOPREFIX, DT_NOPREFIX ); MAP_STYLE( SS_WORDELLIPSIS, DT_WORD_ELLIPSIS ); MAP_STYLE( SS_ENDELLIPSIS, DT_END_ELLIPSIS ); MAP_STYLE( SS_PATHELLIPSIS, DT_PATH_ELLIPSIS ); NMAP_STYLE( SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | SS_WORDELLIPSIS | SS_ENDELLIPSIS | SS_PATHELLIPSIS, DT_WORDBREAK ); // Set transparent background dc.SetBkMode(TRANSPARENT); //解决重影(将对话框的背景图片贴到控件上) CClientDC clDC(GetParent()); //创建其父窗口的客户区DC。由于此处控件的父窗口是对话框,因此就是获取对话框的DC。 //相当于GetDC CRect rect; CRect rect1; GetClientRect(rect);//获取本static控件的客户区大小 //this->GetClientRect(rect); //省去一个this,this就代表触发wm_paint消息的控件,以下同 GetWindowRect(rect1);//获取本static控件在窗口的位置和大小 GetParent()->ScreenToClient(rect1);//将本static控件的屏幕座标转换为客户区座标 dc.SetTextColor(m_TextColor);//设置字体颜色 if (m_dcBk.m_hDC == NULL) { m_dcBk.CreateCompatibleDC(&clDC); m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height()); m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk); m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);//将clDC的图片copy至m_dcBk //m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, 100, 100, SRCCOPY); } dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);//将m_dcBk的图片copy至当前dc //解决重影 // Draw the text dc.DrawText(szText, client_rect, dwText); // Select old font dc.SelectObject(pOldFont); } void CTransparentStatic::SetTextColor(COLORREF TextColor) { //TRACE("CTransparentStatic::SetTextColor(COLORREF TextColor)\n"); m_TextColor=TextColor; } //void CTransparentStatic::SetFont(int nSize) //{ // TRACE("CTransparentStatic::SetFont(int nSize)\n"); // m_nFontsize = nSize ; // //} DWORD CTransparentStatic::SetBk(CDC* pDC) { TRACE("CTransparentStatic::SetBk(CDC* pDC)\n"); CClientDC clDC(GetParent()); CRect rect; CRect rect1; GetClientRect(rect); GetWindowRect(rect1); GetParent()->ScreenToClient(rect1); if (m_dcBk.m_hDC == NULL) { m_dcBk.CreateCompatibleDC(&clDC); m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height()); m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk); m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY); } // if m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rect1.left, rect1.top, SRCCOPY); return 0; } // if