Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Icon to ImageList without Duplicates

I want to add icons to an TImagelist, but without adding the same Icon again. This is how I retrieve the Icon:

  Icon := TIcon.Create;
  SHGetFileInfo(PChar(filename), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON);
  icon.Handle := FileInfo.hIcon;
  imageid := imagelist.AddIcon(icon);
  DestroyIcon(FileInfo.hIcon);
  Icon.Free;
  

First I tried to compare the bitmaps after adding the icon to the imagelist, and delete it again after I found a match. I tried comparing the bitmaps via streams and comparemem, and I tried comparing them via scanlines, both had the result that the same icons somehow translate to slightly different bitmaps, at least it didn't work.

Then I tried to get a hash of the icon before I add it to the imagelist, and compare it to previous hashes. Now I have the opposite problem - All icons translate to the same hash. I tried copying it to a bitmap before hashing, but the result is the same. This is the current state:

  Icon := TIcon.Create;
  SHGetFileInfo(PChar(filename), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON);
  icon.Handle := FileInfo.hIcon;
  bm := TBitmap.Create;
  icon.AssignTo(bm);
  stream := TMemoryStream.Create;
  bm.SaveToStream(stream);
  hash := System.hash.THashMD5.GetHashString(stream);
  stream.Free;
  bm.Free;
  imageid := iconhashlist.IndexOf(hash);
  if imageid = -1 then begin
     imageid := imagelist.AddIcon(icon);
     iconhashlist.Add(hash);
  end;
  DestroyIcon(FileInfo.hIcon);
  Icon.Free;
  

Any ideas why this doesn't work?

like image 919
natraj Avatar asked Oct 29 '25 05:10

natraj


1 Answers

In your TMemoryStream example, you are not seeking the stream's Position back to 0 after bm.SaveToStream() exits. It leaves the Position at the end of the stream, and then THashMD5.GetHashString() tries to read from the stream at its current Position, which yields no data for it to compute the hash with, and thus it returns the same MD5 value every time.

bm.SaveToStream(stream);
stream.Position := 0; // <-- ADD THIS
hash := System.hash.THashMD5.GetHashString(stream);
like image 117
Remy Lebeau Avatar answered Nov 01 '25 12:11

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!