最近在項目中將CStatic控件設置為背景透明且在一個定時器函數改變其文本,結果CStatic的文字重疊了。解決該問題的方案是:從CStatic類派生自己的靜態文本控件。
其實設置背景透明,也就是在CStatic重畫時,返回一個空刷子而已,所以改變文本並沒有改變上次殘留的背景,從而導致重疊現象。
為了解決這個問題,我們可以讓父窗口重繪該區域,以下是我的解決方法:
1: 從CStatic繼承一個類CStaticEx
2: 增加WM_CTLCOLOR消息反射(把很多事情留給父窗口窗口處理不是一件很好的事,就讓CStaticEx自己處理,這樣還可以不影響到其他的Static)
3:處理WM_SETTEXT,當文本改變時,重繪父窗口的該控件所在的區域。
代碼如下:
// StaticEx.h
class CStaticEx : public CStatic { DECLARE_DYNAMIC(CStaticEx) public: CStaticEx(); virtual ~CStaticEx(); protected: DECLARE_MESSAGE_MAP() afx_msg HBRUSH CtlColor(CDC* pDC, UINT ); virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); }; //
#include "StaticEx.h"
// StaticEx.cpp
IMPLEMENT_DYNAMIC(CStaticEx, CStatic) CStaticEx::CStaticEx() { } CStaticEx::~CStaticEx() { } BEGIN_MESSAGE_MAP(CStaticEx, CStatic) ON_WM_CTLCOLOR_REFLECT() END_MESSAGE_MAP() // CStaticEx 消息處理程序 HBRUSH CStaticEx::CtlColor(CDC* pDC, UINT ) { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255, 0, 0)); return (HBRUSH)GetStockObject(HOLLOW_BRUSH); } LRESULT CStaticEx::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if(WM_SETTEXT == message) { CRect rect; GetWindowRect(&rect); CWnd *pParentWnd = GetParent(); if(pParentWnd) { pParentWnd->ScreenToClient(&rect); pParentWnd->InvalidateRect(&rect); } } return CStatic::DefWindowProc(message, wParam, lParam); }