AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Komponenten löschen > Abstracter Fehler

Ein Thema von mimi · begonnen am 26. Aug 2006 · letzter Beitrag vom 28. Aug 2006
Antwort Antwort
Seite 1 von 2  1 2      
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#1

Komponenten löschen > Abstracter Fehler

  Alt 26. Aug 2006, 15:51
Hallo,
ich erzeuge sehr viele komponenten zu laufzeit das mache ich so:
Delphi-Quellcode:
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;
....
und jeztt möchte ich die komponenten löschen und zwar über einen button der dieser komonente gehört.
Jedes mal wenn ich es tuen möchte gibt es eine fehlermeldung:
Abstackter Fehler

löschen wollte ich es so:
Delphi-Quellcode:
procedure TForm2.PanelFree(Sender:Tobject);
var
  test:TWinControl;
begin
  (Sender as TWinControl).Parent.parent:=nil;
  (Sender as TWinControl).Parent.Free;
// test.free;

end;
Für lösungen währe ich dankbar !
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#2

Re: Komponenten löschen > Abstracter Fehler

  Alt 26. Aug 2006, 18:23
Hallo Michael,

zunächst einmal zu Deiner eigentlichen Frage.
Zitat von mimi:
und zwar über einen button der dieser komonente gehört.
Bedeutet das, dass der betreffende Button auf dem Panel liegt? Dann müsstest Du eigentlich auch den Button zur Laufzeit erzeugen und dem Panel zuordnen:
Button23.Parent := Panel23; // oder so 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:
Delphi-Quellcode:
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 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!

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:
sPanel_soll_geloescht_werden := ((Sender as TButton).Parent as TPanel).Name; 3. Der Focus muss vom Panel wegbewegt werden!!!
StaticText1.SetFocus; // ich bin mir nicht sicher, ob das bei TStaticText möglich ist 4. Dieses Control prüft, ob die Löschung jetzt möglich und vorgesehen ist:
Delphi-Quellcode:
// 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;
Ich hoffe, diese Hinweise helfen Dir weiter.

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:
ScrollBox.Refresh; 3. Die Variable 'str' beim Erstellen des Panels ist überflüssig; eine Konvertierung StrToInt/IntToStr kann eingespart werden:
Delphi-Quellcode:
  Panel.tag := form1.JvPageControl1.PageCount * 10 + ScrollBox.ControlCount-1;
  panel.name := 'Panel' + IntTostr(Panel.tag);
Ich finde auch, dass Leerzeichen vor und hinter ':=' das Ganze besser lesbar machen.

PS. In letzter Zeit sind Deine Beiträge verständlich. Danke für diese Rücksichtnahme!
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#3

Re: Komponenten löschen > Abstracter Fehler

  Alt 26. Aug 2006, 21:15
Wenn der Button zur Laufzeit erzeugt wurde, muss er ebenfalls 'manuell' gelöscht werden. Das darf aber keinesfalls innerhalb seiner eigenen OnClick-Routine (PanelFree?) genau das habe ich versucht...

Zitat:
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.
nirgenwo nur als funktion erstmal ich möchte wenn alle so läuft wie ich es mir vorstelle, in einer extra unit verpacken
Zitat:
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:
das steht da nur als test drin, da ich es noch nicht richtig gemacht habe... später wird das alles entwas anders aussehen.
ScrollBox.Refresh; warum ? es klappt doch auch so.... naja ich werds mal einbauen, danke für den tipp
Zitat:
3. Die Variable 'str' beim Erstellen des Panels ist überflüssig; eine Konvertierung StrToInt/IntToStr kann eingespart werden:
Delphi-Quellcode: markieren
Panel.tag := form1.JvPageControl1.PageCount * 10 + ScrollBox.ControlCount-1;
panel.name := 'Panel' + IntTostr(Panel.tag);
leider nicht, ich habe mir dabei was gedacht und zwar:
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
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Komponenten löschen > Abstracter Fehler

  Alt 26. Aug 2006, 21:25
vielen dank noch mal es hat funktiniert.. ich habe das jetzt so gemacht:
Delphi-Quellcode:
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;
als erstens gebe ich den focus weg bzw. setzte den auf NIL
ich lösche erst alle komponenten die zurlaufzeit erstellt wurden sind.
Danach lösche ich das panel selbst.
scheint zu klappen...
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#5

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 11:19
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:
form1.ActiveControl:=niL;
Application.ProcessMessages;
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?!

4. Delphi-Referenz durchsuchenRemoveControl entfernt die Komponente nur aus der Liste test.Controls[i], macht also das Gleiche wie Parent := nil. Du musst diese Komponenten jeweils ebenfalls "free" machen!

5. Zur Erzeugung der Anzeige:
Zitat von mimi #3:
ScrollBox.Refresh; warum ? es klappt doch auch so...
Unnötige Verweise auf "ferne" Formulare sollten entfallen (es sei denn, ich habe das Zusammenspiel Deiner Formulare falsch verstanden). Es geht Dir vermutlich darum, dass die Anzeige erneuert wird, nachdem das Panel erzeugt wurde. Dazu ist (nur) das Control neu zu zeichnen, auf dem das Panel angelegt wurde, also ScrollBox; für diesen Vorgang ist Refresh vorgesehen, während Show die Eigenschaft Visible des betreffenden Formulars verändert. (Ich hoffe, dies erklärt meinen Vorschlag - wie gesagt, vorausgesetzt, dass er zu Deinen Intentionen passt.)

Gruß Jürgen
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 11:47
Zitat von Jürgen Thomas:
Delphi-Quellcode:
form1.ActiveControl:=niL;
Application.ProcessMessages;
Vorsicht vor Application.ProcessMessages. Das kann zu einem ungewollten Programmablauf führen.

Ü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.
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#7

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 14:44
@Jürgen Thomas
Zitat:
Deshalb würde ich eher int-Variablen als Zwischenspeicher verwenden als diese Konvertierungen.
dann hätte ich probleme die zahlen zusammen zubringen... ich möchte sie ja nicht addieren sondern zusammen fügen und das geht leider nur als string, oder verstehe ich dich jetzt falsch ?

Zitat:
2. ActiveControl := nil;
naja... ich weiß keine andere lösung und das war das einfachste, wobei führer habe ich das meistens so gemacht:
components[0] oder so änlich das hat mir den aktieve komponente zurückgeben.
danke für den hinweiß werde ich einbauen !


Zitat:
. Wozu hast Du in PanelFree die Variable MenuItem deklariert?
ganz einfach: ich muss ein menuItem und ein panel gleichzeitg löschen und das war der einfachste weg

Zitat:
4. Schau in die Delphi-HilfeRemoveControl entfernt die Komponente nur aus der Liste test.Controls[i], macht also das Gleiche wie Parent := nil. Du musst diese Komponenten jeweils ebenfalls "free" machen!
meine delphi 2005 PE hilfe hat mit das nicht gesagt bzw. dort gabs die anweisung leider nicht...
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.
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#8

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 14:47
nachtrag:
Delphi-Quellcode:
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;
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 !
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Jürgen Thomas

Registriert seit: 13. Jul 2006
Ort: Berlin
750 Beiträge
 
#9

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 15:38
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:
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;
Gruß Jürgen
#D mit C# für NET, dazu Firebird
früher: Delphi 5 Pro, Delphi 2005 Pro mit C# (also NET 1.1)
Bitte nicht sauer sein, wenn ich mich bei Delphi-Schreibweisen verhaue; ich bin inzwischen an C# gewöhnt.
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#10

Re: Komponenten löschen > Abstracter Fehler

  Alt 27. Aug 2006, 19:17
habe ich versucht:
1. kam eine fehlermeldung vom complier das
Zitat:
[Fehler] Unit1.pas(332): E2010 Inkompatible Typen: 'TWinControl' und 'TControl'
dann habe ich das geändert oben dann ging das complieren.

2. die Laufzeit fehlermeldung kommt immer noch mit deinem code... wenn ich es so mache:
Delphi-Quellcode:
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;
kommt keine fehlermeldung !
und die komponente ist auch weg, naja ich kann sie nicht mehr mit FindComponent finden...
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:24 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