protected static ShellDll.ShellAPI.SFGAO shGetFileAttribute(PIDL pidl, ShellDll.ShellAPI.SFGAO lookup) { ShellAPI.SHFILEINFO shfi = new ShellAPI.SHFILEINFO(); shfi.dwAttributes = ShellAPI.SFGAO.READONLY | ShellAPI.SFGAO.HIDDEN | ShellAPI.SFGAO.BROWSABLE | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.HASSUBFOLDER; ShellAPI.SHGFI dwFlag = ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ATTRIBUTES | ShellAPI.SHGFI.ATTR_SPECIFIED | ShellAPI.SHGFI.USEFILEATTRIBUTES; ShellAPI.FILE_ATTRIBUTE dwAttr = 0; int cbFileInfo = Marshal.SizeOf(shfi.GetType()); IntPtr retPtr = ShellAPI.SHGetFileInfo(pidl.Ptr, dwAttr, ref shfi, cbFileInfo, dwFlag); if (retPtr.ToInt32() != ShellAPI.S_OK && retPtr.ToInt32() != 1) { Marshal.ThrowExceptionForHR(retPtr.ToInt32()); } return(shfi.dwAttributes); }
public static extern IntPtr SHGetFileInfo(IntPtr ppidl, ShellAPI.FILE_ATTRIBUTE dwFileAttributes, ref ShellAPI.SHFILEINFO sfi, int cbFileInfo, ShellAPI.SHGFI uFlags);
internal static void SetIconIndex(ShellItem item, int index, bool SelectedIcon) { bool HasOverlay = false; //true if it's an overlay int rVal = 0; //The returned Index ShellAPI.SHGFI dwflag = ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ICON; ShellAPI.FILE_ATTRIBUTE dwAttr = 0; //build Key into HashTable for this Item int Key = index * 256; if (item.IsLink) { Key = Key | 1; dwflag = dwflag | ShellAPI.SHGFI.LINKOVERLAY; HasOverlay = true; } if (item.IsShared) { Key = Key | 2; dwflag = dwflag | ShellAPI.SHGFI.ADDOVERLAYS; HasOverlay = true; } if (SelectedIcon) { Key = Key | 4; dwflag = dwflag | ShellAPI.SHGFI.OPENICON; HasOverlay = true; //not really an overlay, but handled the same } if (imageTable.ContainsKey(Key)) { rVal = (int)imageTable[Key]; } else if (!HasOverlay && !item.IsHidden) //for non-overlay icons, we already have { rVal = (int)System.Math.Floor((double)Key / 256); // the right index -- put in table imageTable[Key] = rVal; } else //don't have iconindex for an overlay, get it. { if (item.IsFileSystem & !item.IsDisk & !item.IsFolder) { dwflag = dwflag | ShellAPI.SHGFI.USEFILEATTRIBUTES; dwAttr = dwAttr | ShellAPI.FILE_ATTRIBUTE.NORMAL; } PIDL pidlFull = item.PIDLFull; ShellAPI.SHFILEINFO shfiSmall = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiSmall, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.SMALLICON); ShellAPI.SHFILEINFO shfiLarge = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiLarge, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.LARGEICON); Marshal.FreeCoTaskMem(pidlFull.Ptr); lock (imageTable) { rVal = ShellAPI.ImageList_ReplaceIcon(smallImageListHandle, -1, shfiSmall.hIcon); ShellAPI.ImageList_ReplaceIcon(largeImageListHandle, -1, shfiLarge.hIcon); } ShellAPI.DestroyIcon(shfiSmall.hIcon); ShellAPI.DestroyIcon(shfiLarge.hIcon); imageTable[Key] = rVal; } if (SelectedIcon) { item.SelectedImageIndex = rVal; } else { item.ImageIndex = rVal; } }
/// <summary> /// Returns the icon index for the given ShellItem. /// </summary> /// <param name="item"> /// ShellItem for which the icon index is calculated. /// </param> /// <param name="selected"> /// True if the item is selected, false otherwise. /// </param> public int GetIconIndex(ShellItem item, bool selected) { bool hasOverlay = false; int index = item.ImageIndex; int res; ShellAPI.FILE_ATTRIBUTE dwFileAttrib = 0; ShellAPI.SHGFI uFlags = ShellAPI.SHGFI.ICON | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.SYSICONINDEX; int key = item.ImageIndex << 8; // check for overlays if (item.IsLink) { key = key | 1; uFlags = uFlags | ShellAPI.SHGFI.LINKOVERLAY; hasOverlay = true; } if (item.IsShared) { key = key | 2; uFlags = uFlags | ShellAPI.SHGFI.ADDOVERLAYS; hasOverlay = true; } // not really an overlay, but handled the same if (selected) { key = key | 4; uFlags = uFlags | ShellAPI.SHGFI.OPENICON; hasOverlay = true; } if (imageTable.ContainsKey(key)) { res = (int)imageTable[key]; } // for non-overlay icons we already have the index else if (!hasOverlay && !item.IsHidden) { res = index; imageTable[key] = index; } // don't have icon index for an overlay else { if (item.IsFileSystem && !item.IsDisk && !item.IsFolder) { uFlags |= ShellAPI.SHGFI.USEFILEATTRIBUTES; dwFileAttrib = ShellAPI.FILE_ATTRIBUTE.NORMAL; } ShellAPI.SHFILEINFO sfiSmall = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(item.FullPidl, dwFileAttrib, ref sfiSmall, ShellAPI.cbFileInfo, uFlags | ShellAPI.SHGFI.SMALLICON); ShellAPI.SHFILEINFO sfiLarge = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(item.FullPidl, dwFileAttrib, ref sfiLarge, ShellAPI.cbFileInfo, uFlags | ShellAPI.SHGFI.LARGEICON); lock (padlock) { // add overlaid icon to the image list res = ShellAPI.ImageList_ReplaceIcon(smallImageListHandle, -1, sfiSmall.hIcon); ShellAPI.ImageList_ReplaceIcon(largeImageListHandle, -1, sfiLarge.hIcon); } ShellAPI.DestroyIcon(sfiSmall.hIcon); ShellAPI.DestroyIcon(sfiLarge.hIcon); imageTable[key] = res; } return(res); }