使用 IPicture 和 MemDC

6/16/2007 2:38:32 PM

  前一段时间,用MFC作个界面程序:画图并在上面写一段文字。原来用IPicture 在DC上 Render ,然后用DC TextOut 出文字,结果文字闪耀。在 OnEraseBkgnd(CDC* pDC) 用了 Mem dc 也没有起作用, 初始还以为刷新快不能做到不闪耀,后来才发现 mem dc 忘了设置 Bitmap ,没有 bitmap 对于内存dc不能画上内容,而 OnPaint 中又没有使用内存DC。导致一直是OnPaint 中DC在画图和写字。
bool DrawPicture(CDC* pdc, IPicture* pic, const CRect& rcBounds)
{
 CDC MemDC;  //定义内存DC
 MemDC.CreateCompatibleDC(NULL);   //注意不要写成.CreateCompatibleDC(pdc);
 MemDC.SetBkMode(TRANSPARENT);  //设置透明,Textout写字没有白色的背景块
 //得到图片的宽度和高度
 SIZE sizeInHiMetric;
 pic->get_Width(&sizeInHiMetric.cx);  //获取加载进pic的图像宽度和高度
 pic->get_Height(&sizeInHiMetric.cy);
 CBitmap bmpFace;   //创建bitmap
 bmpFace.CreateCompatibleBitmap(pdc, rcBounds.Width(), rcBounds.Height()); 
 //将这幅图片选入内存DC,原来memdc不起作用就是因为,bmp图片没有选入到dc中.郁闷
 CBitmap* pOldBmp = MemDC.SelectObject(&bmpFace); 
 //把整个图片 {0,cy,cx,-cy} .拷贝到 memdc 的rcBounds 区域 
 pic->Render(MemDC.GetSafeHdc(), rcBounds.left, rcBounds.top, rcBounds.right, rcBounds.bottom,
  0, sizeInHiMetric.cy, sizeInHiMetric.cx, -sizeInHiMetric.cy, &rcBounds);
 MemDC.SetTextColor(RGB(0,255,0));
 MemDC.TextOut(3,3,m_strFileTips); 
 //拷贝memdc (0,0,rcbounds.width,rcbounds.height) 区域到 pdc
 pdc->BitBlt(0,0,rcBounds.Width(),rcBounds.Height(),&MemDC,0,0,SRCCOPY);   //拷贝 memdc - > dc
 MemDC.SelectObject(pOldBmp);
 bmpFace.DeleteObject();
 MemDC.DeleteDC();
 return true;
}
 
对于镂空图可以使用
void DrawTransPic(IPicture* pic,const CRect& rc,COLORREF clr)
{
 if(pic == NULL)
  return;
 CDC dc;  //内存DC
 dc.CreateCompatibleDC(NULL);
 CBitmap bmp;
 bmp.CreateCompatibleBitmap(&m_MemDC,m_RtDC.Width(),m_RtDC.Height());  //m_RtDC为内存DC区域
 CBitmap* pold = dc.SelectObject(&bmp);
 SIZE sizeInHiMetric;
 pic->get_Width(&sizeInHiMetric.cx);
 pic->get_Height(&sizeInHiMetric.cy); 
 //拷贝整个图片到dc整个客户区
 pic->Render(dc.GetSafeHdc(), 0, 0, m_RtDC.Width(), m_RtDC.Height(),
    0, sizeInHiMetric.cy, sizeInHiMetric.cx, -sizeInHiMetric.cy, NULL);   //把 pic 画到真个dc 上
 //这里的m_MemDC 也是内存DC,拷贝dc 整个区域到m_MemDC 的 rc 区域,clr 为要剔除掉的关键色
 m_MemDC.TransparentBlt(rc.left,rc.top,rc.Width(),rc.Height(),&dc,0,0,m_RtDC.Width(),m_RtDC.Height(),clr);
 bmp.DeleteObject();
 dc.SelectObject(pold);
 dc.DeleteDC();
}
最后 m_RealDC 真正的设备 dc, 获取全部 memdc 内容
m_RealDC->BitBlt(0,0,m_RtDC.Width(),m_RtDC.Height(),&m_MemDC,0,0,SRCCOPY);
可以在 OnPaint() 和 OnEraseBkgnd(CDC* pDC) 调用该函数DrawPicture 函数,OnEraseBkgnd(CDC* pDC) 注意要 return TRUE;
使用后不再有闪耀的问题。
当然镂空图最好的方法是layerwindow

posted on 2010-10-08 15:20  阿蒙1024  阅读(838)  评论(0)    收藏  举报

导航