CreateCompatibleDC与BitBlt 学习

本文详细介绍了CreateCompatibleDC和BitBlt两个Windows API函数的使用方法。前者用于创建与指定设备兼容的内存设备描述表,后者用于将一个设备上下文的内容复制到另一个设备上下文中。文章通过实例展示了如何利用这两个函数实现屏幕内容的绘制和拷贝。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CreateCompatibleDC与BitBlt

CreateCompatibleDC

创建一个与指定设备一致的内存设备描述表。

HDC CreateCompatibleDC(HDC hdc //设备描述表句柄);

参数 hdc

现有的设备描述表的一个句柄,如果这个句柄为NULL,则函数创建一个和应用程序当前屏幕一致的内存设备描述表。

返回值 如果函数调用成功,则返回一个内存设备描述表句柄;否则返回NULL。

说明
创建一个与特定设备场景一致的内存设备场景
返回值
Long,新设备场景句柄,若出错则为零
参数表
参数类型及说明
hdcLong,设备场景句柄。新的设备场景将与它一致。也可能为0以创建一个与屏幕一致的设备场景
注解

在绘制之前,先要为该设备场景选定一个位图。不再需要时,该设备场景可用DeleteDC函数删除。删除前,其所有对象应回复初始状态

BitBlt( //图形拷贝
  HMDC0, //目标设备场景
  x0,y0 //目标左上角坐标
  w,h //目标图形宽、高
  HMDC1, //源设备场景
  x1,y1 //源左上角坐标
  SRCCOPY //拷贝方式,这里是直接拷贝);

使用方法:

CreateCompatibleDC

CDC MemDC;//首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象

//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);
//这时还不能绘图,因为没有地方画^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
CRect rc;
GetClientRect(&rc);

MemBitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap* pOldBit=MemDC.SelectObject(&MemBitmap);

//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
MemDC.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(255,255,255));

......//一些绘制过程


//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,SRCCOPY);

//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();

尤其是最后两部:
MemBitmap.DeleteObject();
MemDC.DeleteDC();
这是清理和回收内存的!

转载于:https://www.cnblogs.com/kanego/p/3584144.html

<think>好的,我需要回答用户关于MFC/GDI编程中CreateCompatibleDC和new CDC的差异及使用场景的问题。首先,我需要回忆这两个函数的作用和区别。 根据引用中的信息,用户提到了new CDC和GetDC,还有CreateCompatibleBitmap。CreateCompatibleDC应该和内存设备上下文有关。通常,在GDI中,CreateCompatibleDC用于创建当前设备兼容的内存DC,用于绘图操作,比如双缓冲。而new CDC是直接创建一个CDC对象,但可能需要通过Attach关联到已有的HDC,如引用1中的例子。用户提供的引用3提到GetDC用于获取窗口或屏幕的DC,这可能和CreateCompatibleDC的使用场景不同。 接下来,我需要明确两者的差异。CreateCompatibleDC是API函数,生成一个兼容的内存DC,而new CDC是MFC中创建CDC对象的方式,但需要正确初始化,比如通过Attach或CreateCompatibleDC。此外,内存DC通常需要位图结合使用,如引用2中的CreateCompatibleBitmap,用于创建兼容位图,然后选入内存DC中进行绘制。而直接new CDC可能没有关联到有效的设备上下文,需要后续绑定。 使用场景方面,CreateCompatibleDC常用于离屏绘图,比如避免闪烁,或者处理位图。而new CDC可能用于需要手动管理设备上下文的情况,例如从现有的HDC创建对象,如引用1中的例子,但需要注意正确释放资源。 另外,引用4中的BitBlt操作可能需要源和目标DC,这里源可能是一个内存DC,而目标可能是屏幕DC。因此,正确使用CreateCompatibleDC和关联的位图是关键。 总结差异点:创建方式、用途(内存DC vs 通用CDC对象)、是否需要关联HDC、资源管理方式。需要分点说明,并给出示例场景,如双缓冲使用CreateCompatibleDC,而new CDC配合Attach用于获取现有DC。 最后,检查是否有遗漏的引用内容,确保回答准确。可能还需要提到资源释放,比如DeleteDC和ReleaseDC的区别,但用户的问题主要关注差异和使用场景,所以重点放在那里。</think>在MFC/GDI编程中,`CreateCompatibleDC`和`new CDC`的差异主要体现在对象创建方式、应用场景及资源管理上: --- ### 1. **本质差异** - **`CreateCompatibleDC`** 这是GDI函数,用于创建指定设备上下文(DC)兼容的**内存设备上下文**。它生成的DC不直接关联物理设备,而是作为离屏绘图的“画布”,通常需要配合兼容位图使用(如`CreateCompatibleBitmap`[^2])。例如: ```cpp CDC memDC; memDC.CreateCompatibleDC(pDC); // 创建屏幕兼容的内存DC CBitmap bmp; bmp.CreateCompatibleBitmap(pDC, width, height); // 创建兼容位图 memDC.SelectObject(&bmp); // 将位图选入内存DC ``` 后续可通过`BitBlt`将内存DC内容复制到屏幕DC[^4]。 - **`new CDC`** 这是MFC中直接实例化`CDC`对象的方式。但新创建的`CDC`对象默认未关联任何设备上下文,需手动绑定HDC(如通过`Attach`或`GetDC`)。例如: ```cpp CDC *pDC = new CDC; pDC->Attach(hdc); // 将现有HDC附加到CDC对象[^1] ``` 若未正确绑定HDC,直接操作可能导致崩溃。 --- ### 2. **使用场景对比** | **场景** | `CreateCompatibleDC` | `new CDC` | |------------------------|-----------------------------------------------|-----------------------------------------| | **双缓冲绘图** | ✔️ 创建内存DC避免屏幕闪烁 | ❌ 需手动关联兼容DC | | **临时设备上下文操作** | ❌ 需提前创建兼容DC | ✔️ 通过`GetDC()`快速获取窗口DC[^3] | | **位图处理** | ✔️ 必须配合位图使用(如截图、图像合成)[^5] | ❌ 需额外步骤绑定位图 | | **跨线程资源管理** | ❌ 需注意DC线程归属 | ✔️ 可封装HDC实现线程局部存储 | --- ### 3. **资源管理注意事项** - **`CreateCompatibleDC`** 必须通过`DeleteDC()`释放内存DC,否则造成资源泄漏。 - **`new CDC`** 若通过`Attach`绑定HDC,需调用`Detach()`后手动释放;若通过`GetDC()`获取,需用`ReleaseDC()`释放[^1]。 --- ### 示例场景 1. **屏幕截图(使用`CreateCompatibleDC`)** ```cpp CDC memDC; memDC.CreateCompatibleDC(NULL); // 创建屏幕兼容的内存DC CBitmap bmp; bmp.CreateCompatibleBitmap(GetDC(), width, height); // 引用[2] memDC.SelectObject(&bmp); // 使用BitBlt拷贝屏幕内容到memDC ``` 2. **临时绘图(使用`new CDC`)** ```cpp CDC* pDC = new CDC; pDC->Attach(::GetDC(hWnd)); // 绑定窗口DC pDC->TextOut(10, 10, _T("Hello")); ::ReleaseDC(hWnd, pDC->Detach()); delete pDC; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值