我发现,在FillRgn()Windows GDI API函数之后,这个函数中使用的GDI对象以某种方式“卡住”在内部系统映射中的某个地方,并且不会被正确删除:调用对象的DeleteObject()成功返回,进程的GDI对象数量不会减less。 这里是代码:
void gditest() { HBRUSH h = CreateSolidBrush(RGB(255,237,5)); HRGN rgn = CreateRectRgn(0,100,0); FillRgn(g_DC,rgn,h); int before = GetGuiResources(GetCurrentProcess(),GR_GDIOBJECTS); SelectObject(g_DC,GetStockObject(WHITE_BRUSH)); int rs = DeleteObject( h ); if ( !rs ) throw; int after = GetGuiResources(GetCurrentProcess(),GR_GDIOBJECTS); }
该代码演示了删除HBRUSH句柄variables之前和之后的''相等后; g_DC是HDC的主窗口。
如何删除'h'以使GDI对象的数量递减?
什么是一个很好的方法来打包Windows XP的GTK Python应用程序?
无法在Windows 10上设置Apache Spark 2.1.1
检测Redis的主数据库故障转移和自动切换奴隶主?
它是安全的/定义为假设一个Windows伪句柄的值?
有什么办法来创build一个Shorcut桌面到Node.js(npm)应用程序?
如何通过ProcessID查找进程?
阅读特定的Windows事件日志事件
Windows上的Python 3.4中的Tkinter不会将内部剪贴板数据发布到退出时的Windows剪贴板上
searchWindows 7中的PHP文件的内容
win32com.client.Dispatch(“WScript.Shell”)到底是什么?
当第一次调用SelectObject()时,必须记住返回值,并在完成DC之后再次选择它。 另外,您必须删除所有创建的GDI对象。
void gditest() { HBRUSH h = CreateSolidBrush(RGB(255,GR_GDIOBJECTS); HBRUSH oldBrush = SelectObject(g_DC,GetStockObject(WHITE_BRUSH)); SelectObject( g_DC,oldBrush ); int rs = DeleteObject( h ); if ( !rs ) throw; DeleteObject( rgn ); int after = GetGuiResources(GetCurrentProcess(),GR_GDIOBJECTS); }
注意:
由GetStockObject()检索的对象可以被删除,但是他们不需要。
GDI缓存刷子和区域资源,或者它是一个错误。 删除画笔或区域后,计数不会下降。 在Windows 7上测试。这里是我的快速和繁琐的repro代码:
#include <cassert> #include <iostream> #include <windows.h> void PrintGdiCount() { std::cout << ::GetGuiResources(::GetCurrentProcess(),GR_GDIOBJECTS) << std::endl; } int main() { PrintGdiCount(); ::GdiSetBatchLimit(1); // disable batching HDC hdcScreen = ::GetDC(NULL); PrintGdiCount(); HDC hdcMemory = ::CreateCompatibleDC(hdcScreen); PrintGdiCount(); HBITMAP hbmpMemory = ::CreateCompatibleBitmap(hdcScreen,100); PrintGdiCount(); HBITMAP hbmpOld = reinterpret_cast<HBITMAP>(::SelectObject(hdcMemory,hbmpMemory)); PrintGdiCount(); HBRUSH hbrush = ::CreateSolidBrush(RGB(255,127,32)); PrintGdiCount(); HRGN hrgn = ::CreateRectRgn(0,50,50); PrintGdiCount(); // ::FillRgn(hdcMemory,hrgn,hbrush); // doesn't affect GDI count PrintGdiCount(); BOOL bDeletedBrush = ::DeleteObject(hbrush); assert(bDeletedBrush); PrintGdiCount(); // expected decrement,but it doesn't ::DeleteObject(hrgn); PrintGdiCount(); // expected decrement,but it doesn't ::SelectObject(hdcMemory,hbmpOld); ::DeleteObject(hbmpMemory); PrintGdiCount(); ::DeleteDC(hdcMemory); PrintGdiCount(); ::ReleaseDC(NULL,hdcScreen); PrintGdiCount(); // result is 2 higher than initial count return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。