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?
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With