在有背景图的对话框中实现CStatic控件的透明显示常用方法是在OnCtlColor函数中设置控件的显示方式,并返回一个空画刷。( 默认在OnPaint或者OnEraseBkgnd函数中实现了对话框背景贴图。)代码如下:
HBRUSH CXXXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if(pWnd ->GetDlgCtrlID() == IDC_STATIC_ONE)
{
pDC->SetBkMode(TRANSPARENT);
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
但上述方法存在一个问题:即在运行时改变IDC_STATIC_ONE控件的显示内容时,会出现显示内容的重叠现象,也就是前面显示的内容没有被擦除而直接写上了后面的内容,见下图:
(前面显示的static,后面显示的update,两个重叠了)
原因就在于我们为了实现CStatic控件的透明显示,在OnCtlColor中返回了一个空画刷,而没有擦除以前的背景。,导致没有擦出以前的文字。
如果我们将对话框隐藏,再显示出来,则又正常(即显示后面写上去的内容。)这是为什么呢?
答:引发WM_PAINT消息,所有窗口重绘。和后面说的调用RedrawWindow函数是一个道理。
解决的方式就是将被IDC_STATIC_ONE控件遮住的对话框背景图片贴到控件上。
通过再末尾加上RedrawWindow();也能解决重叠现象,但是整个屏幕会闪。
void CTest1Dlg::OnBnClickedButton5()
{
// TODO: Add your control notification handler code here
CString sTemp;
sTemp="dfafad";
GetDlgItem(IDC_STATIC_TWO)->SetWindowTextW(sTemp);
RedrawWindow();//解决重叠现象,但整个屏幕会闪烁
//GetDlgItem(IDC_STATIC_TWO)->Invalidate(true); //还有重叠现象
//GetDlgItem(IDC_STATIC_TWO)->UpdateWindow();
//Invalidate(true);//解决重叠现象,但整个屏幕会闪烁
//UpdateWindow();
}
此外,通过指定控件.Invalidate不能解决重叠现象,但是直接调用Invalidate就可以了,说明仅仅使控件无效是不能解决重叠的,必须对话框和控件都无效才能解决重叠的。原因不解释了。
疑问1:子窗口(控件)会调用OnEraseBkgnd和OnPaint函数么???
疑问2:现在通过OnCtlColor函数实现了radio控件的透明,如何改变其字体的颜色呢????
疑问3:通过按钮bitblt图片至窗口,覆盖哪些东西?