Häufig benötigte Bitmaps sollen nur einmal gespeichert und zur Laufzeit geladen, geändert und mit Änderungen gespeichert werden.

Lösungsversuch mit Ressourcen: Mit Bitmaps.Res werden die Bitmaps nur einmal erstellt. Aber sie werden beim Kompilieren in jede EXE/DLL eingebunden; sie können zur Laufzeit u.U. bearbeitet werden; aber nicht mit Änderungen gespeichert werden.

Lösungsversuch mit ImageList: Laut Delphi-Hilfe werden alle Bitmaps einer ImageList intern in einer gemeinsamen Bitmap gespeichert.
Die gewünschten Ziele würden also erreicht, wenn ich diese gemeinsame Bitmap ,am Stück' einlesen, bearbeiten und speichern könnte - aber ausgerechnet die Methoden TImageList.ReadData und TImageList.WriteData sind private.

Versuch mit Nachbesserung von TImageList.WriteData<br>
Diese Funktion lässt sich einfach übernehmen; '||' habe ich als Ersatz für das Zeilenende benutzt.
procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(SF); ||
try ||
// der folgende Befehl ist wohl Windows-Standard und übernimmt ImageList.Handle ||
if not ImageList_Write(ImageListe.Handle, SA) ||
then raise EWriteError.CreateRes(@SImageWriteFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;<br>
Wegen der folgenden Funktion weiß ich nicht, ob dies funktioniert; aber es sieht zumindest richtig aus und liefert keinen Laufzeitfehler.

Die Nachbesserung von TImageList.ReadData sollte ähnlich funktionieren (für Delphi 3 ff.):<br>
procedure TForm1.Images_Read( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(Stream); ||
try ||
ImageListe.FreeHandle; ||
ImageListe.Handle := ImageList_Read(SA); ||
if ImageListe.Handle = 0 then raise EReadError.CreateRes(@SImageReadFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;

Aber diese Variante funktioniert nicht: * Delphi weist bei ImageListe.OnCreate automatisch das benötigte Handle zu. * FreeHandle wird nicht umgesetzt. * ImageList_Read gibt einen ImageList-Handle zurück, der aber nicht direkt der schon vorhandenen ImageListe zugewiesen werden kann.<br>
Kann der Handle durch die Funktion zugewiesen werden mit var-Parameter für ImageListe? Gibt es einen anderen 'Umweg'?

Lösungsversuch mit einzelnen Bitmaps in einem gemeinsamem Stream/Datei: Wie bei AddImages wird jedes Bitmap der Liste an einen Stream (mit Speichern in einer Datei) angehängt bzw. ausgelesen. Es funktioniert prinzipiell wie gewünscht:

procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; i1: integer; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
try ||
for i1 := 0 to ImageListe.Count - 1 ||
do begin ||
ImageListe.GetBitmap( i1, Bild ); ||
Bild.SaveToStream(Ausgabe); ||
end; ||
Ausgabe.SaveToFile( ImageFile ); ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;

procedure TForm1.Images_Read ( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
ImageListe.Clear; ||
try ||
Ausgabe.LoadFromFile(ImageFile); ||
Ausgabe.Seek( 0, soFromBeginning ); ||
repeat ||
Bild.LoadFromStream(Ausgabe); ||
ImageListe.Add(Bild,nil); ||
until Ausgabe.Position >= Ausgabe.Size; ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;

Aber unzumutbar ist: * Alle Bitmaps sehen 'unscharf' aus. * Bei weiteren Bitmaps sieht es so aus, als ob die anderen Bitmaps im Hintergrund stünden. Woran kann das liegen, und wie kann das vermieden werden? Danke für Tipps!