GDI绘图(一)

来源:互联网 发布:淘宝代练lol封号赔偿 编辑:程序博客网 时间:2024/05/17 15:40

最近在做一个聊天界面,使用GDI绘制。

基本的思路还是一样,首先建立一个兼容DC,选入适当大小的内存位图,然后在兼容DC上绘制你想要的图像,最后复制到设备DC上。这是常规的防止闪屏的一种方法!

绘制过程比较顺利,但是调试的时候发现内存泄露的比较严重。查看任务管理器,可以看见内存不断的增长,同时GDI对象数目不断增多。

        总结一下

这是第一次关注GDI内存泄露问题,以前总认为我建的只是局部变量,当函数调用完毕,GDI对象应该自己调用析构函数释放内存。可是很显然,事实没如我所愿。

GetDC

After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released.ReleaseDC must be called from the same thread that calledGetDC. The number of DCs is limited only by available memory. 

一般来说,GetDC()之后,一定要调用ReleaseDC()

SelectObject

This function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.An application cannot select a bitmap into more than one DC at a time.

一开始不知道为什么一定要把GDI对象选出,觉得我用完了就用完了啊,反正我再进来我再选我要的GDI对象。但是 ,当你调用DeleteObject(),有这么一句话:

Do not delete a drawing object (pen or brush) while it is still selected into a DC.

也就是说你不把对象选出DC就进行删除,会删除失败,DeleteObject返回False。


对于GDI对象的释放,总结起来就是这么几点:

1 Create出来的DC,DeleteDC()释放,GetDC(),ReleaseDC()释放。

2 欲删除一个GDI对象,必须将其从DC中选出,DeleteObject()才会成功!

3有时,闪烁的原因是因为当重画时,父窗体没有剪切其子窗体区域。这样的结果导致,整个父窗口内容被重画,而子窗体又被显示在了上面(造成闪烁)。这个可以通过在父窗体上设置WS_CLIPCHILDREN 来解决。当这个标志被设置时,被子窗体占据的任何区域将会被排除在更新区域外。因此,即使你尝试在子窗体所在的位置上绘制(父窗口的内容),BeginPaint中的剪切区域也会阻止其绘制效果。  



原创粉丝点击