Autor Beitrag
MasterHiggins
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Do 13.02.03 15:49 
Ich erzeuge zur Laufzeit eine Reihe von Buttons.
Nun will ich aber diese zur Laufzeit wieder löschen um sie anschließend wieder ganz neu aufbauen zu können.

Wie mache ich das ?

Wenn ich MyButton.Destroy sage, gibt mir Delphi ein EAccessViolation Fehler aus.

Was mache ich falsch??

Danke im voraus

MasterH
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 13.02.03 16:00 
Versuchs mal mit myButton.Free
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Do 13.02.03 16:05 
erstmal danke, aber leider gibts denselben Fehler!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 13.02.03 16:21 
Geht:
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    MyButton: TButton;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyButton := TButton.Create(Form1);
  MyButton.Parent := Form1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyButton.Free;
end;
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Do 13.02.03 16:29 
Jetzt habe ich es auch mal über einen Button gemach (vorher über ne eigene Prozedur) und dann gehts...

Muß mal noch rumprobieren, ist bestimmt nur ein Denkfehler meinerseits

Danke
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Fr 14.02.03 09:19 
MasterHiggins hat folgendes geschrieben:
Jetzt habe ich es auch mal über einen Button gemach (vorher über ne eigene Prozedur) und dann gehts...

Über ein Button?

MasterHiggins hat folgendes geschrieben:
Muß mal noch rumprobieren, ist bestimmt nur ein Denkfehler meinerseitsDanke

Poste doch mal den Code mit dem Du den Button erzeugst und den mit dem Du den Button wieder freigibst!

Gruß
TINO
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Fr 14.02.03 09:22 
Mache ich gerne, allerdings will ich da vorher unbedingt noch eine Verallgemeinerung reinkriegen, weil sonst sinds so ca. 4 Seiten :wink:
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 14.02.03 09:29 
Kann es sein, dass deine Variable vom Typ TButton lokal ist?
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Fr 14.02.03 10:16 
Ehrlich gesagt habe ich noch nicht verstanden worauf Du hinaus willst, weil beim Button geht es ja!

Aber mein Button ist als ganz globale Variable in Form1 deklariert.
Bin gerade wie gesagt am verallgemeinern (habe dazu noch zwei andere Themen "am laufen": "restart the programm" und "TObject(STRING)")

Sieht aber alles ganz gut aus soweit, denke, dass ich im laufe des späten Vormittags meinen Quellcode mal posten kann.

Danke aber schon mal für Deine Mühe, dieses Forum ist echt RICHTIG hilfreich.
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Fr 14.02.03 12:35 
Hier jetzt die wichtigen Auszüge aus meinem Quelltext, hoffe habe nix vergessen:



ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
...

procedure TForm1.FormCreate(Sender: TObject);

begin
   form1.inieinlesen;
   offen:=TRUE;
end;

...

Procedure TForm1.erzeugen;
VAR
   i,hoehe:INTEGER;
Begin
   hoehe:=10;
   FOR i:=1 TO menuzeilen DO BEGIN
      ebutton[i]:=TBitBtn.Create(self);
      ebutton[i].Left:=20;
      ebutton[i].Top:=i*43;
      ebutton[i].Parent:=Form1;
      ebutton[i].Caption:=menudefinition[i,1];
      ebutton[i].Height:=33;
      ebutton[i].Width:=105;
      hoehe:=hoehe+ebutton[i].Height;
      ebutton[i].Font.Name:='Arial';
      ebutton[i].Font.Size:=8;
      ebutton[i].Font.Style:=[fsBold];
      ebutton[i].Tag:=i;
      IF FileExists(menudefinition[i,3])=TRUE THEN BEGIN
         ebutton[i].Glyph.LoadFromFile(menudefinition[i,3]);
      END;
         ebutton[i].OnClick:=ausfuehren;
   END;
   Form1.Width:=155;
   Form1.Bevel1.Left:=0;
   Form1.Bevel1.Width:=Form1.Width-9;
   Form1.Height:=hoehe+130;
END;

procedure TForm1.ausfuehren(sender:TObject);
   var i:integer;
begin
   i := (sender as TBitBtn).tag;
   WinExec(PChar(menudefinition[i,2]), SW_NORMAL);
end;

procedure TForm1.loeschen;
VAR
   y:INTEGER;
begin
   IF offen THEN BEGIN
      FOR y:=1 TO menuzeilen+1 DO BEGIN
         ebutton[y].Free;
      END;
   END;
   Form1.erzeugen;
end;

...
// ini-Datei einlesen
...
   IF offen THEN Form1.loeschen;
   Form1.erzeugen;
End;



Habe jetzt damit aber noch ein Problem:

das "löschen" der Buttons klappt, will ich jetzt aber zur LAUFZEIT die ini-datei neu einlesen, dann gibts einen EAccesViolation, aber erst nachdem die Buttons erfolgreich gelöscht wurden.
Zum neu einlesen gehe ich wie folgt vor (über einen Button auf einer Form2):

1. Form1.inieinlesen
2. Form1.loeschen
3. Form1.erzeugen

Irgeneine Idee?

Probier aber auch noch mal selber rauszukriegen an welcher Stelle genau.
MasterHiggins Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64



BeitragVerfasst: Fr 14.02.03 14:01 
Habe den Fehler gefunden, war ein Logik-Fehler:

Habe erst die geänderte ini-Datei eingelesen und danch die Buttons gelöscht, d.h. er hat unter Umständen versucht nicht exisitierende Buttons zu löschen, was dann zu diesem EAccessViolation-Fehler führte.


Tausend Dank

MasterH
Brueggendiek
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 304

Win 98, Win98SE, Win XP Home
D5 Std
BeitragVerfasst: Mo 17.02.03 01:00 
Hallo!

Objekte in globalen Variablen sollte man immer mit FreeAndNil löschen - oder nach Free den Zeiger auf Nil setzen.

Free kann nämlich auch auf Nil-Zeiger angewandt werden - aber nicht, wenn das Objekt freigegeben wurde! Leider setzt Free den Zeiger nicht auf Nil.

Wenn in einer Prozedur z.B. eine Stringlist als lokale Variable deklariert ist, die erzeugt und wieder freigegeben wird, reicht am Ende Free - danach existiert die Variable ja nicht mehr.

Wenn die Möglichkeit besteht, daß ein Zeiger nicht initialisiert ist, immer vorher auf Nil testen und beim Freigeben auf Nil setzten. Sonst fängt man sich schwer zu findende Fehler ein, da je nach Aufrufreihenfolge der Zeiger mal korrekt und mal falsch ist.

Gruß

Dietmar Brüggendiek