SHGetFileInfo : Setting SHGFI_OPENICON has no affect

1

I have a TreeView that is being used to represent my file system, and am using the SHGetFileInfo function to display the system icons for each path of the tree. I'm now trying to have the folder icon change to an open folder icon when the TreeViewItem is expanded. However, enabling this seems to have no affect, the icon is the same whether SHGFI_OPENICON is set or not.

It's not a bind issue as hard coding it to always use SHGFI_OPENICON has the same results.

Here is the convertor I am using.

public class GetSystemIconConvertor : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string path = values[0].ToString();
        bool isExpanded = (bool)values[1];
        return GetIcon(path, isExpanded);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public static ImageSource GetIcon(string path, bool _isOpen)
    {
        uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON;
        if (_isOpen)
            flags |= SHGFI_OPENICON;

        uint attributes = FILE_ATTRIBUTE_NORMAL;
        if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
            attributes |= FILE_ATTRIBUTE_DIRECTORY;

        SHFILEINFO shfi;
        if (SHGetFileInfo(path, attributes, out shfi, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags) != 0)
        {
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }
        return null;
    }

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

    [DllImport("shell32")]
    private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);

    const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
    const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
    const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
    const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
    const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
    const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
    const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
    const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
    const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
    const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
    const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
    const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
    const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
    const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
    const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;

    const uint SHGFI_ICON = 0x000000100;     // get icon
    const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
    const uint SHGFI_TYPENAME = 0x000000400;     // get type name
    const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
    const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
    const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
    const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
    const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
    const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
    const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
    const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
    const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
    const uint SHGFI_OPENICON = 0x000000002;     // get open icon
    const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
    const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
    const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute
}
c#
wpf
windows-shell
asked on Stack Overflow May 25, 2014 by wforl

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0