在一个基于对话框的应用程序中,用CreateWindows()另外创建了一个窗口,
现在在window2中画实时显示的背景图,达到了无闪烁的动画效果。
现在想在背景图上面另外画一些小图标,可这些小图标却老是闪烁显示啊?
大虾们,怎么才能让它们也不闪啊?
UP者有分。 《《 很急,真帮忙解决问题的,可以另开贴给分。》》
UP
用背景色重画不行?或者直接内存copy
用双缓冲进行刷新
void CMyEdit::OnPaint()
{
//在View中显示整个界面背景位图,编辑框取出其外框区域内的背景位图。
CPaintDC dc(this); // device context for painting
CRect re;
GetClientRect(&re);//得到Edit控件的外框,即背景区域
if(bFirst){
//第一次刷新,取得编辑框下的背景位图,
memDC->CreateCompatibleDC(&dc);
bFirst=FALSE;
//关键就是我不会保存该背景位图,下次刷新前怎样载入它?
bitmap.CreateCompatibleBitmap(&dc,re.Width(),re.Height());
oldBmp=memDC->SelectObject(&bitmap); //选入取得的背景位图。
memDC->BitBlt(0,0,re.Width(),re.Height(),&dc,0,0,SRCCOPY);//载进缓存上下文。
bitmap.DeleteObject();
}
else {
//这里如何载入保存的背景位图?
}
LOGFONT lf;
GetFont()->GetLogFont(&lf);
memDC->SetBkMode(1);
memDC->SelectObject(GetFont());
for() //显示文字的循环。
{
......
memDC->TextOut(0, i*nLineH, p);
}
dc.BitBlt(0,0,re.Width(),re.Height(),memDC,0,0,SRCCOPY);
memDC->SelectObject(oldBmp);
}
不知道你实时显示的背景图是怎么做的,能说一下吗?
建议:
多做几个memDC,每个小图标分别做一个memdc
例如:
memdcIcon1.SelectObject(hIcon1);
memdcIcon2.SelecctObject(hIcon2);
memdcBk.SelectObject(hBitmap);//hbitmap背景图
Bitblt(memdcBk,.....memdcIcon1);
Bitblt(memdcBk,.....memdcIcon2);
然后
Bitblt(hdc,...memdcBk);
大概记得:
简单做法:建立一个 Timer,触发时从 avi 中取得 bitmap 后,放入一个 dc 中,再把另外的小图标写入这个 dc 中,可以同时进行颜色屏蔽,达到部分透明效果,然后将这个 dc 写入 window 的 dc 中。我就是这么实现的,对于小尺寸 avi 效果很好。如果要对付大尺寸,那就要重写 timer 部分了,比较麻烦。
不闪烁的关键是对 window 的 dc 每个周期内只写一次,就是先在内存中写好。
对了,忘说了,在上面双缓冲的基础上
还要重载WM_ERASEBKGND消息
BOOL CNanrenView::OnEraseBkgnd(CDC* pDC)
{
return false;
}
我给你一段我的代码,是“是男人就下100层的网络版”中的画图代码:
void CNanrenView::draw()
{
pMemDC->BitBlt(0,0,643,436,bmp0,0,0,SRCCOPY);
for(int i=0;i<6 ;i++)
{
pMemDC->BitBlt(fl[i],400-i*60-hight,96,16,bmp1,32*9,0,SRCCOPY);
}
for(int j=1;j< 20;j++)
{
//if(data[j].flg!=127)
{
pMemDC->BitBlt(data[j].x,data[j].y,32,32,bmp2,32*data[j].flg,32*data[j].sst,SRCAND);
pMemDC->BitBlt(data[j].x,data[j].y,32,32,bmp1,32*data[j].flg,32*data[j].sst,SRCPAINT);
}
}
InvalidateRect(re);
IsLock=false;
return;
}
void CNanrenView::OnDraw(CDC* pDC)
{
if (in==0)
{//第一次调用,用于初始化
CBitmap bitmap,bitmap2,bitmap3,bit;
bitmap.LoadBitmap(IDB_BITMAP1);
pMemDC=new CDC;
bmp0=new CDC;
bmp1=new CDC;
bmp2=new CDC;
pMemDC->CreateCompatibleDC(pDC);
pMemDC->SelectObject(&bitmap);
bit.LoadBitmap(IDB_BITMAP1) ;
bmp0->CreateCompatibleDC(pDC);
bmp0->SelectObject(&bit);
bitmap2.LoadBitmap(IDB_BITMAP2);
bmp1->CreateCompatibleDC(pDC);
bmp1->SelectObject(&bitmap2);
bitmap3.LoadBitmap(IDB_BITMAP3);
bmp2->CreateCompatibleDC(pDC);
bmp2->SelectObject(&bitmap3);
CRect* re=new CRect;
//背景
pMemDC->BitBlt(100,100,32,32,bmp1,32*8,0,SRCCOPY);
in=1;
}
CNanrenDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->BitBlt(0,0,634,436,pMemDC,0,0,SRCCOPY);
}
BOOL CNanrenView::OnEraseBkgnd(CDC* pDC)
{
return false;
}
这样就完成了,我在需要重画的时候调用draw()函数,它就改变了pMemDC,同事激发了OnDraw,不需要我控制重画的时候OnDraw就自动重画了。代码绝对可用
给你提个建议:
可以建立两个内存DC,一个用来存放源图片,一个用来完成图片的重画
然后再将重画完的内存DC中的图片,用Bitblt函数拷贝到,显示器DC,这样
你的图片就不回闪烁了!
祝你成功!