CDC在屏幕绘图可以用以下方法:
CDC dc;
dc.CreateCompatibleDC(NULL);
CBitmap m_bitmap;
m_bitmap.LoadBitmap(IDB_BITMAP1); //载入资源文件
dc.SelectObject(&m_bitmap);
CDC *pDC = GetDC();
pDC->BitBlt(0,0,200,100,&dc,0,0,SRCCOPY);
m_bitmap.DeleteObject();
dc.DeleteDC();
上面虽然可以在屏幕绘图,但是如里需要绘多张图,并且有重叠的部份,当鼠标改变窗口大小时,重叠部份有严重的闪烁。非常难看
CDC *pDC = GetDC();
pDC->BitBlt(0,0,200,100,&dc,0,0,SRCCOPY); 这个方式是直接在屏幕绘图,如果多张图,即多次调用此方法。
为了避免闪烁,可采用双缓冲的方法,不管你要绘多少张图,先把它们绘在一个内存DC,之后再在屏幕显示
DC小知识点:
CDC dc; 这个是内存dc, 使用BitBlt只会在内存中,不会在屏幕显示
一旦dc=GetDC(); 此时dc就与屏幕有关了,BitBlt方法就会输出的屏幕
CDC双缓冲防闪屏绘图实例
下面的nWidth,nHeight 是屏幕的宽高
CDC *pDC=this->GetDC(); //此DC负责在屏幕显示
CDC dc,sub_dc; //dc 负责组建对话框整张大图,sub_dc负责里面小块
dc.CreateCompatibleDC(NULL);
sub_dc.CreateCompatibleDC(&dc); //注意参数,&dc就指定了sub_dc是基于dc的。
CBitmap bg_bmp,load_bmp; // bg_bmp负责构造背景,load_bmp负责从资源文件载入位图
bg_bmp.CreateCompatibleBitmap(pDC,nWidth,nHeight); //先创建一张与对话框当前大小一致的位图
dc.SelectObject(&bg_bmp);
dc.FillSolidRect(0,0,nWidth,nHeight,RGB(236,236,234)); //构造背景
bg_bmp.DeleteObject();
//构造第一张图
load_bmp.LoadBitmap(IDB_TITLE_L); //从资源载入第一张图
sub_dc.SelectObject(&load_bmp); //放到sub_dc中,
dc.BitBlt(0,0,16,28,&sub_dc,0,0,SRCCOPY); //把sub_dc的内容写到dc中,此时dc的内容并不会在屏幕显示
load_bmp.DeleteObject();
//构造第二张图
load_bmp.LoadBitmap(IDB_TITLE_BG); //从资源载入第二张图
sub_dc.SelectObject(&load_bmp); //放到sub_dc中,
dc.StretchBlt(16,0,(nWidth-145),28,&sub_dc,0,0,1,28,SRCCOPY); //再把sub_dc的内容写到dc中,这样第二张图就与第一张图合在一起变成了一张图
load_bmp.DeleteObject();
//输出到屏幕
pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dc,0,0,SRCCOPY);
this->ReleaseDC(pDC);
this->ReleaseDC(&dc);
this->ReleaseDC(&sub_dc);
OK,至此双缓冲绘图完全完成了。
单缓冲用两个dc, 比缓冲用了三个dc:dc,sub_dc , pDC
dc利用BitBlt方法合并成一张大图,pDC把dc的内存显示到屏幕、
这样,不管有多少张图,实际上只在屏幕输出一次,就避免了闪烁现象