![]() |
Komponenten löschen > Abstracter Fehler
Hallo,
ich erzeuge sehr viele komponenten zu laufzeit das mache ich so:
Delphi-Quellcode:
und jeztt möchte ich die komponenten löschen und zwar über einen button der dieser komonente gehört.
procedure Add_PlaylistPanel(Caption:String;L,T:Integer; ScrollBox:TJvscrollbox);
var panel:TJvCaptionPanel; sp:TJvBitBtn; clb:TJvCheckListBox; str:String; begin Form1.Show; // panel hinzufügen panel:=TJvCaptionPanel.Create(Form1); Panel.left:=l; Panel.Top:=t; Panel.Width:=129; Panel.Height:=298; Panel.Parent:=Scrollbox; panel.Visible:=True; Panel.CaptionPosition:=dpTop; Panel.Caption:=caption; str:=IntTostr(form1.JvPageControl1.PageCount)+IntTostr(ScrollBox.ControlCount-1); Panel.tag:=StrToInt(str); panel.name:='Panel'+str; .... Jedes mal wenn ich es tuen möchte gibt es eine fehlermeldung: Abstackter Fehler löschen wollte ich es so:
Delphi-Quellcode:
Für lösungen währe ich dankbar !
procedure TForm2.PanelFree(Sender:Tobject);
var test:TWinControl; begin (Sender as TWinControl).Parent.parent:=nil; (Sender as TWinControl).Parent.Free; // test.free; end; |
Re: Komponenten löschen > Abstracter Fehler
Hallo Michael,
zunächst einmal zu Deiner eigentlichen Frage. Zitat:
Delphi-Quellcode:
Wenn der Button anders erzeugt wurde, dann sollte Dein Verfahren im Prinzip richtig sein. Versuche einmal, genaue Prüfungen einzubauen, Haltepunkt auf begin setzen und dann im Einzelschritt zu debuggen:
Button23.Parent := Panel23; // oder so
Delphi-Quellcode:
Wenn der Button zur Laufzeit erzeugt wurde, muss er ebenfalls 'manuell' gelöscht werden. Das darf aber keinesfalls innerhalb seiner eigenen OnClick-Routine (PanelFree?) geschehen; denn dann würde der Sender während der Ausführung verschwinden, und das Programm wüsste am Ende von PanelFree nicht mehr, was es mit den Variablen und Daten auf dem Stack anfangen soll!
procedure TForm2.PanelFree(Sender:Tobject);
// da du ein Panel löschen willst, kann Du es auch so deklarieren var test: TPanel; begin // ist der Sender wirklich ein Button? if (Sender is TButton) then begin // sitzt der Button auf einem Panel? if (Sender as TButton).Parent is TPanel then begin // da Du das Control hinter der Variable test löschen willst, muss es // erst einmal zugeordnet werden!!! das fehlte bei Dir auf jeden Fall, // oder es kam zu spät, als Button.Parent bereits auf nil gesetzt wurde test := (Sender as TButton).Parent as TPanel; // entferne die Verknüpfung des Buttons von seinem Parent // Dein Fehler hier war wahrscheinlich das doppelte Parent (Sender as TButton).Parent := nil; // jetzt kannst Du das Panel auflösen, aber bitte mit Fehlerprüfung try test.free; except ; // leere Fehlermaßnahme funktioniert und genügt hier wohl end; end; end; end; Wenn der Button durch Add_PlaylistPanel erzeugt wurde (worauf Deine Variable sp:TJvBitBtn hindeutet), musst Du völlig anders verfahren: 1. ButtonClick muss ebenso wie oben prüfen, ob es sich um einen Button auf einem Panel handelt. 2. Eine Variable des Formulars muss eine Information erhalten:
Delphi-Quellcode:
3. Der Focus muss vom Panel wegbewegt werden!!!
sPanel_soll_geloescht_werden := ((Sender as TButton).Parent as TPanel).Name;
Delphi-Quellcode:
4. Dieses Control prüft, ob die Löschung jetzt möglich und vorgesehen ist:
StaticText1.SetFocus; // ich bin mir nicht sicher, ob das bei TStaticText möglich ist
Delphi-Quellcode:
Ich hoffe, diese Hinweise helfen Dir weiter.
// OnEnter des neuen Controls prüft:
if sPanel_soll_geloescht_werden <> '' then begin // Panel löschen, ähnlich wie oben, aber als Parameter eher den Namen übergeben; // denn der Sender hat jetzt keine Bedeutung mehr // 1. suche unter allen Komponenten diejenige mit dem übergebenen Namen // 2. lösche alle Komponenten, die auf diesem Panel setzen // 3. lösche das Panel selbst // Variable zurücksetzen sPanel_soll_geloescht_werden := ''; end; Zusatzbemerkungen 1. Wo ist Add_PlaylistPanel deklariert? innerhalb von TForm1, von TForm2 oder global? Sinnvollerweise gehört es in das Formular, in dem die Panels erzeugt werden. Nur wenn Du dies in mehreren Formularen erledigst, ist eine globale Deklaration (unter Win32 - nicht unter NET) sinnvoll. 2. Was hat 'Form1.Show' in dieser Prozedur zu suchen? Wenn es darum geht, dass das Panel angezeigt wird, dann benutze am Ende dieser Routine:
Delphi-Quellcode:
3. Die Variable 'str' beim Erstellen des Panels ist überflüssig; eine Konvertierung StrToInt/IntToStr kann eingespart werden:
ScrollBox.Refresh;
Delphi-Quellcode:
Ich finde auch, dass Leerzeichen vor und hinter ':=' das Ganze besser lesbar machen.
Panel.tag := form1.JvPageControl1.PageCount * 10 + ScrollBox.ControlCount-1;
panel.name := 'Panel' + IntTostr(Panel.tag); PS. In letzter Zeit sind Deine Beiträge verständlich. Danke für diese Rücksichtnahme! |
Re: Komponenten löschen > Abstracter Fehler
Delphi-Quellcode:
genau das habe ich versucht...
Wenn der Button zur Laufzeit erzeugt wurde, muss er ebenfalls 'manuell' gelöscht werden. Das darf aber keinesfalls innerhalb seiner eigenen OnClick-Routine (PanelFree?)
Zitat:
Zitat:
ScrollBox.Refresh; warum ? es klappt doch auch so.... naja ich werds mal einbauen, danke für den tipp Zitat:
ich erzeuge zurlaufzeit ein TMainmenu item bzw mehrer, und eine TabSheet... und beide müssen irgenwie gefunden werden.. jetzt speichere ich diesen wert als tag und ordne ihn beiden zu(also den MenuItem und dem Panel) der tab besteht aus zwei zaheln. 1.die anzahl der Pagaseiten 2. Die Anzahl der panels so bekommen ich ein eindeutigen namen hin ich hoffe du kannst mit diese beschreibung was anfangen... kann ich den qullcode auch hochladen, wenn du möchtes ! ich werde das gleich mal versuchen einzubauen.... nach deiner beschreibung. vielen dank für diese ausführliche antwort |
Re: Komponenten löschen > Abstracter Fehler
vielen dank noch mal es hat funktiniert.. ich habe das jetzt so gemacht:
Delphi-Quellcode:
als erstens gebe ich den focus weg bzw. setzte den auf NIL
procedure TForm2.PanelFree(Sender:Tobject);
var test:TWinControl; MenuItem:TMenuItem; i:Integer; begin test:=TJvCaptionPanel((Sender as TWinControl).Parent); form1.ActiveControl:=niL; for i:=test.ControlCount-1 downto 0 do begin if test.Controls[i] <> NIL then test.RemoveControl(test.Controls[i]); end; test.free; end; ich lösche erst alle komponenten die zurlaufzeit erstellt wurden sind. Danach lösche ich das panel selbst. scheint zu klappen... |
Re: Komponenten löschen > Abstracter Fehler
Gut, wenn ich Dir helfen konnte. Nur noch einige kurze Anmerkungen:
1. Zu Deiner Namensgebung für die Panels und IntToStr/StrToInt: Dein Vorgehen verstehe ich. Ich vermute aber, dass Delphi bei diesen Umwandlungen viel probieren muss (und StrToInt gerne zu Exceptions führt, wenn auch nicht in Deinem Fall). Deshalb würde ich eher int-Variablen als Zwischenspeicher verwenden als diese Konvertierungen. 2. ActiveControl := nil; gefällt mir nicht, denn das aktive Formular sollte auch ein ActiveControl haben. Aber wenn es klappt... Aber füge noch eine Zeile ein, damit Du sicher sein kannst, dass der Focus entfernt ist:
Delphi-Quellcode:
3. Wozu hast Du in PanelFree die Variable MenuItem deklariert? Warum setzt Du die Variable test nicht auf das, was sie ist, nämlich TJvCaptionPanel - Du musst doch sowieso das cast vornehmen?!
form1.ActiveControl:=niL;
Application.ProcessMessages; 4. ![]() 5. Zur Erzeugung der Anzeige: Zitat:
Gruß Jürgen |
Re: Komponenten löschen > Abstracter Fehler
Zitat:
Übrigens das Setzen von ActiveControl auf NIL funktioniert einwandfrei, denn in diesem Fall bekommt das Formular den Focus, aber kein darauf liegendes Control. Ein darauf folgendes Application.ProcessMessages ist nicht notwendig, da der Focus mit einem "Windows.SetFocus(Handle)" sofort wechselt und nicht erst eine Botschaft in die Messagequeue steckt. |
Re: Komponenten löschen > Abstracter Fehler
@Jürgen Thomas
Zitat:
Zitat:
components[0] oder so änlich das hat mir den aktieve komponente zurückgeben. danke für den hinweiß werde ich einbauen ! Zitat:
Zitat:
ich meine das mit den free hatte auch irgenwelche probeleme veruarsacht aber ich werde es nocheinmal testen zu 5. achso, das habe ich jetzt sowieso verändert alles passiert jetzt in ein und den selben formular. ich wollte nur das formualr anzeigen mehr nicht. @jbg danke für den tipp. |
Re: Komponenten löschen > Abstracter Fehler
nachtrag:
Delphi-Quellcode:
wenn ich es mit free mache bekomme ich eine abstrakte fehlermeldung und wenn ich es mit removcontrol mache ist die komponente weg bzw. kann nicht mehr gefunden werden mit findcomponent !
procedure TForm1.PanelFree(Sender:Tobject);
var test:TWinControl; MenuItem:TMenuItem; i:Integer; begin test:=TJvCaptionPanel((Sender as TWinControl).Parent); TMenuItem(form1.FindComponent('MenuItem' +InTTostr(test.tag))).Destroy; form1.ActiveControl:=niL; for i:=test.ControlCount-1 downto 0 do begin if test.Controls[i] <> NIL then test.Controls[i].free; // test.RemoveControl(test.Controls[i]); end; test.free; end; |
Re: Komponenten löschen > Abstracter Fehler
Vielleicht muss tatsächlich beides gemacht werden: das jeweilige Control aus der Panel-Liste entfernen und getrennt löschen, und das geht erst nach dem Entfernen. Probiere einmal Folgendes (die eingefügten Zeilen habe ich markiert):
Delphi-Quellcode:
Gruß Jürgen
procedure TForm1.PanelFree(Sender:Tobject);
var test:TWinControl; ctl: TWinControl; // eingefügt MenuItem:TMenuItem; i:Integer; begin test:=TJvCaptionPanel((Sender as TWinControl).Parent); TMenuItem(form1.FindComponent('MenuItem' +InTTostr(test.tag))).Destroy; form1.ActiveControl:=niL; for i:=test.ControlCount-1 downto 0 do begin if test.Controls[i] <> NIL then begin // begin...end eingefügt, weil jetzt mehrere Befehle kommen ctl := test.Controls[i]; // damit auf ctl noch später zugegriffen werden kann test.RemoveControl(test.Controls[i]); ctl.Free; // löschen end; // Gegenstück zum eingefügten begin end; test.free; end; |
Re: Komponenten löschen > Abstracter Fehler
habe ich versucht:
1. kam eine fehlermeldung vom complier das Zitat:
2. die Laufzeit fehlermeldung kommt immer noch mit deinem code... wenn ich es so mache:
Delphi-Quellcode:
kommt keine fehlermeldung !
procedure TForm1.PanelFree(Sender:Tobject);
var test:TWinControl; MenuItem:TMenuItem; i:Integer; begin test:=TJvCaptionPanel((Sender as TWinControl).Parent); TMenuItem(form1.FindComponent('MenuItem' +InTTostr(test.tag))).Destroy; form1.ActiveControl:=niL; for i:=test.ControlCount-1 downto 0 do begin if test.Controls[i] <> NIL then begin test.RemoveControl(test.Controls[i]); end; end; test.free; end; und die komponente ist auch weg, naja ich kann sie nicht mehr mit FindComponent finden... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 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-2025 by Thomas Breitkreuz