2017-07-04 60 views
0

我正在製作一個文件傳輸應用程序,並且我需要使用系統圖標,以便圖標可以匹配不同版本的Windows。但是,在你告訴我使用SHFILEINFO之前,我必須告訴你我不能。這些文件是遙遠的,所以我不能只使用SHFILEINFO對他們:/在C#中使用TreeView的系統圖標#

希望有人可以幫助:)有一個愉快的一天!

+1

uhm,這是C#還是C?您可能要更改標題或C#標記。而通過'遙遠'你的意思是在另一臺機器上? –

+1

對不起,錯字:(是的,它在另一臺計算機上(這是我自己的協議,不是標準的TCP或SMB) –

+1

沒關係,只需要一點信息:你的應用程序是基於WPF還是WindowsForms?要顯示在你的應用程序的樹形視圖內嗎? –

回答

0

所以,我把它用從CodeProject這個很好的例子工作:

public class IconReader 
{ 
    /// <summary> 
    /// Options to specify the size of icons to return. 
    /// </summary> 
    public enum IconSize 
    { 
     /// <summary> 
     /// Specify large icon - 32 pixels by 32 pixels. 
     /// </summary> 
     Large = 0, 
     /// <summary> 
     /// Specify small icon - 16 pixels by 16 pixels. 
     /// </summary> 
     Small = 1 
    } 

    /// <summary> 
    /// Options to specify whether folders should be in the open or closed state. 
    /// </summary> 
    public enum FolderType 
    { 
     /// <summary> 
     /// Specify open folder. 
     /// </summary> 
     Open = 0, 
     /// <summary> 
     /// Specify closed folder. 
     /// </summary> 
     Closed = 1 
    } 

    /// <summary> 
    /// Returns an icon for a given file - indicated by the name parameter. 
    /// </summary> 
    /// <param name="name">Pathname for file.</param> 
    /// <param name="size">Large or small</param> 
    /// <param name="linkOverlay">Whether to include the link icon</param> 
    /// <returns>System.Drawing.Icon</returns> 
    public static System.Drawing.Icon GetFileIcon(string name, IconSize size, bool linkOverlay) 
    { 
     Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); 
     uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; 

     if (true == linkOverlay) flags += Shell32.SHGFI_LINKOVERLAY; 

     /* Check the size specified for return. */ 
     if (IconSize.Small == size) 
     { 
      flags += Shell32.SHGFI_SMALLICON; 
     } 
     else 
     { 
      flags += Shell32.SHGFI_LARGEICON; 
     } 

     Shell32.SHGetFileInfo(name, 
      Shell32.FILE_ATTRIBUTE_NORMAL, 
      ref shfi, 
      (uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi), 
      flags); 

     // Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly 
     System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); 
     User32.DestroyIcon(shfi.hIcon);  // Cleanup 
     return icon; 
    } 

    /// <summary> 
    /// Used to access system folder icons. 
    /// </summary> 
    /// <param name="size">Specify large or small icons.</param> 
    /// <param name="folderType">Specify open or closed FolderType.</param> 
    /// <returns>System.Drawing.Icon</returns> 
    public static System.Drawing.Icon GetFolderIcon(IconSize size, FolderType folderType) 
    { 
     // Need to add size check, although errors generated at present! 
     uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; 

     if (FolderType.Open == folderType) 
     { 
      flags += Shell32.SHGFI_OPENICON; 
     } 

     if (IconSize.Small == size) 
     { 
      flags += Shell32.SHGFI_SMALLICON; 
     } 
     else 
     { 
      flags += Shell32.SHGFI_LARGEICON; 
     } 

     // Get the folder icon 
     Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); 
     Shell32.SHGetFileInfo(@"Folder", 
      Shell32.FILE_ATTRIBUTE_DIRECTORY, 
      ref shfi, 
      (uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi), 
      flags); 

     System.Drawing.Icon.FromHandle(shfi.hIcon); // Load the icon from an HICON handle 

     // Now clone the icon, so that it can be successfully stored in an ImageList 
     System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); 

     User32.DestroyIcon(shfi.hIcon);  // Cleanup 
     return icon; 
    } 

    public static System.Drawing.Icon GetDriveIcon(IconSize size, FolderType folderType) 
    { 
     // Need to add size check, although errors generated at present! 
     uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; 

     if (FolderType.Open == folderType) 
     { 
      flags += Shell32.SHGFI_OPENICON; 
     } 

     if (IconSize.Small == size) 
     { 
      flags += Shell32.SHGFI_SMALLICON; 
     } 
     else 
     { 
      flags += Shell32.SHGFI_LARGEICON; 
     } 

     // Get the folder icon 
     Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); 
     Shell32.SHGetFileInfo(null, 
      Shell32.FILE_ATTRIBUTE_DIRECTORY, 
      ref shfi, 
      (uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi), 
      flags); 

     System.Drawing.Icon.FromHandle(shfi.hIcon); // Load the icon from an HICON handle 

     // Now clone the icon, so that it can be successfully stored in an ImageList 
     System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); 

     User32.DestroyIcon(shfi.hIcon);  // Cleanup 
     return icon; 
    } 
} 

/// <summary> 
/// Wraps necessary Shell32.dll structures and functions required to retrieve Icon Handles using SHGetFileInfo. Code 
/// courtesy of MSDN Cold Rooster Consulting case study. 
/// </summary> 
/// 

// This code has been left largely untouched from that in the CRC example. The main changes have been moving 
// the icon reading code over to the IconReader type. 
public class Shell32 
{ 

    public const int MAX_PATH = 256; 
    [StructLayout(LayoutKind.Sequential)] 
    public struct SHITEMID 
    { 
     public ushort cb; 
     [MarshalAs(UnmanagedType.LPArray)] 
     public byte[] abID; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct ITEMIDLIST 
    { 
     public SHITEMID mkid; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct BROWSEINFO 
    { 
     public IntPtr hwndOwner; 
     public IntPtr pidlRoot; 
     public IntPtr pszDisplayName; 
     [MarshalAs(UnmanagedType.LPTStr)] 
     public string lpszTitle; 
     public uint ulFlags; 
     public IntPtr lpfn; 
     public int lParam; 
     public IntPtr iImage; 
    } 

    // Browsing for directory. 
    public const uint BIF_RETURNONLYFSDIRS = 0x0001; 
    public const uint BIF_DONTGOBELOWDOMAIN = 0x0002; 
    public const uint BIF_STATUSTEXT = 0x0004; 
    public const uint BIF_RETURNFSANCESTORS = 0x0008; 
    public const uint BIF_EDITBOX = 0x0010; 
    public const uint BIF_VALIDATE = 0x0020; 
    public const uint BIF_NEWDIALOGSTYLE = 0x0040; 
    public const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX); 
    public const uint BIF_BROWSEINCLUDEURLS = 0x0080; 
    public const uint BIF_BROWSEFORCOMPUTER = 0x1000; 
    public const uint BIF_BROWSEFORPRINTER = 0x2000; 
    public const uint BIF_BROWSEINCLUDEFILES = 0x4000; 
    public const uint BIF_SHAREABLE = 0x8000; 

    [StructLayout(LayoutKind.Sequential)] 
    public struct SHFILEINFO 
    { 
     public const int NAMESIZE = 80; 
     public IntPtr hIcon; 
     public int iIcon; 
     public uint dwAttributes; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] 
     public string szDisplayName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)] 
     public string szTypeName; 
    }; 

    public const uint SHGFI_ICON = 0x000000100;  // get icon 
    public const uint SHGFI_DISPLAYNAME = 0x000000200;  // get display name 
    public const uint SHGFI_TYPENAME = 0x000000400;  // get type name 
    public const uint SHGFI_ATTRIBUTES = 0x000000800;  // get attributes 
    public const uint SHGFI_ICONLOCATION = 0x000001000;  // get icon location 
    public const uint SHGFI_EXETYPE = 0x000002000;  // return exe type 
    public const uint SHGFI_SYSICONINDEX = 0x000004000;  // get system icon index 
    public const uint SHGFI_LINKOVERLAY = 0x000008000;  // put a link overlay on icon 
    public const uint SHGFI_SELECTED = 0x000010000;  // show icon in selected state 
    public const uint SHGFI_ATTR_SPECIFIED = 0x000020000;  // get only specified attributes 
    public const uint SHGFI_LARGEICON = 0x000000000;  // get large icon 
    public const uint SHGFI_SMALLICON = 0x000000001;  // get small icon 
    public const uint SHGFI_OPENICON = 0x000000002;  // get open icon 
    public const uint SHGFI_SHELLICONSIZE = 0x000000004;  // get shell size icon 
    public const uint SHGFI_PIDL = 0x000000008;  // pszPath is a pidl 
    public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;  // use passed dwFileAttribute 
    public const uint SHGFI_ADDOVERLAYS = 0x000000020;  // apply the appropriate overlays 
    public const uint SHGFI_OVERLAYINDEX = 0x000000040;  // Get the index of the overlay 

    public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; 
    public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; 

    [DllImport("Shell32.dll")] 
    public static extern IntPtr SHGetFileInfo(
     string pszPath, 
     uint dwFileAttributes, 
     ref SHFILEINFO psfi, 
     uint cbFileInfo, 
     uint uFlags 
     ); 
} 

/// <summary> 
/// Wraps necessary functions imported from User32.dll. Code courtesy of MSDN Cold Rooster Consulting example. 
/// </summary> 
public class User32 
{ 
    /// <summary> 
    /// Provides access to function required to delete handle. This method is used internally 
    /// and is not required to be called separately. 
    /// </summary> 
    /// <param name="hIcon">Pointer to icon handle.</param> 
    /// <returns>N/A</returns> 
    [DllImport("User32.dll")] 
    public static extern int DestroyIcon(IntPtr hIcon); 
} 

但是,還有一個問題:圖標看起來太可怕了!這裏有一個截圖: Screenshot from app

做一個人知道我可以解決這個問題嗎?