Ich habe im
QC noch einiges ergänzt. Ich habe herausgefunden, dass es tatsächlich an den Threads liegen muss. Wenn ich einfach nur ein Sleep(500) vor das Load setze, brauche ich keine
OLE Initialisierung. Auch auf einem älteren PC läuft es manchmal beim ersten Versuch bevor der Cache zuschlägt.
Mit dem Sleep kommen auch keinerlei Bildfehler mehr und es ging in allen Versuchen auf allen PCs.
Generell liegt es wohl daran, dass FMX-Framework erst komplett initialisiert sein muss, damit der Code funktioniert.
Mit einem Thread kommt es bei diesem Verhalten auf das Timing an. Ist die Framework-Initialisierung abgeschlossen bevor der Thread startet, dann ist alles gut, ansonsten kommt ein Fehler im ImageDataSoure bei
TBitmap.CreateFromFile
bzw. (mit Debug-DCUs)
Delphi-Quellcode:
function TBitmapCodecWIC.LoadFromFile(
const AFileName:
string;
const Bitmap: TBitmapSurface): Boolean;
...
begin
...
try
TCanvasD2D.ImagingFactory.CreateDecoderFromStream(SA, GUID_NULL, WICDecodeMetadataCacheOnDemand,
dec);
// <- hier
...
finally
FS.Free;
end;
end;
Wenn man jetzt (nur so zum Spass) einen Timer auf die Form klatscht, mit einem Interval von 1 und in diesem Timer, dann den Thread startet (anstatt im FormCreate):
Delphi-Quellcode:
procedure TFormMain.StartupTimerTimer(Sender: TObject);
begin
StartupTimer.Enabled := False;
// Start loading
FSplashImageLoader.Start;
end;
dann gibt es auch keine Zugriffsverletzungen und die Bilder werden korrekt angezeigt.
Die Load-Methode habe ich auch etwas angepasst, damit bei einem Fehler nicht die ganze Hütte zusammenbricht
statt
Delphi-Quellcode:
SetLength( FImages, I + 1 );
FImages[I] := TBitmap.CreateFromFile( ImagesPath + SR.Name );
nehmen wir
Delphi-Quellcode:
LBitmap := TBitmap.CreateFromFile( ImagesPath + SR.Name );
SetLength( FImages, I + 1 );
FImages[I] := LBitmap;
Manchmal muss man nur geschickter und sorgfältiger arbeiten und das Wesen des Frameworks verstehen (nicht wahr, E***a)
Den komplett geänderten Source habe ich mal angehängt zum Testen