GELÖST : Zeile aus TextFile löschen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
Zvoni
Beiträge: 401
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zeile aus TextFile löschen

Beitrag von Zvoni »

Bernie110 hat geschrieben: Mo 26. Aug 2024, 13:50
Ok akzeptiert. Ich verrenne mich da in einen falschen Code. Schon verstanden.
Im Prinzip, möchte ich jeden Formularnamen von jedem Formular, welches aktuell geöffnet ist, in einer Liste angezeigt bekommen. siehe : CheckListBox1

Mittels Flag in der CheckListBox1 möchte ich bestimmen, welches Formular geschlossen werden soll.

Ich habe ein Textfile angelegt. Jedes geöffnete Formular fügt dort seinen Namen an.
Wird ein Formular geschlossen, wird der Name des Forms aus der Textfile gelöscht.
Um gleichzeitig mehrere Formular schließen zu können gibt es ein Formular mit dieser checklistbox1
Die ChecklistBox1 wird mittels dieser Textfile befüllt.
So werden nun alle geöffneten Formular-Namen dort angezeigt.

Der Code soll nun die Checklistbox1 durchlaufen und die mit Haken gekennzeichneten Formularnamen schliessen´und dann diesen Formnamen aus der Textfile löschen.

Und ich versuchte zu fragen, wie man einen Variable für einen Formnamen definiert.
irgend wie so :
VariableFormName = Flag_ja_in_Checklistbox1
VariableFormName.close;


Lg Bernie
Dann stelle ich jetzt mal die provokative Frage: Wozu brauchst du überhaupt ein Textfile?!?!?!
Ein Textfile macht nur Sinn, wenn du den "Zustand" über "Sessions" hinweg speichern willst.

Ich würde einfach Stumpf einen Zeiger auf die (geöffneten) Formulare in Objects von Items speichern.
Die "Items" selbst kann die Caption (oder was auch immer) des jeweiligen Formulars sein.

Und es wurde bereits erwähnt: Wenn du eine Liste durchläufst, in welcher nach deinen Kriterien ("Checked") der COUNT verändert wird: Immer rückwärts durch die Liste.
Ist das einfachste der Welt, da du den Count nicht im Auge behalten musst.

Aircode (Keine Zeit jetzt echten Code zu schreiben)
Setzt voraus, dass beim öffnen eines jeweiligen Formulars ein entsprechends AddObject ausgeführt wird

Code: Alles auswählen

//Öffnen von Formulare --> In OnCreate des jeweilgen Formulars
//Oder was auch immer in der Checklist angezeigt werden soll
frmÜbersicht.MyCheckList.Items.AddObject(Self.Caption, Self);
//frmÜbersicht.MyCheckList.Items.AddObject('Das ist eine Caption', Self);
frmÜbersicht.MyCheckList.Invalidate; //Wegen neu zeichnen? Bin mir gerade nicht sicher


//schliessen von Formularen gemäss Checked-Status
For i:=MyCheckList.Items.Count-1 DownTo 0 Do
   Begin
      If MyCheckList.Checked[i] Then 
        Begin
          TForm(MyCheckList.Items.Objects[i]).Close;
          MyCheckList.Items.Objects[i].Free;
          MyCheckList.Items[i].Delete;
        End;
   End;
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

Zvoni hat geschrieben: Mo 26. Aug 2024, 14:10 Dann stelle ich jetzt mal die provokative Frage: Wozu brauchst du überhaupt ein Textfile?!?!?!
Hi Zvoni, danke für deine Antwort.
Die CheckListBox1 ist in einem seperatem Form mit dem Namen Frm_Admin_OpenForms. Es ist geschlossen wenn die andere Forms geöffnet werden.
Sind dann 10 FOrmulare offen, wollte ich es öffnen und eben darüber die geöffneten Forms mit einer select Möglichkeit schliessen.
Daher dachte ich es ist wohl besser wenn man das ausslagert und in eine Textfile schreibt. ( oder in was auch immer )
In MS Access hab ich so was in eine Locale Tabelle geschrieben.
In meinem Main Form aus dem ich die anderen Formulare öffne, wollte ich die CheckListBox1 nicht haben.

Der Code wir deshalb auch nicht funktionieren oder ?

Code: Alles auswählen

procedure TFrm_USER_UEBERSICHT.FormCreate(Sender: TObject);

begin
    Frm_Admin_OpenForms.CheckListBox1.Items.AddObject(Self.name, Self);
    Frm_Admin_OpenForms.CheckListBox1.Invalidate;
end; 
Edit. Aber man könnte das Formular mit der ChecklistBox auch nur mit Show öffnen und verstecken.
Somit würde das auch funktionieren.
Dann müsste man nur für den Fall, dass man das CheckListBox1 Formular nicht benutzt und die einzelnen geöffneten anderen Formulare manuell schliesst, auch den jeweiliegen Eintrag in der CheckListBox1 wieder löschen oder ?

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1207
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Zeile aus TextFile löschen

Beitrag von kralle »

Moin,

schaue Dir mal die PDF zum Thema "Globale Variablen"
viewtopic.php?p=142857#p142857
an.
Besonders die letzte Lösung.
Dann brauchst Du kein Textfile mehr.

Gruß Heiko
OS: MX Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

Ok ich glaub jetzt hab ichs :

Bei den ganzen normalen FOrms gebe ich folgende COdes ein :


Bei Create :

Code: Alles auswählen

procedure TFrm_USER_UEBERSICHT.FormCreate(Sender: TObject);

begin
    Frm_Admin_OpenForms.CheckListBox1.Items.AddObject(Self.name, Self);
    Frm_Admin_OpenForms.CheckListBox1.Invalidate;
end;  
Bei CLose :

Code: Alles auswählen

procedure TFrm_USER_UEBERSICHT.FormClose(Sender: TObject;
  var CloseAction: TCloseAction);

begin
    if  Frm_Admin_OpenForms.visible = false then
    begin
    Frm_Admin_OpenForms.CheckListBox1.Items.Delete(Frm_Admin_OpenForms.CheckListBox1.Items.IndexOf(Self.name));
    end;

     inherited;
     Closeaction := caFree;

end;   
im Form mit der Checklist :

Code: Alles auswählen

procedure TFrm_Admin_OpenForms.BitBtn1Click(Sender: TObject);
  var
    i : Integer;
begin
  For i:=CheckListBox1.Items.Count-1 DownTo 0 Do
   Begin
      If CheckListBox1.Checked[i] Then
        Begin
          TForm(CheckListBox1.Items.Objects[i]).Close;
          CheckListBox1.Items.Objects[i].Free;
        End;


   End;
    CheckListBox1.DeleteSelected ;
end; // Ende Sub   


Scheint zu funktionieren. Bisher ist kein Fehler aufgetaucht. Genau so hätte ichs mir vorgstellt.. @Zvoni danke.
Jemand einen Einwand ?

Lg Bernie

@Kalle danke ;)

Benutzeravatar
Zvoni
Beiträge: 401
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zeile aus TextFile löschen

Beitrag von Zvoni »

Bin mir gerade nicht sicher, ob du im zweiten codeblock ein Speicher leck hast --> https://lazarus-ccr.sourceforge.io/docs ... bject.html
An object added to the list is not automatically destroyed by the list when the list is destroyed or the string it is associated with is deleted. It is the responsibility of the application to destroy any objects associated with strings.
Im zweiten code block ist die if-abfrage falsch: du kannst ja eine form so oder so immer selbst schliessen.
Das entfernen aus der liste sollte immer stattfinden (mit entsprechendem check indexof vorher)
Hätte sowas erwartet (ungetestet):
Wobei mir klar ist, dass dies in die Hose gehen kann, da OnClose ja auch aus der CheckListBox aufgerufen wird.
Da muss dann der dritte Code-Block ggfs. angepasst werden.
Da würde dann die Zeile mit "Close" reichen

Code: Alles auswählen

procedure TFrm_USER_UEBERSICHT.FormClose(Sender: TObject;  var CloseAction: TCloseAction);
Var i:Integer;
begin
    i:=Frm_Admin_OpenForms.CheckListBox1.Items.IndexOf(Self.name);
    Frm_Admin_OpenForms.CheckListBox1.Items.Objects[i].Free;  //Nach reiflicher Überlegung bin ich mir auch gerade nicht sicher, ob das hier zu einem zweimaligen "Free" führt --> RefCount?
    Frm_Admin_OpenForms.CheckListBox1.Items.Delete(i);
    Frm_Admin_OpenForms.CheckListBox1.Invalidate;
    Closeaction := caFree;
end;  

procedure TFrm_Admin_OpenForms.BitBtn1Click(Sender: TObject);
  var
    i : Integer;
begin
  For i:=CheckListBox1.Items.Count-1 DownTo 0 Do
   Begin
      If CheckListBox1.Checked[i] Then
        Begin
          TForm(CheckListBox1.Items.Objects[i]).Close;
          //CheckListBox1.Items.Objects[i].Free;  //--> wird nicht benötigt, da der "Free" in OnClose der jeweiligen Form stattfindet
        End;
   End;
    //CheckListBox1.DeleteSelected ;  //--> Wird auch nicht mehr benötigt, da jede Form sich selbst aus der Liste entfernt
end; // Ende Sub   

 
Im 3. code-block fehlt das delete

EDIT: Ah....sehe gerade das DeleteSelected im 3. Code-Block
Zuletzt geändert von Zvoni am Mi 28. Aug 2024, 08:29, insgesamt 1-mal geändert.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

Hi merci nochmals für deinen Beitrag.
Bei

Code: Alles auswählen

Var i:Integer;
begin
    i:=Frm_Admin_OpenForms.CheckListBox1.Items.IndexOf(Self.name);
    [b]Frm_Admin_OpenForms.CheckListBox1.Items.Objects(i).Free;[/b]  //Nach reiflicher Überlegung bin ich mir auch gerade nicht sicher, ob das hier zu einem zweimaligen "Free" führt --> RefCount?
    Frm_Admin_OpenForms.CheckListBox1.Items.Delete(i);
    Frm_Admin_OpenForms.CheckListBox1.Invalidate;
    Closeaction := caFree;


Hier läuft er in einen Fehler :
user_uebersicht_u.pas(180,52) Error: Wrong number of parameters specified for call to "GetObject" :?:

Ohne das Frm_Admin_OpenForms.CheckListBox1.Items.Objects(i).Free; funktioniert es, auch bei mehreren Formularen, ohne Fehler.
Lg Bernie

wp_xyz
Beiträge: 5192
Registriert: Fr 8. Apr 2011, 09:01

Re: Zeile aus TextFile löschen

Beitrag von wp_xyz »

Objects ist ein Array-Property, daher musst du eckige Klammern verwenden:

Code: Alles auswählen

  Frm_Admin_OpenForms.CheckListBox1.Items.Objects[i].Free; 
Aber: Du musst hier höllisch aufpassen, dass ab hier nicht mehr auf das Formular, das in Objects[ i ] gespeichert war, zugegriffen wird. Weiter oben hat z.B. das Formular Frm_User_Uebersicht sich selbst als Object der CheckListbox des Frm_Admin_OpenForms hinzugefügt. Der obige Code gibt das Frm_User_Uebersicht frei, die Variable "Frm_User_Uebersicht" existiert aber weiterhin, nun mit ungültigem Inhalt. Wenn du jetzt irgendwann noch auf Frm_User_Uebersicht zugreifst, hast du einen wunderbaren Absturz...

Benutzeravatar
Zvoni
Beiträge: 401
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zeile aus TextFile löschen

Beitrag von Zvoni »

wp_xyz hat geschrieben: Di 27. Aug 2024, 19:06 Objects ist ein Array-Property, daher musst du eckige Klammern verwenden:

Code: Alles auswählen

  Frm_Admin_OpenForms.CheckListBox1.Items.Objects[i].Free; 
Aber: Du musst hier höllisch aufpassen, dass ab hier nicht mehr auf das Formular, das in Objects[ i ] gespeichert war, zugegriffen wird. Weiter oben hat z.B. das Formular Frm_User_Uebersicht sich selbst als Object der CheckListbox des Frm_Admin_OpenForms hinzugefügt. Der obige Code gibt das Frm_User_Uebersicht frei, die Variable "Frm_User_Uebersicht" existiert aber weiterhin, nun mit ungültigem Inhalt. Wenn du jetzt irgendwann noch auf Frm_User_Uebersicht zugreifst, hast du einen wunderbaren Absturz...
Das ist genau der Grund, warum ich oben im Code-Kommentar geschrieben habe, ob es zu einem doppelten Free kommt
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

Hallo Ihr beiden.
vielen herzlichen Dank für die Erklärungen. Hat mir sehr weiter geholfen.!!!
Ich denke das passt so jetzt.
Lg Bernie

Antworten