private void DrawWithAddorner(IntPtr hdc, User32.RECT iconBounds, Boolean isGhosted, Int32 width, Int32 height, IntPtr hThumbnail, Int32 addornerType) { Int32 width2; Int32 height2; if (addornerType == 2) { var addorner = new Bitmap(width + 7, height + 7, PixelFormat.Format32bppPArgb); LinearGradientBrush gb = new LinearGradientBrush(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, this._CurrentSize), Color.White, Color.WhiteSmoke); addorner = Gdi32.RoundCorners(addorner, 0, gb); gb.Dispose(); var hAddorner = addorner.GetHbitmap(); Gdi32.ConvertPixelByPixel(hAddorner, out width2, out height2); Gdi32.NativeDraw(hdc, hAddorner, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width2) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height2) / 2, width2, height2, isGhosted); Gdi32.DeleteObject(hAddorner); addorner.Dispose(); Gdi32.NativeDraw(hdc, hThumbnail, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width2) / 2 + 3, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height2) / 2 + 3, width, height, isGhosted); } else if (addornerType == 3) { var isWide = (height / (Double)width) < 0.6; var hAddorner = isWide ? this._VideAddornerWide.GetHBitmap(this._CurrentSize, true, true) : this._VideAddorner.GetHBitmap(this._CurrentSize, true, true); Gdi32.ConvertPixelByPixel(hAddorner, out width2, out height2); if (isWide) { Gdi32.NativeDrawCrop(hdc, hThumbnail, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2 + (Int32)(this._CurrentSize * 0.12), iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2 + (Int32)(this._CurrentSize * 0.07 / 2), (Int32)(this._CurrentSize * 0.12), (Int32)(this._CurrentSize * 0.03 / 2), width - (Int32)(this._CurrentSize * 0.13 * 2), height - (Int32)(this._CurrentSize * 0.03), isGhosted); var left = iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2; var top = iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2; Gdi32.NativeDraw(hdc, hAddorner, left, top, width2, height2, width2, height + (Int32)(this._CurrentSize * 0.07) - (Int32)(this._CurrentSize * 0.04), isGhosted); } else { Gdi32.NativeDrawCrop(hdc, hThumbnail, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2 + (Int32)(this._CurrentSize * 0.12), iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2 + (Int32)(this._CurrentSize * 0.07 / 2), (Int32)(this._CurrentSize * 0.12), (Int32)(this._CurrentSize * 0.03 / 2), width - (Int32)(this._CurrentSize * 0.13 * 1.9), height - (Int32)(this._CurrentSize * 0.07), isGhosted); Gdi32.NativeDraw(hdc, hAddorner, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2, width2, height2, width2, height + (Int32)(this._CurrentSize * 0.06) - (Int32)(this._CurrentSize * 0.07), isGhosted); } Gdi32.DeleteObject(hAddorner); } }
private void _IconCacheLoadingThreadRun() { while (true) { //if (resetEvent != null) resetEvent.WaitOne(); var index = 0; if (!ThreadRun_Helper(this._ThumbnailsForCacheLoad, true, ref index)) { continue; } if (this._ThumbnailsForCacheLoad.Count() > 1 || !this._IsSupressedTumbGeneration) { //Thread.Sleep(1); var sho = this._ShellViewEx.Items[index]; if (sho.IsNeedRefreshing | !sho.IsThumbnailLoaded) { var addornerType = this.GetAddornerType(sho); var result = sho.GetHBitmap(addornerType == 2 ? this._CurrentSize - 7 : this._CurrentSize, true, true); sho.IsThumbnailLoaded = true; sho.IsNeedRefreshing = false; sho.IsIconLoaded = true; if (result != IntPtr.Zero) { var width = 0; var height = 0; Gdi32.ConvertPixelByPixel(result, out width, out height); if (addornerType == 2) { width = width + 7; height = height + 7; } sho.IsOnlyLowQuality = (width > height && width != this._CurrentSize) || (width < height && height != this._CurrentSize) || (width == height && width != this._CurrentSize); if (!this._RedrawQueue.Contains(index)) { this._RedrawQueue.Enqueue(index); } //this._ShellViewEx.RedrawItem(index); Gdi32.DeleteObject(result); } } sho.Dispose(); } } }
public HResult ExtractAndDrawThumbnail(IntPtr hdc, uint iconSize, out WTS_CACHEFLAGS flags, User32.RECT iconBounds, out bool retrieved, bool isHidden, bool isRefresh = false) { IThumbnailCache thumbCache = null; if (this.ComInterface != null) { var IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); var CLSID_LocalThumbnailCache = new Guid("50EF4544-AC9F-4A8E-B21B-8A26180DB13F"); IntPtr cachePointer; Ole32.CoCreateInstance(ref CLSID_LocalThumbnailCache, IntPtr.Zero, Ole32.CLSCTX.INPROC, ref IID_IUnknown, out cachePointer); thumbCache = (IThumbnailCache)Marshal.GetObjectForIUnknown(cachePointer); } var res = HResult.S_OK; ISharedBitmap bmp = null; flags = WTS_CACHEFLAGS.WTS_DEFAULT; var thumbId = default(WTS_THUMBNAILID); try { retrieved = false; res = thumbCache.GetThumbnail(this._Item.ComInterface, iconSize, isRefresh ? (WTS_FLAGS.WTS_FORCEEXTRACTION | WTS_FLAGS.WTS_SCALETOREQUESTEDSIZE) : (WTS_FLAGS.WTS_INCACHEONLY | WTS_FLAGS.WTS_SCALETOREQUESTEDSIZE), out bmp, flags, thumbId); var hBitmap = IntPtr.Zero; if (bmp != null) { bmp.GetSharedBitmap(out hBitmap); retrieved = true; int width; int height; Gdi32.ConvertPixelByPixel(hBitmap, out width, out height); Gdi32.NativeDraw(hdc, hBitmap, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2, width, height, isHidden); Gdi32.DeleteObject(hBitmap); } } finally { if (bmp != null) { Marshal.ReleaseComObject(bmp); } } return(res); }
public void DrawIcon(IntPtr hdc, Int32 index, IListItemEx sho, User32.RECT iconBounds, Boolean isGhosted, Boolean isHot) { if (sho.OverlayIconIndex == -1) { this._OverlayQueue.Enqueue(index); } var isPerInstance = (sho.IconType & IExtractIconPWFlags.GIL_PERINSTANCE) == IExtractIconPWFlags.GIL_PERINSTANCE; if (this._CurrentSize != 16) { Int32 width = 0; Int32 height = 0; var addornerType = this.GetAddornerType(sho); IntPtr hThumbnail = IntPtr.Zero; if ((!sho.IsThumbnailLoaded && sho.IsIconLoaded) || (sho.IsThumbnailLoaded && !sho.IsIconLoaded) || (sho.IsThumbnailLoaded && sho.IsIconLoaded) || (!sho.IsThumbnailLoaded && !sho.IsIconLoaded)) { hThumbnail = sho.GetHBitmap(addornerType == 2 ? this._CurrentSize - 7 : this._CurrentSize, true); if (hThumbnail != IntPtr.Zero) { Gdi32.ConvertPixelByPixel(hThumbnail, out width, out height); if (addornerType > 0) { this.DrawWithAddorner(hdc, iconBounds, isGhosted, width, height, hThumbnail, addornerType); } else { Gdi32.NativeDraw(hdc, hThumbnail, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2, width, height, isGhosted); } if (addornerType == 2) { width = width + 7; height = height + 7; } sho.IsNeedRefreshing = ((width > height && width != this._CurrentSize) || (width < height && height != this._CurrentSize) || (width == height && width != this._CurrentSize)) && !sho.IsOnlyLowQuality; if (!sho.IsNeedRefreshing) { sho.IsThumbnailLoaded = true; sho.IsIconLoaded = true; } } } if (hThumbnail == IntPtr.Zero && !sho.IsThumbnailLoaded && !sho.IsIconLoaded || sho.IsNeedRefreshing) { Task.Run(() => { this._ThumbnailsForCacheLoad.Enqueue(index); }); } if (hThumbnail == IntPtr.Zero && !sho.IsIconLoaded && isPerInstance) { Task.Run(() => { this._IconsForRetreval.Enqueue(index); }); this.DrawDefaultIcons(hdc, sho, iconBounds); } if (hThumbnail == IntPtr.Zero && (sho.IsIconLoaded || !isPerInstance)) { if (!sho.IsRCWSet && isPerInstance) { Task.Run(() => { this._IconsForRetreval.Enqueue(index); }); this.DrawDefaultIcons(hdc, sho, iconBounds); } else { hThumbnail = sho.GetHBitmap(this._CurrentSize, false); Gdi32.ConvertPixelByPixel(hThumbnail, out width, out height); Gdi32.NativeDraw(hdc, hThumbnail, iconBounds.Left + (iconBounds.Right - iconBounds.Left - width) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - height) / 2, width, height, isGhosted); } } Gdi32.DeleteObject(hThumbnail); using (var g = Graphics.FromHdc(hdc)) { if (this._ShellViewEx.ShowCheckboxes && this._ShellViewEx.View != ShellViewStyle.Details && this._ShellViewEx.View != ShellViewStyle.List) { /* * var lvi = new LVITEMINDEX(); * lvi.iItem = index; * lvi.iGroup = this._ShellViewEx.GetGroupIndex(index); */ var iGroup = this._ShellViewEx.GetGroupIndex(index); var lvItem = new LVITEM() { iItem = index, iGroupId = iGroup, iGroup = iGroup, mask = LVIF.LVIF_STATE, stateMask = LVIS.LVIS_SELECTED }; var lvItemImageMask = new LVITEM() { iItem = index, iGroupId = iGroup, iGroup = iGroup, mask = LVIF.LVIF_STATE, stateMask = LVIS.LVIS_STATEIMAGEMASK }; var res = User32.SendMessage(this._ShellViewEx.LVHandle, MSG.LVM_GETITEMW, 0, ref lvItemImageMask); if (isHot || (UInt32)lvItemImageMask.state == (2 << 12)) { res = User32.SendMessage(this._ShellViewEx.LVHandle, MSG.LVM_GETITEMW, 0, ref lvItem); var checkboxOffsetH = 14; var checkboxOffsetV = 2; if (this._ShellViewEx.View == ShellViewStyle.Tile || this._ShellViewEx.View == ShellViewStyle.SmallIcon) { checkboxOffsetH = 2; } if (this._ShellViewEx.View == ShellViewStyle.Tile) { checkboxOffsetV = 5; } CheckBoxRenderer.DrawCheckBox(g, new Point(iconBounds.Left + checkboxOffsetH, iconBounds.Top + checkboxOffsetV), lvItem.state != 0 ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal); } } } if (sho.OverlayIconIndex > 0) { if (this._CurrentSize > 180) { this._Jumbo.DrawOverlay(hdc, sho.OverlayIconIndex, new Point(iconBounds.Left, iconBounds.Bottom - (this._ShellViewEx.View == ShellViewStyle.Tile ? 5 : 0) - this._CurrentSize / 3), this._CurrentSize / 3); } else if (this._CurrentSize > 64) { this._Extra.DrawOverlay(hdc, sho.OverlayIconIndex, new Point(iconBounds.Left + 10 - (this._ShellViewEx.View == ShellViewStyle.Tile ? 5 : 0), iconBounds.Bottom - 50)); } else { this._Large.DrawOverlay(hdc, sho.OverlayIconIndex, new Point(iconBounds.Left + 10 - (this._ShellViewEx.View == ShellViewStyle.Tile ? 5 : 0), iconBounds.Bottom - 32)); } } if (sho.ShieldedIconIndex > 0) { if (this._CurrentSize > 180) { this._Jumbo.DrawIcon(hdc, sho.ShieldedIconIndex, new Point(iconBounds.Right - this._CurrentSize / 3 - 3, iconBounds.Bottom - this._CurrentSize / 3), this._CurrentSize / 3); } else if (this._CurrentSize > 64) { this._Extra.DrawIcon(hdc, sho.ShieldedIconIndex, new Point(iconBounds.Right - 43, iconBounds.Bottom - 50)); } else { this._Large.DrawIcon(hdc, sho.ShieldedIconIndex, new Point(iconBounds.Right - 33, iconBounds.Bottom - 32)); } } if (sho.IsShared) { if (this._CurrentSize > 180) { this._Jumbo.DrawIcon(hdc, this._SharedIconIndex, new Point(iconBounds.Right - this._CurrentSize / 3, iconBounds.Bottom - this._CurrentSize / 3), this._CurrentSize / 3); } else if (this._CurrentSize > 64) { this._Extra.DrawIcon(hdc, this._SharedIconIndex, new Point(iconBounds.Right - 40, iconBounds.Bottom - 50)); } else { this._Large.DrawIcon(hdc, this._SharedIconIndex, new Point(iconBounds.Right - 30, iconBounds.Bottom - 32)); } } IListItemEx badge = this.GetBadgeForPath(sho.ParsingName); if (badge != null) { var badgeIco = badge.GetHBitmap(this._CurrentSize, false, false, true); Gdi32.ConvertPixelByPixel(badgeIco, out width, out height); Gdi32.NativeDraw(hdc, badgeIco, iconBounds.Left + (iconBounds.Right - iconBounds.Left - _CurrentSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - _CurrentSize) / 2, _CurrentSize, isGhosted); Gdi32.DeleteObject(badgeIco); badge.Dispose(); } if (this._ShellViewEx.View == ShellViewStyle.Tile) { var lvi = new LVITEMINDEX(); lvi.iItem = index; lvi.iGroup = this._ShellViewEx.GetGroupIndex(index); var lableBounds = new User32.RECT() { Left = 2 }; User32.SendMessage(this._ShellViewEx.LVHandle, MSG.LVM_GETITEMINDEXRECT, ref lvi, ref lableBounds); using (var g = Graphics.FromHdc(hdc)) { var lblrectTiles = new RectangleF(lableBounds.Left, iconBounds.Top + 6, lableBounds.Right - lableBounds.Left, 15); if (this._ShellViewEx.RequestedCurrentLocation.ParsingName.Equals(KnownFolders.Computer.ParsingName) && (sho.IsDrive || sho.IsNetworkPath)) { var fmt = new StringFormat(); fmt.Trimming = StringTrimming.EllipsisCharacter; fmt.Alignment = StringAlignment.Center; fmt.Alignment = StringAlignment.Near; fmt.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; fmt.LineAlignment = StringAlignment.Center; this.DrawComputerTiledModeView(sho, g, lblrectTiles, fmt); } } } } else { sho.IsThumbnailLoaded = true; Int32 width = 0, height = 0; if ((sho.IconType & IExtractIconPWFlags.GIL_PERCLASS) == IExtractIconPWFlags.GIL_PERCLASS) { var hIconExe = sho.GetHBitmap(this._CurrentSize, false); if (hIconExe != IntPtr.Zero) { sho.IsIconLoaded = true; Gdi32.ConvertPixelByPixel(hIconExe, out width, out height); Gdi32.NativeDraw(hdc, hIconExe, iconBounds.Left + (iconBounds.Right - iconBounds.Left - this._CurrentSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - this._CurrentSize) / 2, this._CurrentSize, isGhosted); Gdi32.DeleteObject(hIconExe); } } else if ((sho.IconType & IExtractIconPWFlags.GIL_PERINSTANCE) == IExtractIconPWFlags.GIL_PERINSTANCE) { if (!sho.IsIconLoaded) { /* * if (sho.IsNetworkPath || this._ShellViewEx.IsSearchNavigating) { * Task.Run(() => { * this._IconsForRetreval.Enqueue(index); * }); * } else { * Task.Run(() => { * this._IconsForRetreval.Enqueue(index); * }); * } */ //Task.Run(() => { this._IconsForRetreval.Enqueue(index); //}); this._Small.DrawIcon(hdc, this._ExeFallBackIndex, new Point(iconBounds.Left + (iconBounds.Right - iconBounds.Left - this._CurrentSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - this._CurrentSize) / 2)); } else { var hIconExe = sho.GetHBitmap(this._CurrentSize, false); if (hIconExe != IntPtr.Zero) { sho.IsIconLoaded = true; Gdi32.ConvertPixelByPixel(hIconExe, out width, out height); Gdi32.NativeDraw(hdc, hIconExe, iconBounds.Left + (iconBounds.Right - iconBounds.Left - this._CurrentSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - this._CurrentSize) / 2, this._CurrentSize, isGhosted); Gdi32.DeleteObject(hIconExe); } } } if (sho.OverlayIconIndex > 0) { this._Small.DrawOverlay(hdc, sho.OverlayIconIndex, new Point(iconBounds.Left, iconBounds.Bottom - 16)); } if (sho.ShieldedIconIndex > 0) { this._Small.DrawIcon(hdc, sho.ShieldedIconIndex, new Point(iconBounds.Right - 9, iconBounds.Bottom - 10), 10); } if (sho.IsShared) { this._Small.DrawIcon(hdc, this._SharedIconIndex, new Point(iconBounds.Right - 9, iconBounds.Bottom - 16)); } IListItemEx badge = this.GetBadgeForPath(sho.ParsingName); if (badge != null) { var badgeIco = badge.GetHBitmap(16, false, false, true); Gdi32.ConvertPixelByPixel(badgeIco, out width, out height); Gdi32.NativeDraw(hdc, badgeIco, iconBounds.Left, iconBounds.Top, 16, isGhosted); Gdi32.DeleteObject(badgeIco); } } }