直接加载资源位图到DC,此时DC是只读的,任何改写DC的操作都将失败,解决方法有:
一、将资源位图映射到DC的画刷中:
用位图作为背景并且可以在上面画图的思路是这样的:要作到不闪烁就是用内存缓冲的方法,
而用位图作为背景就要将位图的影像“映射”到View的Brush中。代码如下:
CClientDC pDC(this);
m_dc.CreateCompatibleDC(&pDC);
CBitmap backBitmap;
backBitmap.LoadBitmap(IDB_BITMAP1); //载入位图
BITMAP bmp; //计算位图尺寸
backBitmap.GetBitmap(&bmp);
int bmpWidth= bmp.bmWidth;
int bmpHeight= bmp.bmHeight;
CBitmap memBitmap; //创建用于画图的Bitmap
memBitmap.CreateCompatibleBitmap(&pDC,bmpWidth, bmpHeight);
CBitmap* pOldBitmap= m_dc.SelectObject(&memBitmap);
CRect rect(0,0,bmpWidth, bmpHeight); //改写Brush
CBrush bkBrush;
bkBrush.CreatePatternBrush(&backBitmap);
CBrush* pOldBrush=m_dc.SelectObject(&bkBrush);
m_dc.FillRect(rect, &bkBrush);
CPen pen(PS_SOLID, 3,RGB(10,100,10));
m_dc.SelectObject(&pen);
m_dc.MoveTo(10,10);
m_dc.LineTo(200,200);
m_dc.SetTextColor(0x1874CD);
CString s="100";
m_dc.ExtTextOut ( 150, 150, ETO_OPAQUE, NULL, s, 8, NULL );
pDC.BitBlt(0,0,CLIENT_SCREEN_X,CLIENT_SCREEN_Y,&m_dc,0,0,SRCCOPY);
二、双内存DC交换方式
选加载资源位置到内存DC1,再从DC1拷贝位图到DC2,在DC2上可随意画图。
CBitmap c_SrcBmp; ///<原始资源位图(选入DC后,DC不可写)
CBitmap c_MemBmp; ///<内存位置(可写)
HGDIOBJ h_oldSrcBmp; ///<旧源位图句柄
HGDIOBJ h_oldMemBmp; ///<旧内存位图句柄
HDC h_memReadDC; ///<内存读DC句柄
HDC h_memWriteDC; ///<内存写DC句柄
h_memReadDC = ::CreateCompatibleDC(lpDrawItemStruct->hDC); ///<内存读DC句柄
h_memWriteDC = ::CreateCompatibleDC(lpDrawItemStruct->hDC); ///<内存写DC句柄
c_MemBmp.m_hObject = ::CreateCompatibleBitmap(lpDrawItemStruct->hDC, mus_width, mus_height);
c_SrcBmp.LoadBitmap(mui_disableID);
h_oldSrcBmp = ::SelectObject(h_memReadDC, c_SrcBmp.m_hObject);
h_oldMemBmp = ::SelectObject(h_memWriteDC, c_MemBmp.m_hObject);
::BitBlt(h_memWriteDC, 0, 0, mus_width, mus_height, h_memReadDC, 0, 0, SRCCOPY);
..................
::SelectObject(h_memWriteDC, h_oldMemBmp);
::SelectObject(h_memReadDC, h_oldSrcBmp);
///清理内存(与建立顺序相反)
::DeleteDC(h_memWriteDC);
::DeleteDC(h_memReadDC);
::DeleteObject(h_oldMemBmp);
::DeleteObject(h_oldSrcBmp);
::DeleteObject(c_MemBmp);
::DeleteObject(c_SrcBmp);