2010-12-22 76 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,你会看到一个黑盒子。