怎么在对话框OnPaint()中利用双缓冲解决屏幕刷新时闪烁有关问题?
如何在对话框OnPaint()中利用双缓冲解决屏幕刷新时闪烁问题?急~~
在CDlg的OnPaint中
执行
CFont font;
// CPen pen;
// CBrush brush;
dc.SelectStockObject(NULL_BRUSH);
dc.SetBkMode(TRANSPARENT);
if (m_bDraw)
{
for(int i=0;i<10;i++)
{
font.CreatePointFont(m_FontSize[i],"宋体");
CFont* pOldFont=dc.SelectObject(&font);
dc.SetTextColor(m_color[i]);
dc.TextOut(m_TextPos[i],m_rectSepareter.bottom+10,strSpaceText[i]);
dc.SelectObject(pOldFont);
font.Detach();
}
}
void CSpaceTextView::OnTimer(UINT nIDEvent)
{
KillTimer(1);
Alpha=Alpha-I_Alpha;
for(int i=0;i<10;i++)
{
Alpha1=Alpha+Decal*i;
Cosine=cos(Alpha1);
fontsize[i]=(Taille+30*Cosine)*7;
posx[i]=Midx+100*sin(Alpha1);
col[i]=RGB((27+Cosine*80+50),(127+Cosine*80+50),0);
}
bdraw=TRUE;
Invalidate();
SetTimer(1,50,NULL);
CView::OnTimer(nIDEvent);
}
50ms刷新一次。。。。。
用双缓冲怎么解决了。。在网上看了资料,感觉好模糊。
在对话框中是否需要添加WM_ERASEBKGND的响应函数。
在里面创建CMemDC,CBitmap结构。。
双缓冲是不是相当于在内存中开辟一个CBitmap变量的内存(可以是其他结构的不?),在里面画好了。
在用memDC.BitBlt()画到view上或Dlg上?
我这个要怎么解决呢。。
在对话框上。
------解决方案--------------------
楼主的代码可以这么改:
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC); //创建与视图的设备相兼容的内存设备
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom); //创建一个与视图兼容的位图
CBitmap* pOldBmp=dcMem.SelectObject(&bmp); //选择位图
CFont font;
// CPen pen;
// CBrush brush;
dcMem.SelectStockObject(NULL_BRUSH);
dcMem.SetBkMode(TRANSPARENT);
if (m_bDraw)
{
for(int i=0;i <10;i++)
{
font.CreatePointFont(m_FontSize[i],"宋体");
CFont* pOldFont=dcMem.SelectObject(&font);
dcMem.SetTextColor(m_color[i]);
dcMem.TextOut(m_TextPos[i],m_rectSepareter.bottom+10,strSpaceText[i]);
dcMem.SelectObject(pOldFont);
font.Detach();
}
}
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY); //将在内存中绘制好的图像重新显示到视图中
dcMem.SelectObject(pOldBmp);
pOldBmp->DeleteObject();
所谓的双缓存其实就是将源视图的一部分放入到内存视图中,然后把一系列复杂的绘图操作都在内存中绘制,如果直接在窗体上绘制,大量的颜色变化会引起屏幕闪烁感。双缓存主要是为了改善视觉效应。在使用双缓存时,之所以要用
bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
是因为这个方法,可以原份不动地将视图中的原来颜色复制下来,而一般的CreateCompatibleDC方法则无法做到,它甚至不能复制原设备描述表的属性,仅结构上兼容与原设备。CreateCompatibleBitmap方法保证了,在改变原来视图颜色的基础上继续作图。
在调用了dcMem.CreateCompatibleDC与bmp.CreateCompatibleBitmap方法,那么dcMem就可以理所当然地将bmp选入到自己的设备中。dcMem.CreateCompatibleDC语句也会后面的pDC->BitBlt奠定了基础,只有两个兼容的位图才能使用BitBlt方法。
------解决方案--------------------
楼主你好,你的例子我们已经收到了,修正的代码如下,问题已经解决掉。
在CDlg的OnPaint中
执行
CFont font;
// CPen pen;
// CBrush brush;
dc.SelectStockObject(NULL_BRUSH);
dc.SetBkMode(TRANSPARENT);
if (m_bDraw)
{
for(int i=0;i<10;i++)
{
font.CreatePointFont(m_FontSize[i],"宋体");
CFont* pOldFont=dc.SelectObject(&font);
dc.SetTextColor(m_color[i]);
dc.TextOut(m_TextPos[i],m_rectSepareter.bottom+10,strSpaceText[i]);
dc.SelectObject(pOldFont);
font.Detach();
}
}
void CSpaceTextView::OnTimer(UINT nIDEvent)
{
KillTimer(1);
Alpha=Alpha-I_Alpha;
for(int i=0;i<10;i++)
{
Alpha1=Alpha+Decal*i;
Cosine=cos(Alpha1);
fontsize[i]=(Taille+30*Cosine)*7;
posx[i]=Midx+100*sin(Alpha1);
col[i]=RGB((27+Cosine*80+50),(127+Cosine*80+50),0);
}
bdraw=TRUE;
Invalidate();
SetTimer(1,50,NULL);
CView::OnTimer(nIDEvent);
}
50ms刷新一次。。。。。
用双缓冲怎么解决了。。在网上看了资料,感觉好模糊。
在对话框中是否需要添加WM_ERASEBKGND的响应函数。
在里面创建CMemDC,CBitmap结构。。
双缓冲是不是相当于在内存中开辟一个CBitmap变量的内存(可以是其他结构的不?),在里面画好了。
在用memDC.BitBlt()画到view上或Dlg上?
我这个要怎么解决呢。。
在对话框上。
------解决方案--------------------
楼主的代码可以这么改:
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC); //创建与视图的设备相兼容的内存设备
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom); //创建一个与视图兼容的位图
CBitmap* pOldBmp=dcMem.SelectObject(&bmp); //选择位图
CFont font;
// CPen pen;
// CBrush brush;
dcMem.SelectStockObject(NULL_BRUSH);
dcMem.SetBkMode(TRANSPARENT);
if (m_bDraw)
{
for(int i=0;i <10;i++)
{
font.CreatePointFont(m_FontSize[i],"宋体");
CFont* pOldFont=dcMem.SelectObject(&font);
dcMem.SetTextColor(m_color[i]);
dcMem.TextOut(m_TextPos[i],m_rectSepareter.bottom+10,strSpaceText[i]);
dcMem.SelectObject(pOldFont);
font.Detach();
}
}
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY); //将在内存中绘制好的图像重新显示到视图中
dcMem.SelectObject(pOldBmp);
pOldBmp->DeleteObject();
所谓的双缓存其实就是将源视图的一部分放入到内存视图中,然后把一系列复杂的绘图操作都在内存中绘制,如果直接在窗体上绘制,大量的颜色变化会引起屏幕闪烁感。双缓存主要是为了改善视觉效应。在使用双缓存时,之所以要用
bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
是因为这个方法,可以原份不动地将视图中的原来颜色复制下来,而一般的CreateCompatibleDC方法则无法做到,它甚至不能复制原设备描述表的属性,仅结构上兼容与原设备。CreateCompatibleBitmap方法保证了,在改变原来视图颜色的基础上继续作图。
在调用了dcMem.CreateCompatibleDC与bmp.CreateCompatibleBitmap方法,那么dcMem就可以理所当然地将bmp选入到自己的设备中。dcMem.CreateCompatibleDC语句也会后面的pDC->BitBlt奠定了基础,只有两个兼容的位图才能使用BitBlt方法。
------解决方案--------------------
楼主你好,你的例子我们已经收到了,修正的代码如下,问题已经解决掉。
- C/C++ code
void CSpaceTextDlg::OnTimer(UINT nIDEvent) { Alpha=Alpha-I_Alpha; Alpha=Alpha-I_Alpha; for(int i=0;i<10;i++) { Alpha1=Alpha+Decal*i; Cosine=cos(Alpha1); m_FontSize[i]=(int)(Taille+25*Cosine)*7; m_TextPos[i]=int(Midx+100*sin(Alpha1))-10; m_color[i]=RGB((27+Cosine*80+50),(127+Cosine*80+50),0); } m_bDraw=TRUE; //我们只需要局部刷新被更新的区域。 InvalidateRect(CRect(0,0,230,125),FALSE); CDialog::OnTimer(nIDEvent); }