public void LoadIcon(int index) { if (User32.SendMessage(this.LVHandle, MSG.LVM_ISITEMVISIBLE, index, 0) == 0) { return; } ShellItem sho = null; int hash = -1; Bitmap bitmap = null; this.Invoke(new MethodInvoker(() => { sho = Items[index]; hash = sho.GetHashCode(); Thread.Sleep(1); Application.DoEvents(); bitmap = sho.GetShellThumbnail(IconSize); if ((sho.GetIconType() & IExtractIconpwFlags.GIL_PERCLASS) == 0) { if (!cache.ContainsKey(hash)) { cache.Add(hash, new Bitmap(bitmap)); } } else { if (!cache.ContainsKey(hash)) { cache.Add(hash, null); } } bitmap.Dispose(); })); User32.SendMessage(this.LVHandle, MSG.LVM_REDRAWITEMS, index, index); //Thread.Sleep(1); //Application.DoEvents(); //if (token.IsCancellationRequested == true) //{ // return; //} }
protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 78) { NMHDR nmhdr = new NMHDR(); nmhdr = (NMHDR)m.GetLParam(nmhdr.GetType()); switch ((int)nmhdr.code) { case WNM.LVN_GETDISPINFOW: var nmlv = new NMLVDISPINFO(); nmlv = (NMLVDISPINFO)m.GetLParam(nmlv.GetType()); //if ((nmlv.item.mask & LVIF.LVIF_COLUMNS) == LVIF.LVIF_COLUMNS) //{ // int[] varArray = {0,1,2,3}; // IntPtr ptr = Marshal.AllocHGlobal(varArray.Length*Marshal.SizeOf(varArray[0])); // Marshal.Copy(varArray,0,ptr, varArray.Length); // nmlv.item.cColumns = varArray.Length; // nmlv.item.puColumns = (uint)ptr; // Marshal.StructureToPtr(nmlv, m.LParam, false); //} if ((nmlv.item.mask & LVIF.LVIF_TEXT) == LVIF.LVIF_TEXT && nmlv.item.iSubItem == 0) { var currentItem = Items[nmlv.item.iItem]; nmlv.item.pszText = this.View == ShellViewStyle.Tile ? String.Empty : currentItem.DisplayName; Marshal.StructureToPtr(nmlv, m.LParam, false); } if ((nmlv.item.mask & LVIF.LVIF_TEXT) == LVIF.LVIF_TEXT && nmlv.item.iSubItem == 1) { var currentItem = Items[nmlv.item.iItem]; nmlv.item.pszText = "AAAAA"; Marshal.StructureToPtr(nmlv, m.LParam, false); } break; case WNM.LVN_ITEMACTIVATE: var iac = new NMITEMACTIVATE(); iac = (NMITEMACTIVATE)m.GetLParam(iac.GetType()); Navigate(Items[iac.iItem]); break; case WNM.LVN_ENDSCROLL: tokenSource.Cancel(); // .Cancel(); this.Cancel = true; this.cache.Clear(); //this.refreshedImages.Clear(); GC.Collect(); Shell32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); break; case CustomDraw.NM_CUSTOMDRAW: { if (nmhdr.hwndFrom == this.LVHandle) { var nmlvcd = new NMLVCUSTOMDRAW(); nmlvcd = (NMLVCUSTOMDRAW)m.GetLParam(nmlvcd.GetType()); var index = (int)nmlvcd.nmcd.dwItemSpec; var hdc = nmlvcd.nmcd.hdc; switch (nmlvcd.nmcd.dwDrawStage) { case CustomDraw.CDDS_PREPAINT: m.Result = (IntPtr)CustomDraw.CDRF_NOTIFYITEMDRAW; break; case CustomDraw.CDDS_ITEMPREPAINT: m.Result = (IntPtr)CustomDraw.CDRF_NOTIFYPOSTPAINT; break; case CustomDraw.CDDS_ITEMPOSTPAINT: if (nmlvcd.clrFace != 0 && nmlvcd.clrTextBk != 0) { var itemBounds = new User32.RECT(); User32.SendMessage(this.LVHandle, MSG.LVM_GETITEMRECT, index, ref itemBounds); var iconBounds = new User32.RECT(); iconBounds.Left = 1; User32.SendMessage(this.LVHandle, MSG.LVM_GETITEMRECT, index, ref iconBounds); ShellItem sho = null; var hash = -1; sho = Items[index]; try { hash = sho.GetHashCode(); if (sho != null) { icon = sho.GetShellThumbnail(IconSize, ShellThumbnailFormatOption.ThumbnailOnly, ShellThumbnailRetrievalOption.CacheOnly); if (icon == null) { Bitmap tempicon = null; if (!cache.TryGetValue(hash, out tempicon)) { //if (!this.refreshedImages.Contains(index)) //{ // this.refreshedImages.Add(index); //} Task.Run(() => { LoadIcon(index); }); } else { if (tempicon != null) { icon = tempicon; } } if ((sho.GetIconType() & IExtractIconpwFlags.GIL_PERCLASS) == IExtractIconpwFlags.GIL_PERCLASS || sho.IsFolder) { icon = sho.GetShellThumbnail(IconSize, ShellThumbnailFormatOption.IconOnly); } else { int iconindex = 0; if (Path.GetExtension(sho.ParsingName) == ".exe" || Path.GetExtension(sho.ParsingName) == ".com" || Path.GetExtension(sho.ParsingName) == ".bat") { iconindex = 2; } else if (sho.IsFolder) { iconindex = 3; } var real_icon = IconSize > 48 ? jumbo.GetIcon(iconindex) : extra.GetIcon(iconindex); if (real_icon != null) { icon = real_icon.ToBitmap(); //real_icon.Dispose(); User32.DestroyIcon(real_icon.Handle); } Bitmap tempicon2 = null; if (!cache.TryGetValue(hash, out tempicon2)) { //if (!this.refreshedImages.Contains(index)) //{ // this.refreshedImages.Add(index); //} Task.Run(() => { LoadIcon(index); }); } else { if (tempicon2 != null) { icon = tempicon2; } } } // //else // // icon = ((ShellItem)KnownFolders.Windows).GetShellThumbnail(IconSize, ShellThumbnailFormatOption.IconOnly); // //} } ////var txtBounds = new User32.RECT(); ////txtBounds.Left = 2; ////WindowsAPI.SendMessage(this.handle, WindowsAPI.LVM.GETITEMRECT, index, ref txtBounds); if (icon != null) { using (Graphics g = Graphics.FromHdc(hdc)) { if (icon.Width != icon.Height) { g.DrawImageUnscaled(icon, new Rectangle(iconBounds.Left + (iconBounds.Right - iconBounds.Left - IconSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - IconSize) / 2, IconSize, IconSize)); } else { g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.DrawImage(icon, new Rectangle(iconBounds.Left + (iconBounds.Right - iconBounds.Left - IconSize) / 2, iconBounds.Top + (iconBounds.Bottom - iconBounds.Top - IconSize) / 2, IconSize, IconSize)); } } icon.Dispose(); if (cache.ContainsKey(hash)) { cache[hash].Dispose(); } cache.Remove(hash); } } } catch (Exception ex) { //throw; } } m.Result = (IntPtr)CustomDraw.CDRF_SKIPDEFAULT; break; } } } break; } } }