MFC绘图CBitmap/HBITMAP/CImage/CStatic/CDC/HDC-绘制到Static的五种方法

参考:http://bbs.csdn.net/topics/30173861

参考:http://www.360doc.com/content/13/0507/21/10724725_283723432.shtml 

Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  转载请标明来源 

所用的图形都是绘制到设备上来的(CDC),绘制前也需要绑定图纸(CBitmap)

先 介绍基础:HDC/CDC转换   CBitMap/HBITMAP/Bitmap转换

HDC:         Handle to a device context (DC).                  // 设备dc的句柄

CDC:         Defines a class of device-context objects.  // 封装设备dc

CBitmap:  Encapsulates a Windows graphics device interface (GDI) bitmap and provides member functions to manipulate the bitmap.  //封装Bitmap

HBITMAP: Handle to a bitmap.                                          // bitmap的句柄

Bitmap:    This class inherits from the Image class.    // 图形、图纸

转换关系上:

CDC->HDC  CBitmap->HBITMAP都是一样的方法,通过GetSafeXX()获取的Handle

             HDC hDc = dc.GetSafeHdc();

             HBITMAP hBitmap= HBITMAP(bitmap.GetSafeHandle());   // dc.Detach 同样会返回一个HBITMAP指针

HDC->CDC  HBITMAP->CBitmap 方法也类似,通常使用Attach/Detach完成使用和关闭         

             CDC dc; dc.Attach(hDc);  使用完毕后 dc.Detach().

            CBitmap bitmap; bitmap.Attach(HBITMAP); 使用完毕后 bitmap.Detach();

CBitmap->Bitmap:  通过GetBitmap获取Bitmap,形如:Bitmap bmp; bitmap.GetBitmap(bmp);

HBITMAP->Bitmap: 通过GetObject获取Bitmap,形如:Bitmap bmp;  GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&bmp);

Bitmap->HBITMAP: 通过GetHBITMAP获取HBITMAP,形如:bmp.GetHBITMAP(RGB(0,0,0), &hBitmap);

 

构建设备&选择图纸:SelectObject

当我们创建一个内存dc时,如果没有绑定图纸,是不能够绘制出信息的,绑定图纸的方法如下:形如memDC.SelectObject(&memBitmap);

	CDC memDC;						//定义一个显示设备对象
	CBitmap memBitmap;						//定义位图
	memDC.CreateCompatibleDC(m_static.GetDC());			//创建CDC兼容设备
	memBitmap.CreateCompatibleBitmap(m_static.GetDC(),iWidth,iHeight); 	//创建CDC兼容图片
	memDC.SelectObject(&memBitmap);					//设备选择当前的图纸-位图

接下来,就可以使用memDC进行绘制,调用memDC.LineTo/Draw3dRect等等,绘制完成后,可以使用下面的BitBlt来吧内容copy到static框中来

m_static.GetDC()->BitBlt(0,0,200,200,&memDC,50,50,SRCCOPY);

附加说明:BitBlt方法可以复制设备dc的一段图纸的信息出来,贴到另一个设备dc中

 (注意CreareCompatibleDC对应的DeleteDC释放)

 (注意CreateCompatibleBitmap对应的DeleteObject释放)

 

采用提出要求和给出实现方法布置下面的实现:  

要求: 在Dialog中添加了一个图片组件框(绑定CStatic变量),要把某个图片显示到这个里面

实现方法1:借用CImage中对图片的支持

a. 修改Static框为Bitmap模式

   设置属性-杂项-type:Bitmap

(也可以在OnInitDialog代码中添加属性修改:m_staticPic.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 加载图片&设置到Static中,在OnInitDialog中

		CImage image;				//使用图片类   
		image.Load(m_cstrPicName);			//装载路径下图片信息到图片类  
		m_staticPic.SetBitmap(image.Detach());


 

实现方法2:导入到工程里的Bitmap文件,借用LoadBitmap

a. 同样的修改CStatic框为BItmap模式 

	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 加载图片&设置到Static中

	HBITMAP hBitmap=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_TEST)); // 加载图片
	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);
	m_static.SetBitmap(hBitmap); 


 

实现方法3:借助Gdiplus::Bitmap加载图片

a. 同样的修改CStatic框为Bitmap模式

	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 在构造函数中初始化gdi/关闭gdi

Dlg中声明变量 
    	ULONG_PTR m_gdiplus;
构造函数中初始化gdi:
	Gdiplus::GdiplusStartupInput input;  
	Gdiplus::GdiplusStartup(&m_gdiplus,&input,NULL); 
析构函数中关闭gdi:
	Gdiplus::GdiplusShutdown(m_gdiplus);  

c. 使用gdi相关的函数打开文件&设置给static框

	Gdiplus::Bitmap gdiBitmap(cstrPathFile);  	//传入图片路径
	HBITMAP hBitmap;
	gdiBitmap.GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);
	m_static.SetBitmap(hBitmap);




 实现方法四:OnPaint中直接绘制

a. 重载Dialog的OnPaint函数,在OnPaint函数中添加代码:例如,绘制一个彩色的框

    声明一个CPaintDC,绑定static框,然后绘制

	CPaintDC dcStatic((CWnd*)&m_static);
	dcStatic.FillSolidRect(0, 0, 100, 10, RGB(0,255,0));

 


实现方法五:使用CBitmap内存中创建一个图形,绑定给static框

a. 同样的修改CStatic框为Bitmap模式

	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 创建图形&图形绑定给static框 

	CDC memDC;						//定义一个显示设备对象
	CBitmap memBitmap;						//定义位图
	memDC.CreateCompatibleDC(m_static.GetDC());			//创建CDC兼容设备
	memBitmap.CreateCompatibleBitmap(m_static.GetDC(),iWidth,iHeight); 	//创建CDC兼容图片
	CBitmap* pOldBmp = memDC.SelectObject(&memBitmap);					//设备选择当前的图纸-位图
	memDC.Draw3dRect(0, 0, iWidth, iHeight, RGB(0,0,0), RGB(225,225,225));	//图纸上绘制信息
	m_static.SetBitmap(&memBitmap);
	memBitmap.DeleteObject();
	memBitmap.Detach();  memDC.selectObject(pOldBmp); memDC.DeleteDC();

最后一步绑定static框,也可以采用复制的方法,从memdc中直接复制一段信息:

m_static.GetDC()->BitBlt(0,0,200,200,&memDC,50,50,SRCCOPY);

 

 实现方法六:使用Cimage在内存中创建一个图形,绑定给 static框

a. 同样的修改CStatic框为Bitmap模式

	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 创建图形,使用SetPixelRGB设置颜色

	int iWidth = 500, iHeight = 500;
	CImage image;
	image.Create(iWidth, iHeight, 24);
	for (int i=0; i

 

实现方法七:Cimage和CBitmap混用,实现类似水印效果

a. 同样的修改CStatic框为Bitmap模式

	m_static.ModifyStyle(SS_ENHMETAFILE,SS_BITMAP|SS_CENTERIMAGE);

b. 创建Cimage,先绘制一些信息

int iWidth = 500, iHeight = 500;
	CImage image;
	image.Create(iWidth, iHeight, 32);
	for (int i=0; i

c.  创建内存DC,Cimage作为CBitmap绑定给MemDC,绘制附加信息

	CDC memDC;									
	memDC.CreateCompatibleDC(GetDC());
	memDC.SelectObject(image.Detach());  // 或 HBITMAP hMap = image.Detach(); memDC.SelectObject(hMap);
	memDC.FillSolidRect(0, 0, iWidth, iHeight/2, RGB(0,255,0)); // 绘制一些其他信息

d. 绑定给Static框

m_static.SetBitmap(HBITMAP(memDC.GetCurrentBitmap()->GetSafeHandle()));   // 或 m_static.SetBitmap(hMap);

注意:如果使用CBitmap.attach接受image.Detach时,需要注意对cbitmap进行detach,否则CBitmap生命周期结束,会释放资源,导致图片不显示

 

 

你可能感兴趣的:(MFC,C++)