AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Bei einer Komponente ein Panel zwischenschalten
Thema durchsuchen
Ansicht
Themen-Optionen

Bei einer Komponente ein Panel zwischenschalten

Ein Thema von blackdrake · begonnen am 27. Mär 2009 · letzter Beitrag vom 21. Apr 2009
 
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#8

Re: Bei einer Komponente ein Panel zwischenschalten

  Alt 30. Mär 2009, 10:09
Hallo.

Ich habe den Code nochmal ganz genau analysiert, Diagramme gemacht (Stichwort Hirnknoten) und einiges verbessert. Nun klappt es ohne AV beim Create. Im Destroy habe ich aber aufgrund der Owner Probleme. Selbst wenn das Destroy funktioniert, kommt die AV am Programmende. Ich habe verschiedene Varianten durchprobiert und im Quellcode kurz kommentiert. Könnt ihr mir bitte weiterhelfen?

Delphi-Quellcode:
type
  TPaneledImage = class(TImage)
  private
    FPanel: TPanel;
    procedure SetVisible(Value: boolean);
    function GetParent: TWinControl;
    function GetOwner: TComponent; reintroduce;
    function GetVisible: boolean;
  protected
    procedure SetParent(AParent: TWinControl); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    property Parent: TWinControl read GetParent write SetParent;
    property Visible: boolean read GetVisible write SetVisible;
    property Owner: TComponent read GetOwner;
  end;

constructor TPaneledImage.Create(AOwner: TComponent);
begin
  // Host-Panel erstellen
  FPanel := TPanel.Create(AOwner);

  // Eigenschaften für das Panel
  FPanel.BevelOuter := bvNone;

  // Das eigentliche Image erstellen
  inherited Create(FPanel); {1}
  // inherited Create(AOwner); {2}
  // inherited Create(Self); {3}

  // Unveränderliche Eigenschaften für das Image im Panel festlegen
  inherited SetParent(FPanel);
  Align := alClient;
  Visible := true;
end;

destructor TPaneledImage.Destroy;
begin
  // Zuerst das Panel freigeben. Das Panel wird zuerst Nil gesetzt, dann freigegeben.
  // Das Panel wird widerum uns zuerst freigeben, weswegen dieses Destroy ein zweites
  // Mal aufgerufen wird und die korrekte Freigabe von TObject einleitet.

  if Assigned(FPanel) then
  begin
    FreeAndNil(FPanel) // Diese Zeile wird 1x zuerst aufgerufen
  end
  else
  begin
    // Diese Zeile wird 1x danach aufgerufen
    inherited;
    // Hier wird zusätzlich einmal TPaneledImage.SetParent aufgerufen
  end;

  // Aber NACH Destroy gibts eine AV!
end;

function TPaneledImage.GetOwner: TComponent;
begin
  result := FPanel.Owner;
end;

function TPaneledImage.GetParent: TWinControl;
begin
  result := FPanel.Parent;
end;

function TPaneledImage.GetVisible: boolean;
begin
  result := FPanel.Visible;
end;

procedure TPaneledImage.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  // Das Image im Panel soll bei (0, 0) bleiben. Nur das Panel bewegt sich.
  inherited SetBounds(0, 0, AWidth, AHeight);

  FPanel.Left := ALeft;
  FPanel.Top := ATop;
  FPanel.Width := AWidth;
  FPanel.Height := AHeight;
end;

procedure TPaneledImage.SetParent(AParent: TWinControl);
begin
  if not Assigned(FPanel) then exit; // Verhindern einer AV bei Destroy

  if FPanel.Parent <> AParent then
  begin
    FPanel.Parent := AParent;
  end;
end;

procedure TPaneledImage.SetVisible(Value: boolean);
begin
  if FPanel.Visible <> Value then
  begin
    FPanel.Visible := Value;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TPaneledImage;
begin
  x := TPaneledImage.Create(Self);
  try
    x.Parent := Self;
    x.AutoSize := true;
    x.Picture.LoadFromFile('C:\WINDOWS\Präriewind.BMP');
  finally
    x.Free; // Verursacht eine AV, wenn Programm später beendet wird
  end;
end;
Create-Versuch {1}

Self gehört Self.Panel
Self.Panel gehört Self.Owner

Create-Versuch {2}

Self gehört Self.Owner
Self.Panel gehört Self.Owner

Create-Versuch {3}

Self gehört Self (hä? )
Self.Panel gehört Self.Owner

Weitere Idee 4

Self gehört Self.Owner
Self.Panel gehört Self

Weitere Idee 5

Self gehört Self.Panel
Self.Panel gehört Self


Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz