STM_SETIMAGE引起的gdi内存泄露

2/10/2017来源:ASP.NET技巧人气:381

STM_SETIMAGE引起的gdi内存泄露

最近给程序加了一个动画功能后,发现程序会引起及其严重的内存泄露,找了半天发现是调用STM_SETIMAGE引起的。素以在此将使用STM_SETIMAGE遇到的问题记录一下。 我的程序将动画的所有帧提前加载后用定时器循环用STM_SETIMAGE把位图句柄发送到窗口显示,发现没显示一次就泄露好几M内存,而且动画切换的速度是很快的,所以不一会就开始bad_alloc了。 为什么每发送一次STM_SETIMAGE就泄露呢?查看msdn关于STM_SETIMAGE的说明,最后有一段描述,原文不贴了,翻译过来大概就是这样: 在xp下(xp以上应该也是),如果显示的位图有非零的透明通道的像素(我自己翻译的),控件就会复制一份位图,这个复制的位图的句柄将在下次调用STM_SETIMAGE时作为返回值返回,调用者有责任释放这个位图,不然就会内存泄露。 解决方法: 我不知道微软内部用了怎样的实现才会导致有这样奇葩的使用方式,而且目前我也不知道怎样判断什么叫做“有非零的透明通道的像素”,所以只能通过判断返回的句柄,如果创建static控件后第一次使用STM_SETIMAGE,会返回NULL,如果内部没有复制位图,那么下次调用STM_SETIMAGE的返回值就是上次传入的位图句柄,如果内部有复制位图,那么下次调用STM_SETIMAGE的返回值就是static控件内部创建的位图句柄,需要用DeleteObject删除位图,释放内存。