原理:
创建内存位图对象;
创建内存DC;
将位图对象选入到内存DC,便可以在内存DC中画图;
最后将内存DC中的图拷贝到窗口DC
在BOOL C***Dlg::OnEraseBkgnd(CDC* pDC) 中实现:
CDC MemDC; //定义一个显示设备对象 CBitmap MemBitmap;//定义一个内存位图对象 //随后建立与屏幕显示兼容的内存显示设备 MemDC.CreateCompatibleDC(NULL); //或者MemDC.CreateCompatibleDC(pDc); //这时还不能绘图,因为没有地方画 //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBitmap = MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色 MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //绘图内存图(如果是现成的位图,只要LoadBitmap一下资源就可以直接贴图了) MemDC.MoveTo(……); MemDC.LineTo(……); ...等等绘图操作 //最后再将内存中的图全部拷贝到屏幕上进行显示 pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); //还原内存DC原来位图(通常省略) memDC.SelectObject(pOldBitmap); //绘图完成后的清理 MemBitmap.DeleteObject(); MemDC.DeleteDC();
//加载图片 CBitmap m_BkGndBmp; m_BkGndBmp.LoadBitmap(IDB_BITMAP3); //获取窗口大小 CRect rcClient; GetClientRect(&rcClient); //获取图片大小 BITMAP bm; m_BkGndBmp.GetBitmap(&bm); //创建内存DC CDC memDC; memDC.CreateCompatibleDC(pDC); //将为图选入DC CBitmap *pOldBmp = memDC.SelectObject(&m_BkGndBmp); //拷贝DC到窗口 pDC->StretchBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); //清理内存 memDC.SelectObject(pOldBmp); memDC.DeleteDC();
例 2:
//背景重绘 //注意: 为了避免动态进度条的闪烁,通过两个办法: //(1).将所有要绘制的,如圆角边框,内部填充色,动态链接图片等等先画到内存,最后再从内存拷贝到屏幕 //(2).屏蔽系统的CDialogEx::OnEraseBkgnd(pDC); BOOL CConnectDlg::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //CDialogEx::OnEraseBkgnd(pDC); //屏蔽以避免闪烁 //窗口大小 CRect rc; GetClientRect(&rc); //创建内存DC CDC dcTmp; dcTmp.CreateCompatibleDC(pDC); //创建内存位图(大小通常用窗口大小) CBitmap bmpTmp; bmpTmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height()); //将位图选入内存DC CBitmap *pOldBitmap = dcTmp.SelectObject(&bmpTmp); //下面操作开始在内存DC中画图 //操作1:画窗口的圆角边框及内部填充色 POINT pt; pt.x = 5; pt.y = 5; CRect rc2(rc); //画边框时需要向内缩进 rc2.right -= 1; rc2.bottom -= 1; CPen hNewPen(PS_SOLID, 1, RGB(170, 170, 170)); CPen* hOldPen = dcTmp.SelectObject(&hNewPen); dcTmp.RoundRect(&rc2, pt); //注意:RoundRect()会将自动填充内部颜色为默认画笔的RGB(255,255,255) dcTmp.SelectObject(hOldPen); rc2.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE))); //区域向内缩进一个边框 CBrush brush(RGB(240, 240, 240)); //故画线后需要重新填充内部颜色 dcTmp.FillRect(&rc2, &brush); brush.DeleteObject(); //操作2:加载图片 Graphics graphics(dcTmp.GetSafeHdc()); graphics.DrawImage(m_pImage1, m_nX, m_nY, m_nW, m_nH); graphics.DrawImage(m_pImage2, m_rcProcess, m_nOffsetX, 0, m_rcProcess.Width, m_rcProcess.Height, UnitPixel); //操作3:绘制按钮 DrawTitleButton(&dcTmp); //然后将画好的内存图全部拷贝到屏幕上显示 pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &dcTmp, 0, 0, SRCCOPY); //还原原来的DC dcTmp.SelectObject(pOldBitmap); //最后清理内存 bmpTmp.DeleteObject(); dcTmp.DeleteDC(); return TRUE; }
该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。 BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop); 函数从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩。 BOOL StretchBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop);