2014-10-06 65 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