请教如何解决双缓冲刷新和半透明控件显示背景的矛盾
在下在一个对话框上想绘制一个动画,因此需要使用双缓冲进行不断地刷新;然而在该对话框上又有需要半透明效果的控件(比如半透明的PNG按钮),使他们能透过本身显示出下面对话框背景的颜色。
个人在实际的使用中,发现以我掌握到的方法,对话框的双缓冲和半透明控件之间似乎很难共存。主要是如下几个方面造成的:
1、为了动态显示动画,必须使用双缓冲;
2、由于对话框不断的刷新——即使只刷新动画那一块,一样会造成对话框上控件的闪烁;
3、为了阻止对话框在重绘时不断刷新控件,于是我只能将对话框的“Clip Children”属性设置为true;
4、“Clip Children”属性设置后,对话框重绘时不去管它的子控件,闪是不会闪了,可半透明按钮“先绘制背景,再在该区域上绘制本按钮”的要求又达不到了。
对话框中的OnPaint()函数代码:
void CtestDlg::OnPaint(){ CPaintDC dc(this); // device context for painting CRect rect; GetClientRect(&rect); int Width = rect.right - rect.left; int Height = rect.bottom - rect.top; CDC *pDC = this->GetDC(); CDC MenmDC; CBitmap MemBitmap; MenmDC.CreateCompatibleDC(NULL); MemBitmap.CreateCompatibleBitmap(pDC, Width, Height); CBitmap *pOldBit = MenmDC.SelectObject(&MemBitmap); /*********************************************************/ MenmDC.FillSolidRect(0, 0, Width, Height, RGB(255, 128, 0)); //根据变量计数,绘制当前进度条的长度 using namespace Gdiplus; Graphics graphics(MenmDC.m_hDC); graphics.DrawImage(m_ImgScroll, Rect(30, 120, m_ImgScroll->GetWidth() * ((float)m_Tick / (float)100), m_ImgScroll->GetHeight()), 0, 0, m_ImgScroll->GetWidth() * ((float)m_Tick / (float)100), m_ImgScroll->GetHeight(), UnitPixel); /*********************************************************/ pDC->BitBlt(0, 0, Width, Height, &MenmDC, 0, 0, SRCCOPY); MenmDC.SelectObject(pOldBit); MemBitmap.DeleteObject(); MenmDC.DeleteDC(); ReleaseDC(pDC);}BOOL CtestDlg::OnEraseBkgnd(CDC* pDC){ return TRUE;}void CtestDlg::OnTimer(UINT nIDEvent){ switch (nIDEvent) { case 1201: { ++ m_Tick; if (m_Tick >= 100) { m_Tick = 0; } //获取当前进度条需要绘制的长度,并刷新之 CRect rect; rect.left = 30; rect.top = 120; rect.right = rect.left + m_ImgScroll->GetWidth() * ((float)m_Tick / (float)100); rect.bottom = rect.top + m_ImgScroll->GetHeight(); InvalidateRect(&rect, FALSE); } break; }}