1. 程式人生 > >CStatic控制元件背景透明且改變其文字時,文字重疊解決方法

CStatic控制元件背景透明且改變其文字時,文字重疊解決方法

問題 提出:

最近在專案中將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);
}


注意:上述方法在在Winxp、win7、Wince下測試通過,但在Wince平臺下不起作用, 在Wince平臺下,在文字動態改變時除了上面自定義CStatic程式碼外,還必須在文字動態改變處加入如下程式碼:

 m_static.ShowWindow(SW_HIDE);  // 先隱藏下
 m_static.SetWindowText(strNum); 
 m_static.ShowWindow(SW_SHOW);  // 再顯示出來。通過隱藏顯示從而重新整理父視窗

上面只通過隱藏顯示的方法而不需要自定義CStatic在Winxp、win7也可以,請看下文:

下面再介紹一種方法,在Winxp、win7下測試通過:

設定了透明後,應該是不重新整理父視窗的該區域,所以直接就畫出來而沒有清除之前的.解決方法很簡單

將控制元件先影藏再顯示,之前使用控制元件的Invalidate函式,不行,因為那只是重畫了控制元件的區域,而不是重畫控制元件父窗體的該區域

而直接重畫父窗體對效率肯定有影響,所以最簡單的方法就是控制元件ShowWindow(SW_HIDE);然後ShowWindow(SW_SHOW);,這樣父窗體就會重畫該區域,就會清除之前的影象了,然後想到了這樣

 m_static.ShowWindow(SW_HIDE);
 m_static.SetWindowText(strNum); 
 m_static.ShowWindow(SW_SHOW);

先影藏,然後改變內容,再顯示,好了,完美解決了

轉自:http://blog.163.com/[email protected]/blog/static/109412748201331662656796/