CreateCompatibleBitmap 的使用
函数功能:该函数创建与指定的设备环境相关的设备兼容的位图。
函数原型:HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight);
参数:
hdc:设备环境句柄。
nWidth:指定位图的宽度,单位为像素。
nHeight:指定位图的高度,单位为像素。
返回值:如果函数执行成功,那么返回值是位图的句柄;如果函数执行失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError。
备注:由CreateCompatibleBitmap函数创建的位图的颜色格式与由参数hdc标识的设备的颜色格式匹配。该位图可以选入任意一个与原设备兼容的内存设备环境中。由于内存设备环境允许彩色和单色两种位图。因此当指定的设备环境是内存设备环境时,由CreateCompatibleBitmap函数返回的位图格式不一定相同。然而为非内存设备环境创建的兼容位图通常拥有相同的颜色格式,并且使用与指定的设备环境一样的色彩调色板。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:wingdi.h;库文件:gdi32.lib。
PS:需要与CreateCompatibleDC配合使用
物理HDC 设备底层会拥有显存等资源,但是兼容DC并没有给图像像素提供内存空间,因此兼容DC总是和BITMAP配合使用,这样一来,兼容DC就利用BITMAP的图像像素数据空间给自己提供类似于显存的内存空间.
这样有很多好处,以来我们可以在加载图片后,在图片上利用DC的各种绘图功能.请看如下示例:
兼容DC在建立之初,只有1*1像素的尺寸,SelectObject选择bitmap以后才可以进行绘图.
内存DC的可见区域是简单的区域,不像物理DC可见区域可能被其他窗口覆盖而产生复杂的可见区域.由于DC的任何绘图都需要考虑在可见区域内绘图,绝对不能超出可见区域的范围.因此每个GDI绘图输出最终都需要和构成复杂可见区域的每一个巨型区域进行剪裁输出,因此物理DC的绘图效果会比兼容DC速度慢一些.这也就是我们经常用兼容DC进行双缓存输出的一个原因
HDC hdc=GetDC(hwnd);
HDC memdc=CreateCompatibleDC(hdc);
RECT rc;
BITMAP bmp;
HBITMAP holdbmp,hbmp=LoadBitmap(hInstDVBRes,MAKEINTRESOURCE(IDB_CLOCK));//从资源加载位图
holdbmp=(HBITMAP)SelectObject(memdc,hbmp);//这里把hbmp的位图选择到兼容DC memdc,之后这个兼容DC就拥有和
//hbmp同样大小的绘图区域,注意超出位图返回的GDI输出都是无效的.
GetObject(hbmp,sizeof(BITMAP),&bmp);//这里获取位图的大小信息,事实上也是兼容DC绘图输出的范围
SetRect(&rc,0,0,bmp.bmWidth,bmp.bmHeight);
DrawText(memdc,"Center Line Text" -1,&rc,DT_VCENTER|DT_SINGLELINE|DT_CENTER);//在兼容DC中间位置输出字符串
//这样以来我们就相当于把hbmp这个位图加上了文字标注,我们可以把这个增加了文字标注的位图保存起来.一个简单的图像处理基本就OK了.
SelectObject(memdc,holdbmp);//复原兼容DC数据.
DeleteDC(memdc);
***********************************************************
首先现象是这样的:
我的程序突然有一天,一个Create出来的窗口画不出东西,开了天窗!跟进去一看,是调用CBitmap::CreateBitmap失败(返回值为FALSE)。用GetLastError查到的原因是“ERROR_NOT_ENOUGH_MEMORY”。
很奇怪,这个view的代码我并没有动啊!我试着改成CBitmap::CreateCompatibleBitmap,好了!算了,不管了,就这么着吧~
谁知,过了些时日,别的窗口又开天窗了!
这次我把CreateBitmap改成CreateCompatibleBitmap,也不是每次都成功,时不时的就会创建失败!
查msdn,关于CreateBitmap API有如下这一段话:
The CreateBitmap function can be used to create color bitmaps.
However, for performance reasons applications should use CreateBitmap to create monochrome bitmaps and CreateCompatibleBitmap to create color bitmaps.
Whenever a color bitmap returned from CreateBitmap is selected into a device context, the system checks that the bitmap matches the format of the device context it is being selected into.
Because CreateCompatibleBitmap takes a device context, it returns a bitmap that has the same format as the specified device context.
Thus, subsequent calls to SelectObject are faster with a color bitmap from CreateCompatibleBitmap than with a color bitmap returned from CreateBitmap.
这段话看着挺绕,说CreateCompatibleBitmap API比CreateBitmap API的效率更高一些。那么,我的问题之一是:
CBitmap的这两个属性,是否也如API一样,CreateCompatibleBitmap比CreateBitmap的效率高??
我的问题之二:搜了一下,我的程序里,有二十多处地方(17个窗口)调用CreateBitmap,10处地方调用CreateCompatibleBitmap,且这些占用bitmap的窗口只在最后退出的时候才销毁。有经验的同仁看看,调用的地方是不是太多了?如果都换成CreateCompatibleBitmap,资源占用情况是否会有所改观?
——————————————————————————
在Create之前,都有类似如下的代码:
if(NULL != m_pMemBitmap)
{
m_pMemBitmap->DeleteObject();
delete m_pMemBitmap;
}
m_pMemBitmap = new CBitmap;
BOOL b = m_pMemBitmap->CreateCompatibleBitmap(pDC,rcClient.Width(),rcClient.Height());
感觉没有什么可泄漏的。
==================>
晕,真是这样写的话就泄露了,而且露的很厉害
if(NULL != m_pMemBitmap)
{
m_pMemBitmap->DeleteObject();
delete m_pMemBitmap;
m_pMemBitmap = NULL;//光delete, m_pMemBitmap 是不会为NULL的
}
此文摘自:http://fengqing888.blog.163.com/blog/static/3301141620091019104353119/,因为讲的实在太好了,所以就忍不住粘贴过来了。感谢这哥们
CreateCompatibleBitmap 的使用的更多相关文章
- CreateCompatibleDC 与 CreateCompatibleBitmap 小小结
通常使用CreateCompatibleBitmap时候都会用到CreateCompatibleDC.而是用CreateCompatibleDC的目的不是为CreateCompatibleBitmap ...
- CreateCompatibleDC与CreateCompatibleBitmap
函数功能:该函数创建一个与指定设备兼容的内存设备上下文环境(DC). 函数原型:HDC CreateCompatibleDC(HDC hdc): 参数: hdc:现有设备上下文环境的句柄,如果该句柄为 ...
- 依赖于设备的位图(DDB) ,CreateCompatibleBitmap用法
DDB(Device-dependent bitmap)依赖于具体设备,这主要体现在以下两个方面: DDB的颜色模式必需与输出设备相一致.例如,如果当前的显示设备是256色模式,那么DDB必然也是25 ...
- CreateCompatibleBitmap 需要注意的问题
不要使用CreateCompatibleDC得到的内存DC作为其参数,应使用真实DC,否则图片不能显示
- Windows API 函数列表 附帮助手册
所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...
- MFC双缓存技术代码
屏蔽背景刷新,在View中添加对WM_ERASEBKGND的响应,直接返回TRUE: BOOL CTEMV1View::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息 ...
- C#调用Win32API
Win32API.cs using System;using System.Drawing;using System.Runtime.InteropServices;using Lordal.Wi ...
- 【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片
本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp ...
- C++ 在Windows下截取整个屏幕 和 指定句柄窗口的屏幕
#include <windows.h> #include <stdint.h> #include <stdio.h> void ShootScreen(const ...
随机推荐
- Zabbix Agent 安装指南和 Zabbix Server 设置自动发现
Zabbix Agent分为两种模式,被动模式(Passive)和主动模式( 我们实验在node1.yulongjun.com 和node2.yulongjun.com上分别配置Zabbix Agen ...
- Kafka、RabbitMQ、RocketMQ等 消息中间件 介绍和对比
文章目录 1.前言 2.概念 2.1.MQ简介 2.2.MQ特点 2.2.1.先进先出 2.2.2.发布订阅 2.2.3.持久化 2.2.4.分布式 3.消息中间件性能究竟哪家强? 3.1.Kafka ...
- +new Date是什么意思?
转载自:http://blog.csdn.net/abxn2002/article/details/53420816 JavaScript中可以在某个元素前使用 ‘+’ 号,这个操作是将该元素转换成N ...
- 初识 MQTT——IBM
为什么 MQTT 是最适合物联网的网络协议 官方网址: http://mqtt.org/ Michael Yuan2017 年 6 月 14 日发布 WeiboGoogle+用电子邮件发送本页面 0 ...
- docker限制容器日志大小
1.新建/etc/docker/daemon.json,若有就不用新建了.添加log-dirver和log-opts参数,样例如下: # vim /etc/docker/daemon.json { & ...
- 数据类型之字符串类型与Number类型
㈠字符串类型 ⑴在JS中字符串需要使用引号引起来 ⑵使用双引号或单引号都可以,但是不要混着用 ⑶引号不能嵌套,双引号不能放双引号,单引号不能放单引号 ⑷在字符串中,可以使用“\”作为转义字符,当表示一 ...
- 油猴Tampermonkey离线安装流程(附文件)
1.下载插件插件包,然后解压(解压到你想放插件的位置,其实任意位置都可以,记住解压的位置) 链接:https://pan.baidu.com/s/1aanhsb6ZlapnzBeBRtp3Hg 提取码 ...
- P1427 小鱼的数字游戏
输入格式: 一行内输入一串整数,以0结束,以空格间隔. 输出格式: 一行内倒着输出这一串整数,以空格间隔. 直接上代码: #include<iostream> using namespac ...
- 背景(background)
背景(background) 背景家族由5个主要的背景属性组成 background-color背景颜色 background-color:colorNome(取值 如:颜色名 red green. ...
- easyui datagrid的API
本文可以当做api来使用 动态编辑用到DOM解析的话参考 http://www.w3school.com.cn/xmldom/dom_htmlcollection.asp 使用方法(Usage Exa ...