CStatic控件背景透明且改变其文本时,文字重叠解决方法

来源:互联网 发布:简明python教程 从哪买 编辑:程序博客网 时间:2024/06/03 13:23

问题 提出:

最近在项目中将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/danshiming@126/blog/static/109412748201331662656796/

0 0