2014-10-06 63 views
0

我正在使用Shell32.dll的ExtractIconEx来收集特定文件夹中所有文件的图标。删除由shell32.dll创建的gdi对象 - > 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(); 
    ..... 
} 

我设法重现ExtractIconEx的其中填充的IntPtr变量调用导致GDI对象的质量(或多个填充iconLarge和iconSmall是这里的原因)。

我试过了几次不同的变体(比如ObjectDelete来自interops,...),但没有任何东西似乎工作,或者它以某种方式销毁程序也消除了doSomethingWithThis图像。

所以问题ehre是可以做些什么来减少不必要的GDI对象数量? (有趣的部分有其共有的该文件夹中的5个文件!)

回答

1

documentation

您必须通过调用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); 

你应该返回值的留意也。

+0

从同一个DLL的destroyicon? – Thomas 2014-10-06 11:56:01

+0

再次,您可以从文档中找到此信息:http://msdn.microsoft.com/en-gb/library/windows/desktop/ms648063(v=vs.85).aspx查看文档的requirements部分找到包含该函数的DLL。你可以从pinvoke.net获得一个函数声明:http://www.pinvoke.net/default.aspx/user32/destroyicon.html?diff=y – 2014-10-06 11:57:26

+0

ok找到它。问题tehre虽然:这是否也应删除:doSomethingWithThis? – Thomas 2014-10-06 12:04:17