Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi AccessViolation mit Checkbox aber warum? (https://www.delphipraxis.net/58590-accessviolation-mit-checkbox-aber-warum.html)

lucius 9. Dez 2005 11:06


AccessViolation mit Checkbox aber warum?
 
Guten Tag Delphianer,

Ich habe einige Checkboxen womit ich verschiedene Kategorieen (TV - Kids, DVD-r unsw) einer Listview anzeichen und ausblenden moechte.
Jetzt mache ich das mittels StringListen, bei einem Click auf die Checkbox wird geprueft ob Sie markiert ist oder nicht und der Entsprechende Code wird dan ausgefuehrt.
Standard sind die Checkboxen markiert(Checked := true).
Hier mein Code von einer Checkbox:
Delphi-Quellcode:
procedure THaupt.KidsClick(Sender: TObject);
var
z, i : Integer;
slLines, slFields, FieldList : TStringList;
begin
if Kids.Checked = false then
  begin
    slFields := TStringList.Create;
    slLines := TStringList.Create;
      for z := ListView.Items.Count-1 downto 0 do
        if ListView.Items[z].SubItems[1] = 'TV - Kids' then
          begin
            slFields.Assign(Listview.Items[z].SubItems);
            slFields.Insert(0, Listview.Items[z].Caption);
            slLines.Add(slFields.CommaText);
            ListView.Items[z].Delete;
          end;
      Listview.Invalidate;
      showmessage(slLines.CommaText); //<-- Items in StringListe werden korrekt angezeigt//
  end
  else
  begin
    FieldList := TStringList.Create;
      for i := 0 to Pred(slLines.Count) do //<-- Ab hier gibt es eine AccessViolation//
        begin
          FieldList.CommaText := slLines[i];
            with ListView.Items.Add do
              begin
                Caption := FieldList[0];
                FieldList.Delete(0);
                SubItems.Assign(FieldList);
              end;
        end;

  slLines.Free;
  slFields.Free;
  FieldList.Free;
  end;
end;
Wenn die Checkbox demarkiert ist und ich wieder die Checkbox clicke gibt es eine AccesViolation ab der Zeile wie oben beschrieben im Code.
Meine Frage lautet wie kann das sein?
Vielen Dank im voraus.

MFG Lucius.

chaosben 9. Dez 2005 11:11

Re: AccessViolation mit Checkbox aber warum?
 
Ich behaupte mal ganz locker, das du eine Warnung erhältst, die etwa so lautet:
"slLines könnte undefiniert sein"

Also der Fehler ist: Du greifst im "else"-Zweig auf slLines zu. Du erzeugst es aber nur im If-Zweig. Daher kann er im else-Zweig nur fehlerbehaftet darauf zugreifen. :)

lucius 9. Dez 2005 11:20

Re: AccessViolation mit Checkbox aber warum?
 
Hi chaosben, deine Behauptung stimmt nicht ganz.
Zitat:

"slLines könnte undefiniert sein"
Ich loesche ja erst die TStringListe in dem else Zweig
Delphi-Quellcode:
slLines.Free;
slFields.Free;
FieldList.Free;
also muessten die Items doch noch im else Zweig vorhanden sein wenn ich Sie wieder in der Listview anzeigen moechte?

Gruss Lucius.

RavenIV 9. Dez 2005 11:24

Re: AccessViolation mit Checkbox aber warum?
 
nur mal so als Denkanstoss:
und wann wird slLines angelegt?

lucius 9. Dez 2005 11:28

Re: AccessViolation mit Checkbox aber warum?
 
Hallo RavenIV,
Zitat:

und wann wird slLines angelegt?
Delphi-Quellcode:
if Kids.Checked = false then
  begin
    slFields := TStringList.Create;
    slLines := TStringList.Create; //<---- Hier//
oder verstehe ich dich falsh?

chaosben 9. Dez 2005 11:34

Re: AccessViolation mit Checkbox aber warum?
 
oh Mann .. du kostest mich Nerven :stupid:

slLines ist eine lokale Variable und wird nur im If-Zweig erstellt. Daher kannst du nur im IF-Zweig unbeschadtet auf dieses Objekt zugreifen. Wenn du es im Else-Teil tust, kommt eine AV.

Und meine angedeutete Warnung ist eine, die vom Compiler kommt. Nicht vom Exception-Handling.

Die einfachste und sicherste Lösung ist folgende:
Delphi-Quellcode:
procedure THaupt.KidsClick(Sender: TObject);
var
z, i : Integer;
slLines, slFields, FieldList : TStringList;
begin
  try
    slLines := TStringList.Create; //<--- Vor dem If erzeugen
    if Kids.Checked = false then
      begin
        slFields := TStringList.Create;
       
          for z := ListView.Items.Count-1 downto 0 do
            if ListView.Items[z].SubItems[1] = 'TV - Kids' then
              begin
                slFields.Assign(Listview.Items[z].SubItems);
                slFields.Insert(0, Listview.Items[z].Caption);
                slLines.Add(slFields.CommaText);
                ListView.Items[z].Delete;
              end;
          Listview.Invalidate;
          showmessage(slLines.CommaText);
      end
      else
      begin
        FieldList := TStringList.Create;
          for i := 0 to Pred(slLines.Count) do  //<--- Und hier unbeschadet verwenden
            begin
              FieldList.CommaText := slLines[i];
                with ListView.Items.Add do
                  begin
                    Caption := FieldList[0];
                    FieldList.Delete(0);
                    SubItems.Assign(FieldList);
                  end;
            end;
   
     
      slFields.Free;
      FieldList.Free;
      end;
    end;
  finally
    slLines.Free; //<--- und in jedem Falle freigeben
  end;
end;

Union 9. Dez 2005 11:37

Re: AccessViolation mit Checkbox aber warum?
 
Kids.Checked ist beim Start, wie Du sagtest = false. Wenn Du nun das erste Mal clickst, läuft er in den else Zweig und slLines ist nicht initialisiert. Bei Deiner Lösung müsstest Du die Stringlisten-Objekte Global deklarieren, sonst funktioniert der else nie!

chaosben: Du Schneller...

lucius 9. Dez 2005 11:44

Re: AccessViolation mit Checkbox aber warum?
 
Habs Global deklariert und jetzt gehts, dummer Denkfehler entschuldigung dafuer.
Danke fuer eure Hilfe und Antworten.

Lucius.

chaosben 9. Dez 2005 11:46

Re: AccessViolation mit Checkbox aber warum?
 
Für Denkfehler braucht man sich nicht entschuldigen. Die kommen einfach vor. Und bei Unsereins alle Weile. :stupid:

//edit: Die Methode, es global zu deklarieren ist unschön, denn dadurch belegst du unnötig lange Speicherplatz, den du nicht nutzt.

lucius 9. Dez 2005 11:58

Re: AccessViolation mit Checkbox aber warum?
 
Hi chaosben, kann ich auch noch irgendwie im Code einbauen das er sich den ListviewIndex merkt von dem Item das rausgenommen wird und es spaeter wieder an der selben Stelle einfuegt?
Delphi-Quellcode:
if ListView.Items[z].SubItems[1] = 'TV - Kids' then
    begin
      slCheckFields.Assign(Listview.Items[z].SubItems);
      slCheckFields.Insert(0, IntToStr(z) + Listview.Items[z].Caption); //IntToStr(z)//
      slCheckLines.Add(slCheckFields.CommaText);
      ListView.Items[z].Delete;
    end;
Besten Dank.

MFG Lucius.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:01 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz