2010-12-22 42 views
4

我試圖提取縮略圖或圖標,如果從Windows資源管理器等文件或文件夾中找不到縮略圖。我使用的是IShellItemImageFactory,當縮略圖出現時,它可以很好地工作。但是,如果文件沒有縮略圖,則該方法返回的圖標具有黑色背景。從c文件中提取縮略圖和圖標#

可疑的原因是當我呼叫Bitmap.FromHbitmap將hbitmap轉換爲位圖時,透明度丟失。是否可以轉換而不會失去透明度?我甚至不確定這是否是問題。唯一的參考,我能找到是question about IShellItemImageFactory評論它說,

「的API有時會返回使用預乘alpha和使用的正α 有時那些位圖 」

是有沒有辦法讓圖標沒有黑色背景,或者我應該堅持Icon.ExtractAssociatedIcon時沒有縮略圖?

回答

3

我用下面的代碼,不知道這是否透明背景的支持,但你可以試試看:

private const uint SHGFI_ICON   = 0x100; 
private const uint SHGFI_LARGEICON  = 0x0; 
private const uint SHGFI_SMALLICON  = 0x1; 
private const uint SHGFI_DISPLAYNAME = 0x00000200; 
private const uint SHGFI_TYPENAME  = 0x400; 

public static Icon GetSmallFileIcon(this FileInfo file) 
{ 
    if (file.Exists) 
    { 
     SHFILEINFO shFileInfo = new SHFILEINFO(); 
     SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_SMALLICON); 

     return Icon.FromHandle(shFileInfo.hIcon); 
    } 
    else return SystemIcons.WinLogo; 
} 

public static Icon GetSmallFileIcon(string fileName) 
{ 
    return GetSmallFileIcon(new FileInfo(fileName)); 
} 

public static Icon GetLargeFileIcon(this FileInfo file) 
{ 
    if (file.Exists) 
    { 
     SHFILEINFO shFileInfo = new SHFILEINFO(); 
     SHGetFileInfo(file.FullName, 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_LARGEICON); 

     return Icon.FromHandle(shFileInfo.hIcon); 
    } 
    else return SystemIcons.WinLogo; 
} 

public static Icon GetLargeFileIcon(string fileName) 
{ 
    return GetLargeFileIcon(new FileInfo(fileName)); 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct SHFILEINFO 
{ 
    public SHFILEINFO(bool b) 
    { 
     hIcon = IntPtr.Zero; iIcon = IntPtr.Zero; dwAttributes = 0; szDisplayName = ""; szTypeName = ""; 
    } 

    public IntPtr hIcon; 
    public IntPtr iIcon; 
    public uint dwAttributes; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string szDisplayName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
    public string szTypeName; 
}; 


[DllImport("shell32.dll")] 
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 
+0

感謝您的摘錄。其實我知道SHGetFileInfo函數。我只是想避免檢查縮略圖是否可用,如果不是提取圖標。 – Giorgi 2010-12-22 16:02:36

1

位圖返回了阿爾法。它是32位,最後8位是阿爾法。我不確定在調用Bitmap.FromHbitmap時會發生什麼情況,但是您應該知道,即使alpha被正確複製(可能是),您以後也可能不會使用它。如果你忽略了alpha,你會看到一個黑盒子。