Problema de POO - Recursividade

08/05/2020

5

Delphi 10.3 Rio, Windows 10 x32

Como estou sozinho nesta empreitada descobri uma complicação em POO. Vê ai se pode me ajudar em alguma coisa e acredito que alguém já deve ter se deparado com isto. Eu tenho um fragmento de código abaixo.

Está ocorrendo o seguinte: Baeado na classe ancestral TFrame eu herdei ela. Porem eu tive que usar uma propriedade Width ou Heigth na classe filha. O que ocorre é que ao usar self.Width ela entra em recursividade (uma entra dentro da outra e estoura a pilha fazendo o delphi fechar sem dar erro algum. Isto logo quando coloco o componente criado no formulário. Descrobri isto.

A pergunta que faço é como eu posso usar o SetWidth que preciso ajustar algumas propriedades antes de passar o valor novo de witdth ao componente?

Tentei até colocar reintroduce em SetWidth, mas nem sei se este método existe na classe TFrame e não ví diferença alguma e acho que nem faz sentido.

Const
   MIN_WIDTH: Integer = 70;

type
  TProgressCard = class(TFrame)
  private
    FWidth: Integer;
    procedure SetWidth(const Value: Integer);
    { Private declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    property Width: Integer read FWidth write SetWidth;
  end;

implementation

{$R *.dfm}

procedure Register;
begin
  RegisterComponents(''Delwie'', [TProgressCard]);
end;

constructor TProgressCard.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWidth:= 200;
  Self.Width:= FWidth;
end;

//esta funcao faz fechar o delphi...porque??
procedure TProgressCard.SetWidth(const Value: Integer);
begin
  //entra com zero e depois o valor e fica intermitente na tela
  //showmessage(Self.Width.ToString); 
  if Value > MIN_WIDTH then begin
     FWidth := Value;
     Self.Width:= FWidth;  //quando executa isto primeiro é zero, e depois o valor certo e executa infinitamente
  end;
end;


Como faço para solucionar isto nesta modalidade de POO?

Se puderem me dar um exemplo de ajustar este fragmento ajudaria mais ainda.
Responder

Posts

vejamos as declarações:
// propriedade Width
property Width: Integer read FWidth write SetWidth;

// procedure SetWidth
procedure TProgressCard.SetWidth(const Value: Integer);
begin
  //entra com zero e depois o valor e fica intermitente na tela
  //showmessage(Self.Width.ToString); 
  if Value > MIN_WIDTH then begin
     FWidth := Value;
     Self.Width:= FWidth;
  end;
end;

o que acontece:
Quando a propriedade Width é alterada, ela dispara a procedure SetWidth.
Daí a procedure SetWidth altera a propriedade Width (Self.Width:= FWidth;) que, ao ser alterada, dispara a procedure SetWidth, entrando num loop infinito.

Pra resolver é simples. é preciso somente alterar a procedure SetWidth:
procedure TProgressCard.SetWidth(const Value: Integer);
begin
  if (Value >= MIN_WIDTH) then
  begin
    FWidth := Value;
    TControl(Self).Width := FWidth; // TControl em Vcl.Controls
  end;
end;
desta forma (TControl(Self).Width) será chamada a procedure SetWidth de TControl, não de TProgressCard, evitando assim o loop infinito.
Responder
Muito obrigado Emerson, eu não tinha me recordado disto que TFrame tinha a classe ancestral TControl. Desta forma não gera a recursividade. Deu certo e funcionou perfeito. Grato pela ajuda.
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar