Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi EAccessViolation (https://www.delphipraxis.net/123695-eaccessviolation.html)

monty.ms 6. Nov 2008 19:05


EAccessViolation
 
Hallo,

Ich hab ein kleines Problem mit meinem Programm. Ich bekomme bei der Ausführung ständig einen EAccessViolation Fehler. Ich weis dass dies oft bei dynamischen Arrays auftaucht. Ich hab meine mehrfach überprüft und bin der Meinung nirgendwo sollte der Fehler auftreten. Nichts destotrotz hab ich dann einfach die Klasse TObjectList zur Hand genommen, in der Hoffnung - dass sollte ich ein Fehler gemacht haben - dieser dort nicht vorkommt. Aber leider bekomme ich immer noch den selben Fehler.

Hier erstmal der Code:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Init;
  //
end;

procedure TForm1.Init;
begin
  CurrentPath := 'L:\';
  Folders := TStringList.Create;
  ObjectList := TObjectList.Create( True );
  //
end;

// Hier geht es los. Das Ausgehende Verzeichnis wird gesetzt und OpenDir ausgeführt.
procedure TForm1.Button1Click(Sender: TObject);
begin
  CurrentPath := 'L:\';
  OpenDir( CurrentPath );
  //
end;


// Die StringList Folders wird geleert, die bisherigen dargestellten Ordner gelöscht, die Neuen werden ermittelt und angezeigt.
procedure TForm1.OpenDir( Dir: String );
begin
  Folders.Clear;
  DeleteView;
  GetFoldersOfDir( Folders, Dir );
  CreateFolders( Folders, ViewPanel );
  //
end;

procedure TForm1.GetFoldersOfDir( TargetList: TObject; Dir: String );
var SearchRec: TSearchRec;
begin
  if FindFirst(Dir+'*', faDirectory, SearchRec) = 0 then
    begin
      repeat
        if (SearchRec.attr and faDirectory) = faDirectory then
          begin
            If (SearchRec.Name <> '.') and (SearchRec.Name <> '..') Then
              TStringList( TargetList ).Add( SearchRec.Name );
          end;
      until FindNext(SearchRec) <> 0;

      FindClose(SearchRec);
    end;
  //
end;

procedure TForm1.LabelClick(Sender: TObject);
begin
  CurrentPath := CurrentPath + TLabel( Sender ).Caption + '\';
  OpenDir( CurrentPath );
  //
end;

// Erstellt Icon und Label für die Ordner.
procedure TForm1.CreateFolders( TargetList: TObject; TargetPanel: TObject );
var n,i: integer;
begin
  For n := 0 To TStringList( TargetList ).Count-1 Do
    Begin
      i := ObjectList.Add( TImage.Create(Form1) );
      With TImage(ObjectList.Items[i]) Do
        Begin
          Parent := TPanel(TargetPanel);
          // Image1 bleibt die ganze Zeit über.
          Picture.Bitmap := Image1.Picture.Bitmap;
          Left := 4;
          Top := 4*(n+1) + 15*(n);
          Proportional := True;
          Width := 13;
          Height := 13;
          Transparent := True;
        End;

      i := ObjectList.Add( TLabel.Create(Form1) );
      With TLabel(ObjectList.Items[i]) Do
        Begin
          Parent := TPanel(TargetPanel);
          Left := 20;
          Top := 4*(n+1) + 15*(n);
          AutoSize := False;
          Width := 95;
          Height := 15;
          Caption := TStringList( TargetList ).Strings[n];
          Transparent := True;
          Cursor := crHandPoint;
          OnClick := LabelClick;
        End;

      TPanel( TargetPanel ).Height := TLabel(ObjectList.Items[i]).Top+30;
    End;

  // Da der Fehler nur ab und zu eintrat, hab ich als Test das ShowMessage rein getan.
  // Danach tritt der Fehler dann immer auf.
  ShowMessage('*');
  //
end;

// Löscht alle Objekte (Icons und Labels der angezeigten Ordner) aus der ObjectList.
// In der ObjectList sind sonst keine anderen Objekte enthalten
procedure TForm1.DeleteView;
begin
  While ObjectList.Count > 0 Do
    Begin
      // Da ObjectList die Dateien auch besitzt (OwnsObjects = True), gibt er auch
      // die Objekte frei, sobald man sie aus der Liste löscht.
      ObjectList.Delete( 0 );
    End;
  //
end;
Kurz zur Ausführung: Das Programm soll mir alle Ordner in einem Verzeichnis anzeigen. Mit einem Klick auf den Ordner zeigt man wieder die darin befindlichen Ordner an.
Nach der Ausführung von Button1Click wechselt er zum Verzeichnis L:\ und zeigt mir einen Ordner (was auch stimmt). Klicke ich auf diesen, so erstellt er Icons und Labels von allen Ordnern korrekt (die Anzahl stimmt, und er zeigt auch alle an), aber gibt mir dann ein EAccessViolation Fehler. (Ohne das ShowMessage manchmal auch erst in anderen Ordnern)

Hab ich irgendwas übersehen? Im Prinzip macht er ja was er soll, und darum versteh ich auch nicht warum ich am Ende trotzdem den Fehler erhalte.

Danke schonmal für jede Hilfe!

SirThornberry 6. Nov 2008 19:09

Re: EAccessViolation
 
Könntest du bitte die genaue Fehlermeldung posten? Eine AccessViolation ist eine Zugriffsverletzung. Entsprechend sind besonders die Adressen wichtig und auch ob es beim lesen oder schreiben passiert.

monty.ms 6. Nov 2008 19:17

Re: EAccessViolation
 
"Access violation at address 004032CE in module 'Project1.exe'. Read of address FFFFFFD0."

mkinzler 6. Nov 2008 19:18

Re: EAccessViolation
 
Und schau im Debugger, in welcher Zeile der Fehler auftritt

monty.ms 6. Nov 2008 19:21

Re: EAccessViolation
 
Die Zeile springt immer nur auf Application.Run, bzw. auf das end danach

mkinzler 6. Nov 2008 19:23

Re: EAccessViolation
 
Setzt doch einen Breakpoint und steppe dann Zeile für Zeile durch

monty.ms 6. Nov 2008 19:34

Re: EAccessViolation
 
Hab ich gemacht, aber es bleibt dabei. Sobald alle Prozeduren zuende gelaufen sind kommt der Fehler. Also bei keiner Operation eigentlich.

SirThornberry 6. Nov 2008 19:40

Re: EAccessViolation
 
Beim ersten überfliegen bin ich als erstes daran hängen geblieben das du deine Targetlist immer als TObject übergibst. Warum eigentlich? Du castest innerhalb der Funktionen immer auf TStringlist. Warum definierst du dann nicht den Parameter als diesen Typ?

monty.ms 6. Nov 2008 19:53

Re: EAccessViolation
 
Stimmt, hab ich auch gleich mal geändert. Aber leider bleibt das Problem bestehen.

EDIT: Könnte es daran liegen, dass ich vom Label die procedure aus aufrufe, während der Ausführung das Label aber gelöscht wird? Denn wenn ich das löschen der Labels raus nehme, funktioniert es.

Nur leider weis ich nicht wie ich das umgehen kann.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 Uhr.

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