删除shell32.dll创建的gdi对象->;ExtractIconEx
本文关键字:gt ExtractIconEx 对象 gdi shell32 dll 创建 删除 | 更新日期: 2023-09-27 18:25:44
我正在使用shell32.dll的ExtractIconEx来收集特定文件夹中所有文件的图标。
它运行得很好,但有一个例外:创建了数百个GDI对象,它们再也不会消失。
包含代码
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern int ExtractIconEx(string stExeFileName, int nIconIndex, ref IntPtr phiconLarge, ref IntPtr phiconSmall, int nIcons);
使用代码
foreach (string filename in ListOfFilenames)
{
IntPtr iconLarge = new IntPtr();
IntPtr iconSmall = new IntPtr();
ExtractIconEx(filename, 1 , ref iconLarge, ref iconSmall, 1);
Image doSomethingWithThis = Icon.FromHandle(iconSmall).ToBitmap();
.....
}
我设法再现了填充IntPtr变量的ExtractIconEx的调用导致了大量GDI对象(或者更多的是填充的iconLarge和iconSmall)。
我用不同的变体尝试过几次(比如interops中的ObjectDelete,…),但似乎都不起作用,或者它还以某种方式消除了doSomethingWithThis图像,从而破坏了程序。
因此,问题是如何减少GDI对象的不必要数量?(有趣的是,该文件夹中总共有5个文件!)
来自文档:
必须通过调用DestroyIcon函数销毁ExtractIconEx提取的所有图标。
因此,每次调用ExtractIconEx
时,都会得到两个图标句柄。用完它们后,请致电DestroyIcon
。
FWIW,我会将图标句柄参数声明为out
,以便简单地调用该函数。
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern uint ExtractIconEx(string stExeFileName, int nIconIndex,
out IntPtr phiconLarge, out IntPtr phiconSmall, int nIcons);
然后你可以调用这样的函数:
IntPtr iconLarge;
IntPtr iconSmall;
uint retval = ExtractIconEx(filename, 1 , out iconLarge, out iconSmall, 1);
你也应该注意回报值。