Lista tframe ed errori nelle free

di il
4 risposte

Lista tframe ed errori nelle free

Buongiorno a tutti, 

ho una finestra con dentro uno scrollbox, dentro questo scrollbox creo n frame a runtime e li aggiungo ad una Tlist.

A volte, e ribadisco a volte, o perlomeno non riesco a capire quando e perchè, quando pulisco la lita quindi quando libero i tframe suggedono cose strane.

O non “sparisce” il frame, o mio da access violation durante la free, o quando crea il frame mi dice che esiste già.

Non riesco ad uscirne,

questo il codice interessato:

per creare la lista di frame


procedure TFrmVars.createListSubid;
var
  i,j,sub: Integer;
  StartValue, EndValue: Integer;
  HexValue: string;
  ListItem: TListItem;
  framesubid:TSubIdFrame;

begin
  StartValue := StrToInt('$' + EdSubFrom.Text);
  EndValue := StrToInt('$' + EdSubTo.Text);

  if not(Assigned(MylstSubid)) then
  begin
   MylstSubid:=TList<TSubIdFrame>.Create;
  end;
  sub:=StartValue;
  for i := 0  to (EndValue-StartValue) do
  begin
    framesubid:=TSubIdFrame.Create(self);
    framesubid.Parent:=Scrollbox;
    framesubid.AutoSize:=True;
    framesubid.Align:=alTop;
    framesubid.top:=i*50+50;
    framesubid.EdSubid.Caption:= Format('0x%.2x', [sub]);
    framesubid.edData.Width:= 27*strtoint(edDlc.Text);
    framesubid.btnData.Left:=framesubid.edData.Left+framesubid.edData.Width+5;
    framesubid.Name:='framesubid_'+IntToStr(i);
    framesubid.dlc:=StrToInt(edDlc.Text);


    framesubid.edData.Caption:=Format('%.2d ', [sub]);
    for j := 1 to framesubid.dlc -1 do
    begin
      framesubid.edData.Caption:=framesubid.edData.Caption+'00 ';
    end;
    if framesubid.edData.Caption.Length>0 then
    begin
     framesubid.edData.Caption:= Copy(framesubid.edData.Caption, 1, Length(framesubid.edData.Caption) - 1);
    end;
    inc(sub);
    MylstSubid.Add(framesubid);
  end;
end;

per la liberazione degli oggetti e pulire la lista


procedure TFrmVars.ClearList;
var
  i: Integer;
  Frame: TSubIdFrame;
begin
  if Assigned(MylstSubid) then
  begin
    for i := MylstSubid.Count - 1 downto 0 do
    begin
      Frame := MylstSubid[i];
      if Assigned(Frame) then
      begin
        try
          Frame.Parent := nil;  // Rimuovi il frame dal suo genitore
          RemoveComponent(Frame);  // Rimuovi il frame dalla lista dei componenti gestiti da Delphi
          FreeAndNil(Frame);  // Libera il frame e imposta il puntatore a nil
        except
          on E: Exception do
          begin
            //ShowMessage('Errore durante la liberazione del frame: ' + E.Message);
          end;
        end;
      end;
    end;
    MylstSubid.Clear; // Dopo aver liberato tutti i frame, svuota la lista
  end;
  RemoveAllSubidFrames;
end;

procedure TFrmVars.RemoveAllSubidFrames;
var
  i: Integer;
  Frame: TComponent;
begin
  for i := Scrollbox.ControlCount - 1 downto 0 do
  begin
    Frame := Scrollbox.Controls[i];

    if Frame is TSubIdFrame then
    begin
      if Pos('framesubid_', Frame.Name) = 1 then
      begin
        Frame.Free;
      end;
    end;
  end;
end;

posso aggiungere l evento onclose della form

procedure TFrmVars.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  try
    ClearList;
    if Assigned(MylstSubid) then
    begin
      MylstSubid.Free;  // Libera la lista dopo aver liberato i frame
      MylstSubid := nil; // Imposta a nil per sicurezza
    end;
  except
    on E: Exception do
    begin
      ShowMessage('Errore durante la chiusura del form: ' + E.Message);
    end;
  end;
end;

a volte non da errori, dopo un tot di volte comincia ad andare di matto, o access violation su FreeAndNil(Frame);

o mi dice che esiste gia un oggetto con quel nome su framesubid:=TSubIdFrame.Create(self);

o li lista ha un numero di item che non ha senso

o a volte rimangono dei frame a vide o e non li cancella, dando errore

, non mi capacito. :/

4 Risposte

  • Re: Lista tframe ed errori nelle free

    26/09/2024 - ziobacco ha scritto:


    a volte non da errori, dopo un tot di volte comincia ad andare di matto, o access violation su FreeAndNil(Frame);

    o mi dice che esiste gia un oggetto con quel nome su framesubid:=TSubIdFrame.Create(self);

    o li lista ha un numero di item che non ha senso

    o a volte rimangono dei frame a vide o e non li cancella, dando errore

    Ci sono diversi errori nel codice. Per dirne qualcuno…

    26/09/2024 - ziobacco ha scritto:


    framesubid:=TSubIdFrame.Create(self);

    Qui perché non usare nil, visto che alla fine ti occupi tu di creare e distruggere i Frame?

    26/09/2024 - ziobacco ha scritto:


    if not(Assigned(MylstSubid)) then begin MylstSubid:=TList<TSubIdFrame>.Create; end; sub:=StartValue; for i := 0 to (EndValue-StartValue) do begin

    Se la lista è già inizializzata, tu vai a inserire nuovi Frame ripetendo il ciclo, quindi creando Frame con lo stesso indice.

    26/09/2024 - ziobacco ha scritto:


    framesubid.Name:='framesubid_'+IntToStr(i);

    Evita di dare un nome al Frame, soprattutto se poi non devi utilizzarlo: impostalo semplicemente a una stringa vuota.

    26/09/2024 - ziobacco ha scritto:


    MylstSubid.Clear; // Dopo aver liberato tutti i frame, svuota la lista end; RemoveAllSubidFrames;

    Dopo aver liberato tutti i Frame, esegui un metodo che rimuove ancora e di nuovo i Frame?

    26/09/2024 - ziobacco ha scritto:


    , non mi capacito. :/

    Ci sono diversi errori formali e tante migliorie da apportare, ad esempio si potrebbe usare una TObjectList al posto di una classica TList, però non ho il tempo materiale di rivedere tutto il codice e correggerlo (anche perché non ho tutto questo tempo libero, per motivi di lavoro): devi razionalizzare e scrivere meglio il codice, e verificare step by step quello che fa rimuovendo le parti inutili, perché l'implementazione potrebbe essere molto più semplici.

    Vedi anche i suggerimenti sopra: secondo me, la maggior parte dei problemi è dovuta proprio a una errata codifica, cioè fai più volte le stesse cose, anche inutilmente, o non le fai quando servono. Va riscritto con maggiore attenzione.

  • Re: Lista tframe ed errori nelle free

    Riesci a commentare cosa sono i nomi che hai dato e a cosa servono?

    Se funziona e non funziona di solito con un contenitore, che sia una lista o combo o qualsiasi contenitore indicizzato ogni volta che togli o aggiungi rischi di saltare l'ordinamento e quindi un access violation per un frame che prima avevi inserito nella lista al nr 4  per poi cancellare il nr 5.

    Ripeto, se crea, elimina e ricrea ma senza un apparente motivo va in access violation è perché stai cercando qualcosa che non esiste. Vai di debug e vedi che valori assumono le variabili in gioco.

  • Re: Lista tframe ed errori nelle free

    @aika: grazie mille per le dritte, provo ad applicarle, Il nome ai frame cmq li do perchè poi mi serve recuperare i click ed i valori che l utente assegna ad alcuni edit che ci sono nei frame.

    il fatto di controllare se la lista fosse assegnata era perchè appunto mi dava errore che esisteva gia. ma da quel metodo ci passa solo dopo essere passato dal metodo clearlist, percui, in teoria, dovrebbe comunque esere vuota, assegnata, ma vuota. ( a parte la prima volta)

    aver creato una procedura che cerca i frame nel tscrollbar mi era nata dal fatto che sulla create del frame mi dava appunto errore che esisteva gia un frame con quel nome, e quindi….si..ci ho buttato la una ricerca dei frame… ma debuggundo cmq non entrava mai nel if… quindi di fatto inutile… concordo..

    TobjectList, al momento evito, non ho molto tempo, se non risolvo provoo ad indagare, ti ringrazio…

    comunque provato a creare i frame con (nil) piuttosto che con (self), sembra che non “impazzisca” piu…

    Grazie mille ^_^

    @sihsandrea: grazie anche a te per la risposta, quello che dici è vero ma noin cancello un frame,m esiste un solo bottone che chiama la procedura clearlist che rimuove tutti i frame ( o dovrebbe) quindi ogni volta che passa dalla procedura createListSubid ( un solo altro bottone) crea da tutti i frame…

  • Re: Lista tframe ed errori nelle free

    27/09/2024 - ziobacco ha scritto:


    @aika: grazie mille per le dritte, provo ad applicarle, Il nome ai frame cmq li do perchè poi mi serve recuperare i click ed i valori che l utente assegna ad alcuni edit che ci sono nei frame.

    Il nome non ti serve a nulla: hai già una lista, puoi usare gli indici o altre informazioni che puoi inserire nella classe del tuo TFrame personalizzato per contenere quello che ti serve, senza ricorrere al nome, e usando peraltro il tipo di dato giusto in base all'informazione che ti serve.

    27/09/2024 - ziobacco ha scritto:


    il fatto di controllare se la lista fosse assegnata era perchè appunto mi dava errore che esisteva gia.

    Questo appunto è un segnale, uno “smell”, che la logica del codice non è corretta.

    27/09/2024 - ziobacco ha scritto:


    ma da quel metodo ci passa solo dopo essere passato dal metodo clearlist, percui, in teoria, dovrebbe comunque esere vuota, assegnata, ma vuota. ( a parte la prima volta)

    Mi sembra un classico “paracadute”: quello che si mette per sicurezza, perché ci si ritrova in condizioni non attese, o non si è sicuri di qual è la situazione nel momento in cui si fa una determinata cosa, e allora si vanno ad aggiungere elementi di contorno superflui che alla fine, oltre a complicare il codice, rischiano di nascondere problemi evidenti e di fare molti più danni di quelli che dovrebbero evitare.

    27/09/2024 - ziobacco ha scritto:


    aver creato una procedura che cerca i frame nel tscrollbar mi era nata dal fatto che sulla create del frame mi dava appunto errore che esisteva gia un frame con quel nome

    Appunto: non usare il nome, e inserisci il campo con l'informazione che metteresti nel nome direttamente nel TFrame. Quando crei un nuovo TFrame, crei una classe discendente, e in quella classe - come in qualsiasi altra - puoi metterci tutto quello che vuoi.

    27/09/2024 - ziobacco ha scritto:


    comunque provato a creare i frame con (nil) piuttosto che con (self), sembra che non “impazzisca” piu…

    Aggiungi il flag ReportMemoryLeaksOnShutdown per verificare che non ci siano “memory leak” (vedi la documentazione).

    Quel “sembra” deve trasformarsi in un “sono sicuro che…”. ;)

Devi accedere o registrarti per scrivere nel forum
4 risposte