/// <summary> /// Returns HICON of provided size (or of default size if requested one isn't available) /// </summary> /// <param name="iconType"></param> private IntPtr GetUnmanagedIcon(API.Shgfi iconType) { Log.Raw("begin", _initialObject); //Way 1, straightforward: "Hey shell, give me an icon for that file!" var shinfo = new API.ShfileinfoW(); var zeroFails = API.SHGetFileInfo(_initialObject, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), API.Shgfi.ICON | iconType); Log.Raw("ShGetFileInfo returned " + zeroFails); if (zeroFails == IntPtr.Zero) //lot of stuff will work via this { //Shell failed //Way 2: way around: "Hey registry, and how should display the stuff of a kind?" var temp = Util.GetDefaultIconResourceIdForClass(_initialObject); Log.Raw("GetDefaultIconResourceIdForClass returned " + (temp ?? "NULL!!")); if (!string.IsNullOrEmpty(temp)) { zeroFails = Util.ResolveIconicResource(temp); Log.Raw("ResolveIconicResource returned " + zeroFails); } if (zeroFails != IntPtr.Zero)//ResolveIconicResource() succeeded and zeroFails contains required handle { shinfo.hIcon = zeroFails; } else if (_id != API.Csidl.INVALID) //For PowerItems initialized without argument but with folderId { //No icon, or Registry doesn't know //Way 3, cumbersome: "Hey shell, I know that stuff means something for ya. Give me the icon for the thing this staff means!" var ppIdl = IntPtr.Zero; var hRes = API.SHGetSpecialFolderLocation(IntPtr.Zero, _id, ref ppIdl); //I know, obsolete, but works ;) Log.Fmt("SHGetSp.F.Loc. for id<={0} returned result code {1}", _id, hRes); zeroFails = (hRes != 0 ? IntPtr.Zero : API.SHGetFileInfo(ppIdl, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), API.Shgfi.ICON | API.Shgfi.PIDL | API.Shgfi.USEFILEATTRIBUTES | iconType)); Marshal.FreeCoTaskMem(ppIdl); Log.Raw("ShGetFileInfo (2p) returned " + zeroFails); } } Log.Fmt("end<<<<<, zf={0}, hi={1}", zeroFails, shinfo.hIcon); return(zeroFails == IntPtr.Zero || shinfo.hIcon == IntPtr.Zero ? IntPtr.Zero : shinfo.hIcon); }
/// <summary> /// Synchronous getter of an icon for PowerItem /// </summary> /// <param name="item">PowerItem we need icon extracted for</param> /// <param name="iconNeeded">type of icon needed - small or large</param> /// <returns>ImageContainer with ImageSources extracted. Can be null.</returns> public static ImageContainer GetImageContainerSync(PowerItem item, API.Shgfi iconNeeded) { Log.Raw("begin>>>>>>>>>>>>>>>", item.FriendlyName); //Checking if there's cached ImageContainer string resolvedArg, descr; try { resolvedArg = PowerItemTree.GetResolvedArgument(item); descr = GetObjectDescriptor(item, resolvedArg); } catch (IOException) { return(null); } lock (Cache) { var container = (ImageContainer)(Cache.ContainsKey(descr) ? Cache[descr] : null); Log.Fmt("arg<={0}, descr<={1}, container<={2}", resolvedArg, descr, (container != null ? "not " : "") + "null"); if (container == null) //No cached instance { container = new ImageContainer(resolvedArg, descr, item.SpecialFolderId); Cache.Add(descr, container); if (iconNeeded == API.Shgfi.SMALLICON) { container.ExtractSmall(); } else { container.ExtractLarge(); } } #if DEBUG Log.Raw("end<<<<<<<<<<<<<<", item.FriendlyName); #endif return(container); } }
/// <summary> /// Starts asynchronous extraction of ImageContainer for PowerItem /// </summary> /// <param name="item">PowerItem we need icon extracted for</param> /// <param name="iconNeeded">type of icon needed - small or large</param> /// <returns>Always null</returns> public static ImageContainer GetImageContainer(PowerItem item, API.Shgfi iconNeeded) { ImageQueue.Enqueue(new Tuple <PowerItem, API.Shgfi>(item, iconNeeded)); return(null); }