Einzelnen Beitrag anzeigen

blackdrake

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

Re: Bei einer Komponente ein Panel zwischenschalten

  Alt 31. Mär 2009, 21:06
Hallo.

Vielen Dank für deine Antwort.

Es funktioniert leider immer noch nicht. Jetzt bekomme ich einen Stacküberlauf.

Ich hatte gestern sehr lange daran gearbeitet und etliche Workarounds beim SetBounds() durchgeführt, sodass das mit den Algignments, Stretch, AutoSize etc alles einigermaßen funktioniert (aber es scheint noch Ausnahmen zu geben). Beispielsweise musste ich in SetBounds() Width und Height verändern, damit AutoSize funktioniert. Jedoch durfte ich Left und Top nicht dort verändern, da sonst ein Image wieder bei (0, 0) war, wenn ich den Parent geändert habe. Das ganze ist extrem kompliziert... Diesbezüglich bin ich für Verbesserungsvorschläge dankbar!

Ich habe mal das komplette Testprogramm + aktuellem Codestand gepostet.

Delphi-Quellcode:
type
  TPaneledImage = class(TImage)
  private
    function GetVisible: boolean;
    procedure SetVisible(const Value: boolean);
    function GetParent: TWinControl;
    procedure SetLeft(const Value: Integer);
    procedure SetTop(const Value: Integer);
    function GetLeft: Integer;
    function GetTop: Integer;
    function GetHeight: Integer;
    function GetWidth: Integer;
    procedure SetHeight(Value: Integer);
    procedure SetWidth(Value: Integer);
    function GetAlign: TAlign;
    procedure SetAlign(Value: TAlign);
  protected
    Panel: TPanel;
    procedure SetParent(AParent: TWinControl); override;
  public
    // Color...
    // Handle
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
    property Visible: boolean read GetVisible write SetVisible;
    property Parent: TWinControl read GetParent write SetParent;
    property Left: Integer read GetLeft write SetLeft;
    property Top: Integer read GetTop write SetTop;
    property Width: Integer read GetWidth write SetWidth;
    property Height: Integer read GetHeight write SetHeight;
    property Align: TAlign read GetAlign write SetAlign;
  end;

{ TPaneledImage }

constructor TPaneledImage.Create(AOwner: TComponent);
begin
  (* inherited Create(AOwner);

  Panel := TPanel.Create(Self);

  // Eigenschaften für Panel
  Panel.BevelOuter := bvNone;
  Panel.Color := clRed;

  // Eigenschaften für Image
  inherited Align := alClient;
  inherited SetParent(Panel); *)



  Panel := TPanel.Create(Self);

  inherited Create(Panel);

  // Eigenschaften für Panel
  Panel.BevelOuter := bvNone;
  Panel.Color := clRed;

  // Eigenschaften für Image
  (* inherited *) Align := alClient;
end;

destructor TPaneledImage.Destroy;
begin
  (* if Assigned(Panel) then
  begin
    inherited SetParent(Panel.Parent);
    FreeAndNil(Panel);
  end; *)


  inherited;
end;

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

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

procedure TPaneledImage.SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer);
begin
  // Das Bild im Panel ist immer bei (0, 0)
  // inherited SetBounds(0, 0, AWidth, AHeight);
  inherited SetBounds(ALeft, ATop, AWidth, AHeight);

  if Assigned(Panel) then
  begin
// Panel.Left := ALeft;
// Panel.Top := ATop;
    Panel.Width := AWidth;
    Panel.Height := AHeight;
  end;
end;

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

procedure TPaneledImage.SetParent(AParent: TWinControl);
begin
  // TEST

  (* if not Assigned(Panel) then exit;

  if Panel.Parent <> AParent then
    Panel.Parent := AParent; *)


  Panel.Parent := AParent;
  if csDestroying in ComponentState then
    inherited SetParent(AParent)
  else
    inherited SetParent(Panel);
end;

procedure TPaneledImage.SetLeft(const Value: Integer);
begin
  inherited Left := 0;
  if Panel.Left <> Value then
    Panel.Left := Value;
end;

procedure TPaneledImage.SetTop(const Value: Integer);
begin
  inherited Top := 0;
  if Panel.Top <> Value then
    Panel.Top := Value;
end;

procedure TPaneledImage.SetHeight(Value: Integer);
begin
  // *** Es könnte passieren, dass wir aufgrund von AutoSize die größe nicht verändenr dürfen!
  inherited Align := alNone;
  inherited Height := Value;
  Value := inherited Height;
  inherited Align := alClient;

  if Panel.Height <> Value then
    Panel.Height := Value;
end;

procedure TPaneledImage.SetWidth(Value: Integer);
begin
  // *** Es könnte passieren, dass wir aufgrund von AutoSize die größe nicht verändenr dürfen!
  inherited Align := alNone;
  inherited Width := Value;
  Value := inherited Width;
  inherited Align := alClient;

  if Panel.Width <> Value then
    Panel.Width := Value;
end;

procedure TPaneledImage.SetAlign(Value: TAlign);
begin
  if Panel.Align <> Value then
  begin
    Panel.Align := Value;
    if (Value = alNone) and AutoSize then
    begin
      Width := Picture.Width;
      Height := Picture.Height;
    end;
  end;
end;

function TPaneledImage.GetLeft: Integer;
begin
  result := Panel.Left;
end;

function TPaneledImage.GetTop: Integer;
begin
  result := Panel.Top;
end;

function TPaneledImage.GetHeight: Integer;
begin
  result := Panel.Height;
end;

function TPaneledImage.GetWidth: Integer;
begin
  result := Panel.Width;
end;

function TPaneledImage.GetAlign: TAlign;
begin
  result := Panel.Align;
end;
Gruß
blackdrake
Angehängte Dateien
Dateityp: zip paneledimage-problem_273.zip (3,2 KB, 1x aufgerufen)
Daniel Marschall
  Mit Zitat antworten Zitat