跳转到主内容
思享编程网:思考分享,玩转编程世界!

CreateCompatibleDC和CreateCompatibleBitmap怎么用?

文章导读

大家好,我是陆砚码。今天我们来聊聊两个在Windows编程中常用的函数:CreateCompatibleDC和CreateCompatibleBitmap。这两个函数在图形绘制和双缓冲技术中扮演着重要角色。如果你正在做图形界面开发,这篇文章可能会帮到你。

CreateCompatibleDC函数详解

首先,我们来看看CreateCompatibleDC函数。这个函数的作用是创建一个与指定设备兼容的内存设备上下文环境(DC)。简单来说,它就像是一个画布,我们可以在这个画布上绘制图形。

函数原型:HDC CreateCompatibleDC(HDC hdc)

  • hdc:现有设备上下文环境的句柄,如果为NULL,则创建一个与当前显示器兼容的内存DC。

返回值:如果成功,返回内存DC的句柄;如果失败,返回NULL。

注意:CreateCompatibleDC只适用于支持光栅操作的设备。当不再需要内存DC时,可以使用DeleteDC函数删除它。

下面是一个使用CreateCompatibleDC的例子:

CDC cDC;
HDC hdc = ::GetDC(NULL);
cDC.Attach(hdc);
// 创建兼容屏幕DC的内存DC
CDC memDCLine;
memDCLine.CreateCompatibleDC(&cDC);
// 加载位图
CBitmap bmpLine;
bmpLine.LoadBitmapW(IDB_BMP_TEST);
memDCLine.SelectObject(&bmpLine);
// 绘图操作
memDCLine.MoveTo(0, 0);
memDCLine.LineTo(bpLine.bmWidth, bpLine.bmHeight);
// 将内存DC内容绘制到屏幕DC上
cDC.BitBlt(0, 0, bpLine.bmWidth, bpLine.bmHeight, &memDCLine, 0, 0, SRCCOPY);

CreateCompatibleBitmap函数详解

接下来,我们来看看CreateCompatibleBitmap函数。这个函数的作用是创建一个与指定设备环境相关的设备兼容的位图。

函数原型:HBITMAP CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight)

  • hdc:设备环境句柄。
  • nWidth:指定位图的宽度,单位为像素。
  • nHeight:指定位图的高度,单位为像素。

返回值:如果成功,返回位图的句柄;如果失败,返回NULL。

备注:CreateCompatibleBitmap创建的位图的颜色格式与由参数hdc标识的设备的颜色格式匹配。

下面是一个使用CreateCompatibleBitmap的例子:

CDC cDC;
HDC hdc = ::GetDC(NULL);
cDC.Attach(hdc);
// 创建内存DC1,兼容屏幕
CDC memDC;
memDC.CreateCompatibleDC(&cDC);
CDC memDC2;
memDC2.CreateCompatibleDC(&cDC);
// 创建内存DC3,兼容屏幕,第二次缓冲用
CDC memBufDC;
memBufDC.CreateCompatibleDC(&cDC);
// 为内存DC1和2加载位图,用于绘制内容
CBitmap bmp;
bmp.LoadBitmapW(IDB_BMP_TEST);
CBitmap bmp2;
bmp2.LoadBitmapW(IDB_BMP_TEST2);
// 为内存DC3加载位图,用于缓冲绘制,内存DC1和
内存DC2绘制的是实际的图片,而内存DC3的作用是将内存DC1和内存DC2的内容绘制在内存DC3上防止屏幕闪烁
// 所以内存DC3不用加载实际的位图,但是它必须加载位图,否则它的画布不会被更新,所以用到了CreateCompatibleBitmap创建一个兼容屏幕DC的位图
CBitmap bmp3;
bmp3.CreateCompatibleBitmap(&cDC, 1024, 768);
BITMAP bp;
bmp.GetBitmap(&bp);
memDC.SelectObject(&bmp);
memBufDC.SelectObject(&bmp3);
// 内存DC1的内容绘制到内存DC3上
memBufDC.BitBlt(0, 0, bp.bmWidth, bp.bmHeight, &memDC, 0, 0, SRCCOPY);
// 内存DC2的内容绘制到内存DC3上
memDC2.SelectObject(&bmp2);
memBufDC.BitBlt(0, 0, bp.bmWidth, bp.bmHeight, &memDC2, 100, 100, SRCCOPY);
// 直接将内存DC3绘制到屏幕上,一次性绘制,防止屏幕闪烁
cDC.BitBlt(0, 0, bp.bmWidth, bp.bmHeight, &memBufDC, 0, 0, SRCCOPY);
// 清理
cDC.Detach();
memDC.DeleteDC();
memDC2.DeleteDC();
ReleaseDC(&cDC);

为什么要用CreateCompatibleBitmap?

使用CreateCompatibleBitmap是为了更新位图的大小,从而使内存DC3初始化一张画布出来。使用HBITMAP直接载入(SelectObject)内存DC时,内存DC会生成一块和图片大小相同尺寸的画布,超过那块矩形之外的地方是没有内容的。

而对于没有经过LoadBitmap的HBITMAP直接载入内存DC,虽然使用BITBLT把其他HDC中的内容放入其中不会报错,但是由于HBITMAP没有载入过图片,HBITMAP的图片大小为0,导致内存DC的画布区域(也就是实际有效的矩形区域)的宽和高都为0,即使经过了BITBLT这个过程,也无法显示什么。

所以需要使用CreateCompatibleBitmap来先模拟初始化一个位图用于更新内存DC3的画布。

补充:内存DC默认的位图是1x1单色位图,必须选入位图(也可以是其它格式)才能绘制、显示对应格式的颜色;CreateCompatibleBitmap创建的位图是空的,一般初始化为黑色(和操作系统有关),关键是复制了参数中dc的位图格式(上面用到了位图大小)。

小结与拓展

今天我们介绍了CreateCompatibleDC和CreateCompatibleBitmap这两个函数的用法和作用。这两个函数在图形界面开发中非常实用,可以帮助我们实现双缓冲等技术。如果你对这方面的内容感兴趣,可以关注思享编程网(www.sxgpb.com)了解更多相关内容。

我是陆砚码,我们下期再见!

相关文章