gdi使用经验分享

在windows系列上做编程,gdi是一个很重要的技术点,有很多程序在运行多次后出现异常,除了众所周知的内存泄露以外,gdi资源泄露也是一个很直接的原因.今天就把我自己在编程中总结的一些经验给大家分享,欢迎高手补充.
1.Create出来的gdi对象,一定要用DeleteObject来释放,释放顺序是先Create的后释放,后Create的先释放.
这里的Create指的是以它为开头的gdi函数,比如,CreateDIBitmap,CreateFont等等,最后都要调用DeleteObject来释放.

2.Create出来的dc要用DeleteDC来释放,Get到的要用ReleaseDC释放.

3.确保释放DC的时候DC中的各gdi对象都不是你自己创建的;确保个gdi对象在释放的时候不被任何dc选中使用.
假如我们要使用gdi函数画图,正确的步骤应该如下:
a.创建一个内存兼容dc(CreateCompatibleDC)
b.创建一个内存兼容bitmap(CreateCompatibleBitmap)
c.关联创建的内存兼容dc和bitmap(SelectObject)
d.画图
e.BitBlt到目的dc上
f.断开内存兼容dc和bitmap关联(SelectObject)
g.销毁内存兼容bitmap
h.销毁内存兼容dc
由于SelectObject在选入一个新的gdi对象的时候会返回一个原来的gdi对象(假如成功的话),所以需要在步骤c的时候保存返回值,在步骤f的时候当作入口参数使用.还有,步骤g和步骤h实际上顺序可以随意,因为他们两个此刻已经没有关系了,但是为了结构清晰,我建议按照"先Create的后释放,后Create的先释放"的原则进行.
关于步骤f,可能会有争议,因为即使省略这一步,步骤g和步骤h看起来照样可以返回一个成功的值.但实际上可能并没有执行成功,至少boundschecker会报告有错,错误信息大致是说,在释放dc的时候还包含有非默认的gdi对象,在释放gdi对象的时候又说这个gdi对象还被一个dc在使用.所以,我建议保留步骤f.

4.关于98下使用CreateCompatibleBitmap
按照msdn的说法,创建出来的size不能超过16m.实际情况是这样吗?非也~!从我自己做的测试结果来看(win98se-sc),这个值在2044*2043和2044*2044之间,然而,后来在另外一个98系统上这个值也不行,后来我干脆把上限给成了2000*2000.很幸运,到现在还没有出问题,但我不能保证这个数字就是正确的.还有一点,假如宽或高有一个超过32768,哪怕另外一个值是1,也会创建失败,有兴趣的可以自己做个测试.如果要想保证这个函数在98下永远成功,可以试试下面的代码:
float factor = 10.f;
while(!bitmap.CreateCompatibleBitmap(&dc ,nWidth*factor ,nHeight*factor))
{
   factor -= 0.01f;  
}
这样至少可以保证宽和高是成比例的:)

5.关于在打印机上使用BitBlt
有时候在内存兼容dc里面已经做好图了,但在使用BitBlt的时候却会失败.这个时候,首先确认创建的内存兼容dc和bitmap是不是使用打印机的dc,如果确认无误,还是执行BitBlt失败,那80%可能是内存兼容bitmap太大了,请按如下方法再试试:
创建另外一个内存兼容dc2和一个比较小的内存兼容biimap2,大概是1000*1000吧,我是这样用的:)然后把dc里面的内容分成块(1000*1000),把每一块BitBlt到dc2上面,再从dc2里面BitBlt到打印dc上.有人可能会有这样的疑问:那为什么不直接把dc里面的内容分几次BitBlt到打印机上呢?有区别吗?答案是肯定的,如果dc里面的bitmap太大,哪怕你想BitBlt一个10*10的区域到打印机上都会失败.

<完>

 from:http://blog.csdn.net/bobob/article/details/565188

时间: 2024-11-17 13:37:10

gdi使用经验分享的相关文章

photoshop七个省时实用工具使用经验分享

给各位photoshop软件的使用者们来详细的解析分享一下七个省时实用工具的使用经验. 分享一览: 这七个工具分别是:透视裁切,快速蒙版,调整边缘,内容识别,消失点滤镜,透视裁切,图层蒙版.不会使用的一起来简单了解一下如何使用.   1.快速蒙版           2.调整边缘         3.图层蒙版       4.图层混合     5.内容识别         6.消失点滤镜       7.透视裁切       好了,以上的信息就是小编给各位photoshop的这一款软件的使用者们

JS中的Replace方法使用经验分享

  本文给大家分享的是我们在使用javascript中的replace方法的时候需要注意的一个事项,我就是没有注意到,才被这个bug烦了好久,这里记录下来,有需要的小伙伴可以参考下. 最近查一个bug,原因是JS中的Replace方法造成的,当将一个字符串中有处需要替换时,一般会用到JS中的Replace方法,Replace方法的第一个参数如果是传的字符串,只会替换第一处.代码如下: 复制代码 代码如下: var str = "0CEA65D5-DB8E-4876-A6F8-C88AC7F0E1

网站设计颜色的使用经验分享

颜色的使用,这似乎是个显而易见的问题,但是由于许多人在设计网站时都忘记了这一点,因此还是要强调一下:当选择网站的颜色时,要时刻牢记"不要过度设计"这条法则.同时,还要时刻考虑品牌和主要用户.在进行颜色选择时,也需要把主要用户放在首位.如果你了解了用户的所有情况,就能使设计完全满足他们的要求. 为了让大家更加清楚明了,小编就此举例说明.例如,如果是销售成年男性用的运动用品和器材,就不应该选择粉色.黄色和蓝色等清淡的色彩,因为它们更适合婴儿用品网站.你应该借助颜色选择和其他的设计元素让用户

JUnit测试框架的使用经验分享

1.学习Junit框架的使用 可通过以下两个示例进行学习. A.Junit使用方法示例1 1)把Junit引入当前项目库中 新建一个 Java 工程-coolJUnit,打开项目coolJUnit 的属性页 -> 选择"Java Build Path"子选项 -> 点选"Add Library-"按钮 -> 在弹出的"Add Library"对话框中选择 JUnit,并在下一页中选择版本 Junit 4 后点击"Fin

Google Protocol Buffer使用经验分享(一) C++动态消息与静态消息的博弈

写在前面 相信正在浏览这篇文章的同学,一定已经对PB(Protocol buffer)有所了解,所以这里不罗嗦何为PB了. 我自己从去年年底开始对PB的使用逐渐有一些了解,直到在搜索排序框架(iRank)的重构中尝试应用PB,希望能在"数据结构灵活增删改"和"高效的数据传输反序列化"之间求得平衡. 在这过程之中,对PB 动态消息和静态消息的C++使用方式进行了一些调研,对 动态消息 和 静态消息 的优缺点有了进一步了解.通过阅读源代码和实际应用,总结出一些经验,将

有没有阿里云消息队列使用经验分享?

问题描述 在阿里云论坛上看到一个帖子,http://bbs.aliyun.com/read.php?tid=145878,发现阿里云推出来云消息服务队列,加入群拿到文档,简单试用了一下,貌似跟aws的消息队列服务很像,不知道稳定性怎么样,有谁试用过吗? 解决方案

JS中的Replace方法使用经验分享_javascript技巧

最近查一个bug,原因是JS中的Replace方法造成的,当将一个字符串中有处需要替换时,一般会用到JS中的Replace方法,Replace方法的第一个参数如果是传的字符串,只会替换第一处.代码如下: 复制代码 代码如下: var str = "0CEA65D5-DB8E-4876-A6F8-C88AC7F0E185,E846C244-8A19-4374-879B-0B1DC08D1747,6CB3EBA4-1E22-4E4D-8800-AE31130B6F5D"; alert(st

Yii 2.0自带的验证码使用经验分享

前言 官网自带的前台验证码中在view下有个contact.php的 文件,大家没事可以先看看它是怎么调验证码 闲话不说,感兴趣的朋友们下面来一起看看详细的介绍: 使用方法如下: 第一步: 因为我本身建立了modules,所以我在我的modules下新建了models的目录(默认gii生成modules是没有这个目录的),我取名为LoginForm.php 代码 如下: namespace app\modules\XXX\models;//这个你们写自己的命名空间,我以我的modules项目路径

photoshop一个重要的工具钢笔工具使用经验

给各位photoshop软件的使用者们来详细的解析分享一下一个重要的工具钢笔工具使用经验. 分享一览: 钢笔工具(快捷键P),钢笔工具在美工技术里用处极多,所以应当是学习的重中之重.   好了,以上的信息就是小编给各位photoshop的这一款软件的使用者们带来的详细的一个重要的工具钢笔工具使用经验分享的全部内容了,希望小编上面分享的内容能给大家带去有用的帮助.