Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Ungültige Zeigeroperation (https://www.delphipraxis.net/159670-ungueltige-zeigeroperation.html)

Moony 7. Apr 2011 15:13

Ungültige Zeigeroperation
 
Hi, zusammen,

ich habe ein Progrämmchen bei dem ich mit einer Hauptform arbeite und innerhalb der Laufzeit wenn benötigt unterschiedliche Frames dynamisch der Hauptform mit

Frame.Parent := fmMain;

zuweise.In den bisherigen Routinen funktioniert das, aber jetzt bei einer neuen Operation funktioniert das Zuweisen eines Frames nicht mehr, obwohl die gleichen Reset-Operationen durchgeführt werden:

Self.Parent := nil;
...

Beim Klick auf ein Image auf der Hauptform wird dann das Startframe zugewiesen:

Frame.Parent := fmMain;
Frame.Left := 0;
Frame.Top := 0;

Beim Zuweisen von fmMain gibt es folgende Fehlermeldung:
Im Projekt ist eine Exception der Klasse EInvalidPointer mit der Meldung 'Ungültige Zeigeroperation' aufgetreten.

Ich habe keine Ahnung warum diese Exception auftritt. Hoffe auf eure schnelle Hilfe....


Danke & Gruß, Moony

stahli 7. Apr 2011 16:47

AW: Ungültige Zeigeroperation
 
Hast Du das Frame vielleicht irgendwo freigegeben?
Setze mal einen Haltepunkt und schau Dir das Frame mal genauer an...

Moony 8. Apr 2011 07:16

AW: Ungültige Zeigeroperation
 
Nee, die Frames werden in der Ondestroy Routine freigegeben. Ich habe einen Haltepunkt gemacht und Assigned(Frame) war nicht nil.

Bummi 8. Apr 2011 07:21

AW: Ungültige Zeigeroperation
 
:glaskugel:
Zitat:

Assigned(Frame)
nicht daß der Fehler von dort kommen müsste, aber ein Assigned heißt nicht dass das Objekt noch da sein muss ...

Moony 8. Apr 2011 07:52

AW: Ungültige Zeigeroperation
 
Ok, aber warum funktioniert es an anderer Stelle mit anderen Frames im Projekt? Wie kann ich dann feststellen, dass ein Frame nicht freigegeben wurde?

ibp 8. Apr 2011 08:07

AW: Ungültige Zeigeroperation
 
Zitat:

Zitat von Bummi (Beitrag 1093833)
:glaskugel:
Zitat:

Assigned(Frame)
nicht daß der Fehler von dort kommen müsste, aber ein Assigned heißt nicht dass das Objekt noch da sein muss ...

Code:
Assigned(Frame)
bedeutet nur, dass Frame <> Nil ist wenn der Ausdruck True ist!

Wie gibst du denn das Frame frei? Mit Free? Wenn ja dann versuch doch mal mit
Code:
FreeAndNil(Frame)

DeddyH 8. Apr 2011 08:12

AW: Ungültige Zeigeroperation
 
Genau, entweder mit FreeAndNil oder nach dem Free Objekt selbst auf nil setzen.

Moony 8. Apr 2011 08:42

AW: Ungültige Zeigeroperation
 
Ok, das kann ich auch versuchen. Aber der Punkt ist, dass zu diesem Zeitpunkt das Frame nicht freigegeben werden soll und somit auch die Routine nicht aufgerufen wird. Wenn ich das Parent vom Frame = nil setze und anschließend einem anderem Frame meine Hauptform als Parent zuweisen will, dann bekomme ich die Zeigerexception.

DeddyH 8. Apr 2011 08:48

AW: Ungültige Zeigeroperation
 
Zitat:

Beim Klick auf ein Image auf der Hauptform wird dann das Startframe zugewiesen:

Frame.Parent := fmMain;
Nur eine Idee:
Delphi-Quellcode:
procedure TfmMain.DeinImageClick(Sender: TObject);
begin
  if Sender is TImage then
    Frame.Parent := TImage(Sender).Parent;

Moony 8. Apr 2011 09:28

AW: Ungültige Zeigeroperation
 
Theoretisch ginge das, aber praktisch nicht, da nicht der Sender als Parent zugewiesen werden muss, sondern die Hauptform.

DeddyH 8. Apr 2011 09:34

AW: Ungültige Zeigeroperation
 
Na dann
Delphi-Quellcode:
Frame.Parent := Application.MainForm;

Moony 8. Apr 2011 10:56

AW: Ungültige Zeigeroperation
 
Nee, hierbei gibt es weiterhin eine Exception.

ConnorMcLeod 8. Apr 2011 11:00

AW: Ungültige Zeigeroperation
 
Kannst Du für uns ein Mini-Beispielprojekt machen?
lg W

stahli 8. Apr 2011 11:32

AW: Ungültige Zeigeroperation
 
Zitat:

Zitat von Moony (Beitrag 1093832)
Nee, die Frames werden in der Ondestroy Routine freigegeben. Ich habe einen Haltepunkt gemacht und Assigned(Frame) war nicht nil.

Kannst Du denn an der Stelle die Frame-Eigenschaften einsehen? Also Frame.Name, Frame.ClassName etc.
Wenn das fehl schlägt, ist Dein Frame vorher zerstört worden.

O.Free (O ist ein Objekt) gibt nur den Speicherbereich frei, so dass dieser wieder neu vergeben werden kann. O (als Zeiger) zeigt aber immer noch auf den bisherigen Speicherbereich (bis O auf nil gesetzt wird).
Wurde der Speicher neu vergeben (z.B. für Stringvariablen) und wird auf O wieder zugegriffen, dann gibt es i.d.R. eine Exception.

DeddyH 8. Apr 2011 11:51

AW: Ungültige Zeigeroperation
 
Aber würde in dem Fall nicht eher eine AV kommen statt Invalid Pointer?

Moony 8. Apr 2011 16:52

AW: Ungültige Zeigeroperation
 
Ich habe den Fehler gefunden, aber noch nicht die Lösung. Es liegt an meinem mehrdimensionalem Array.

Bei fmMain.OnCreate rufe ich eine Routine auf, die ein CSV File einliest und in ein mehrdimensionales Array schreibt. Das sieht so aus:
Delphi-Quellcode:
function GetLanguages: Boolean;
var
  Txt         : String;
  LstValues,
  LstFile     : TStringList;
  i, cnt, j,
  FillCnt     : Integer;
begin
  Result := false;
  if not FileExists(ChangeFileExt(Application.ExeName, '.lng')) then
    Exit;

   TraceFile(DateTimeToStr(Now()) + ' - ' + TRACESYS + ': Sprachdatei wird eingelesen');
   // LanguageFile einlesen
   LstValues := TStringList.Create;
  LstFile  := TStringList.Create;
   try
      LstFile.Delimiter := ';';
      LstValues.Delimiter := ';';
    LstFile.Clear;
    LstFile.LoadFromFile(ChangeFileExt(Application.ExeName, '.lng'));
    Txt := LstFile.Strings[0];

      GetValues(Txt, LstValues);
      myLangList.CommaText := LstValues.CommaText;
      myLangList.Delete(0);

      SetLength(myLangValues, LstFile.Count, LstFile.Count); // Speicher für Spracharray reservieren: array of array of String

      cnt := 0; // Zähler für den ValueIndex
    for i := 1 to LstFile.Count - 1 do
    begin
         Txt := LstFile.Strings[i];

         GetValues(Txt, LstValues);
      while LstValues.Count > (myLangList.Count+1) do
         LstValues.Delete(LstValues.Count - 1);

      FillCnt := (myLangList.Count+1) - LstValues.Count;
         for j := 0 to LstValues.Count - 1 do
      begin
         if LstValues.Strings[j] = '' then
               myLangValues[cnt, j] := LstValues.Strings[0]
        else myLangValues[cnt, j] := LstValues.Strings[j];
      end;

      if FillCnt > 0 then
      begin
        for j := LstValues.Count to myLangList.Count do
          myLangValues[cnt, j] := LstValues.Strings[0];
      end;

         Inc(cnt);
    end;
  finally
     LstFile.Free;
    LstValues.Free;
  end;
end;
Wenn ich diese Routine nicht verwende habe ich keine Probleme. Ich habe bereits behoben, dass falls eine Zeile nicht alle Werte wie die erste hat, dann fülle ich mit dem ersten Wert auf (das ist eine ID).

nichts desto trotz bekomme ich hierbei eine exception.

DeddyH 8. Apr 2011 18:56

AW: Ungültige Zeigeroperation
 
Ohne da jetzt durchgestiegen zu sein, wie sieht es so aus (ungetestet)? Allerdings fülle ich nichts auf, da mir die Länge der längsten Zeile ja nicht im Voraus bekannt ist.
Delphi-Quellcode:
function GetLanguages: Boolean;
var
  LstValues, LstFile: TStringList;
  i, j: Integer;
  Filename: string;
begin
  Result := false;
  Filename := ChangeFileExt(Application.ExeName, '.lng');
  if not FileExists(Filename) then
    Exit;
  TraceFile(DateTimeToStr(Now()) + ' - ' + TRACESYS +
    ': Sprachdatei wird eingelesen');
  // LanguageFile einlesen
  LstFile := TStringList.Create;
  try
    LstFile.LoadFromFile(Filename);
    LstValues := TStringList.Create;
    try
      LstValues.Delimiter := ';';
      LstValues.StrictDelimiter := true; //ggf. weglassen
      SetLength(myLangValues, LstFile.Count);
      for i := 0 to LstFile.Count - 1 do
        begin
          LstValues.DelimitedText := LstFile[i];
          SetLength(myLangValues[i], LstValues.Count);
          for j := 0 to LstValues.Count - 1 do
            myLangValues[i, j] := LstValues[j];
        end;
      Result := true;
    finally
      LstValues.Free;
    end;
  finally
    LstFile.Free;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr.

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