Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#6

AW: TPngImage freigeben

  Alt 20. Aug 2020, 17:21
Besser den kleinsten gemeinsammen Nenner verwenden, also statt TImage das TPicture.
(Igentlich wäre das Kleineste TGraphic, aber für diesen Aufruf geht es nur bis TPicture)
Delphi-Quellcode:
StartDlg.LoadImgFromResource('Main', ImageMain.Picture);

procedure TStartDlg.LoadImgFromResource(Bezeichner: String; Image: TPicture);
So kann man die Funktion auch zum internen Laden benutzen, wo man keine große/sichtbare Komponente nutzen möchte.


Auch wenn nicht mehr nötig, nochmal als Erklärung:


Joar, da hier bei der Zuweisung nur den Inhalt des Objektes kopiert und nicht das Objekt übergeben/freigibt wird, mußt du das Result der Funktion am Ende freigeben.

Und wie haentschman bereits sagte, sollte man den Namen der Funktion anfassen, um das Verhalten auch gleich mit zu dokumentieren. (Create statt Load oder CreateAndLoadImageFormResource)

Delphi-Quellcode:
Image := StartDlg.CreateImgFromResource('Main');
try
  ImageMain.Picture.Graphic := Image; // entspricht ja eigentlich einem ImageMain.Picture.Graphic.Assign(Image);
finally
  Image.Free;
end;

function TStartDlg.CreateImgFromResource(Bezeichner: String): TPngImage;
begin
  Result := TPngImage.Create;
  try
    if Screen.PixelsPerInch >= 192 then
      Result.LoadFromResourceName(HInstance, Bezeichner + '_200') // DPI 200%
    else if Screen.PixelsPerInch >= 144 then
      Result.LoadFromResourceName(HInstance, Bezeichner + '_150') // DPI 150%
    else
      Result.LoadFromResourceName(HInstance, Bezeichner + '_100'); // DPI 100%
  except
    Result.Free; // wenn es beim Laden knallte, muß es hier schon freigegeben werden, da Result nicht aus fer Funktion raus kommt
    raise;
  end;
end;
Oder als Parameter: Objekt extern erstellen und dort freigeben.
Delphi-Quellcode:
Image := TPngImage.Create;
try
  LoadImgFromResource('Main', Image);
  ImageMain.Picture.Graphic := Image;
finally
  Image.Free;
end;

procedure TStartDlg.LoadImgFromResource(Bezeichner: String; Image: TPngImage);
begin
  if Screen.PixelsPerInch >= 192 then
    Image.LoadFromResourceName(HInstance, Bezeichner + '_200') // DPI 200%
  else if Screen.PixelsPerInch >= 144 then
    Image.LoadFromResourceName(HInstance, Bezeichner + '_150') // DPI 150%
  else
    Image.LoadFromResourceName(HInstance, Bezeichner + '_100'); // DPI 100%
end;

Entspricht deiner letzten Variante, außer
* TPicture statt TImage übergeben
* die Instanz wird nur erzeugt, wenn noch kein PNG vorhanden ist
* die Behandlung des Namen vom dem Ladeaufruf entkoppelt
Delphi-Quellcode:
LoadImgFromResource('Main', ImageMain.Picture);

function TStartDlg.LoadImgFromResource(Bezeichner: String; Picture: TPicture);
var
  Temp: TPngImage;
begin
  if Screen.PixelsPerInch >= 192 then
    Bezeichner := Bezeichner + '_200'   // DPI 200%
  else if Screen.PixelsPerInch >= 144 then
    Bezeichner := Bezeichner + '_150'   // DPI 150%
  else
    Bezeichner := Bezeichner + '_100'; // DPI 100%

  if not (Picture.Graphic is TPngImage) then begin // wenn TPngImage schon drin ist, muß man es nicht nochmal neu erzeugen
    Temp := TPngImage.Create;
    try
      Picture.Graphic := Temp; // ja, die Behandlung von Graphic ist echt krank, aber das liegt nicht an dir
    finally
      Temp.Free;
    end;
  end;

  //Picture.Graphic.LoadFromResourceName(HInstance, Bezeichner);
  TPngImage(Picture.Graphic).LoadFromResourceName(HInstance, Bezeichner); // vermutlich geht es auch direkt und wird durchgereicht, aber ich war mir grad nicht ganz sicher
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat