Entwickler-Ecke
Sonstiges (Delphi) - Objekte dynamisch erzeugen
Arakis - Do 13.06.02 21:52
Titel: Objekte dynamisch erzeugen
Hi,
zur Zeit programmiere ich einen Tabsheet-Browser so wie bei Natcaptor. Zu jedem dynamisch erstellten Browser muss ich jede Menge Infos zusätzlich speichern, wie z.B. die History usw.
Dazu habe ich einfach mal ein Object TBrowserDataen erstellt. Darin enthalten sich Stringlisten, Prozeduren, usw.
Das Problem jetzt ist nur, dass halt für jeden Browser so ein Datan-Objekt haben muss. Fast ohne Probleme geht es, wenn ich global ein ein Array of TBrowserdaten erstelle, nur bekomme ich dann Probleme beim Löschen und mit dem "Aufrücken". Ich habe mir sagen lassen, TList und TObjectslist wären da die bessere Möglichkeit. Aber mit denen bekomme ich nichts auf die Reihe. Denn so bald ich die Funkion verlasse, die das Object deklariert hat, wird das Objekt freigegeben, und der Zeiger in der TList zeigt ins Leere. Also suche ich nach einer Create-Methode. Gibt es anscheinend aber nicht. Wie kann ich jetzt ein Object dynamisch erstllen, dass auch nach verlassen der Funkion weiter im Speicher bleibt? Ist das nur mit Klassen möglich? Und wenn, wie?
Bin für jede Hilfe dankbar :P
Bis dann,
Arakis
Thunderman - Do 13.06.02 22:22
Hallo!
Also Variablen von einfachen Typen wie Integer oder auch records kannst du dynamisch mit New(); erzeugen und mit Dispatch wieder freigeben.
Klassen kannst du so erzeugen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| type TMeineKlasse class(TComponent) x : Integer; end; ... var MeineKlasse : TMeineKlasse; begin ... MeineKlasse := TMeineKlasse.Create(nil); ... end; |
Die so erzeugte Variable MeineKlasse kannst du als Pointer in einer TList speichern. Und über diese Liste jederzeit auf die Variable zugreifen. Du musst nur bei beiden Fällen darauf achten, die Variablen auch wieder am Ende deines Programms auf jeden Fall wieder freizugeben. Entweder mit Dispatch(); oder halt im 2. Fall mit MeineKlasse.Free;
New und Dispatch sind eigentlich recht gut in der Delphi-Hilfe erklärt.
Falls Du noch Fragen zu TList hast, einfach raus damit.
Arakis - Do 13.06.02 22:32
Titel: Bitte ein kleines Beispiel
Jo, hätt ich :D
Du meinst, mein Objekt dürfte dann keine weiteren Unterobjekte enthalten, weil die ja nicht einfache Integer/String-Variablen sind? Was ist denn der Unterschied von Klassen und Objekten? Dann werde ich wahrscheinlich aber Klassen nehemen. Könnest du mir den Gefallen tun und ein ganz kleines Beispiel posten, wie man zur Laufzeit eine Klasse Erstellt, in einer TList (oder TObjectList/TClasslist) abspeichert, in einer anderen Funkion wieder anspricht? Dann wäre da noch das wieder freigeben mit free.
Wäre nett :wink:
Bis dann
Tino - Do 13.06.02 23:25
Hi,
ich hab mir mal ein Beispiel zusammen gecodet:
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: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91:
| Type tBrowser = Class Private fHistory: tStringList; Public Constructor Create; Destructor Destroy; override;
Property History: tStringList read fHistory write fHistory; End; tBrowserList = Class Private fList: tList; Function GetCount: Integer; Function GetItems (Index: Integer): tBrowser; Procedure SetItems (Index: Integer; aBroswer: tBrowser); Public Constructor Create; Destructor Destroy; override; Function Add (aBrowser: tBrowser): Integer; Procedure Delete (aIdx: Integer); Procedure Clear; Property Count: Integer read GetCount; Property Items [Index: Integer]: tBrowser read GetItems write SetItems; End; { tBrowser } Constructor tBrowser.Create; Begin fHistory := tStringList.Create; End;
Destructor tBrowser.Destroy; Begin fHistory.Free; Inherited; End;
{ tBrowserList }
Constructor tBrowserList.Create; Begin fList := tList.Create; End;
Destructor tBrowserList.Destroy; override; Begin Clear; fList.Free; Inherited; End;
Function tBrowserList.GetCount: Integer; Begin GetCount := fList.Count; End;
Function tBrowserList.GetItems (Index: Integer): tBrowser; Begin GetItems := tBrowser (fList [Index]); End;
Procedure tBrowserList.SetItems (Index: Integer; aBroswer: tBrowser); Begin fList [Index] := aBrowser]; End; Function tBrowserList.Add (aBrowser: tBrowser): Integer; Begin Add := fList.Add (aBrowser); End;
Procedure tBrowserList.Delete (aIdx: Integer); Begin fList.Delete (aIdx); End;
Procedure tBrowserList.Clear; Var Idx: Integer; Begin For Idx := Count -1 DownTo 0 Do Delete (Idx); End; |
Die Benutzung ist relativ einfach: Auf deinem Mainform erstellst Du eine Variable vom Type tBrowserList (am besten im OnCreate):
BrowserList := tBrowserList.Createdieses Objekt musst Du natürlich wieder freigeben (im OnDestroy):
BrowserList.FreeWenn Du jetzt ein neues Browserfenster erstellst musst du auch ein neues tBrowser-Objekte erstellen und der BrowserList hinzufügen:
Quelltext
1: 2: 3: 4:
| MDIForm := tMDIForm.Create (MainForm); BrowserInfo := tBrowser.Create;
BrowserList.Add (BrowserInfo); |
So mit hast Du zu jedem Browserfenster auch ein Info-Objekt (z. B. mit der Historyliste). Was Du jetzt noch machen musst ist das tBrowser-Objekt mit dem MDI-Form "verbinden". Am besten im Constructor des tBrowser-Objekt das MDI-Form mit angeben.
Gruß
Arakis - Do 13.06.02 23:28
Besten Dank Tino, werde ich dir nie vergessen 8)
Bis dann
Tino - Do 13.06.02 23:33
Gerne! Aber keine Garantie das das sofort funktioniert da ich es nicht getestet habe.
Arakis - Fr 14.06.02 00:05
Titel: Programmierhilfe im Editor funzt nicht
Die Garantie sei dir gegeben :wink:
So wende ich das jetzt an:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Button1Click(Sender: TObject); var b : TBrowser; begin b:=TBrowser.Create; b.fHistory.Add('test'); BrowserList.Add(b); end;
procedure TForm1.Button2Click(Sender: TObject); begin showmessage(BrowserList.Items[0].fHistory.text); end; |
Funzt ganz prima! Aber hier ist eine Sache, die ich schon öfters mal bei Objekten beobachtet habe: ich schreibe:
BrowserList.Items[0].fHistory
setzte dann einen Punkt, aber es kommt keine Programmierhilfe vom Editor! Woran liegt das eigentlich? Er konnte mir ja schließlich auch fHistory ohne zu überlegen anbieten.
Bis dann
Tino - Fr 14.06.02 09:37
Hab natürlich etwas vergessen: Hab meinen Beitrag von oben erweitert. Hinzugekommen ist die 9. Zeile:Property History: tStringList read fHistory write fHistory;Zu Deiner Frage warum fHistory nicht in der Codevervollständigung angezeigt wird: fHistory ist in der Private-Section definiert und gehört somit NUR dem Objekt selbst. Nach außen hin kann man es nicht benutzen! Deshalb habe ich jetzt auch in der Public-Section das Property History hinzugefügt damit Du sauber an das History-Objekte ran kommst!
Gruß
Phoenix - Di 25.06.02 16:21
Titel: Re: Programmierhilfe im Editor funzt nicht
Huhu,
Arakis hat folgendes geschrieben: |
Funzt ganz prima! Aber hier ist eine Sache, die ich schon öfters
mal bei Objekten beobachtet habe: ich schreibe:
BrowserList.Items[0].fHistory
setzte dann einen Punkt, aber es kommt keine Programmierhilfe vom
Editor! Woran liegt das eigentlich? |
Das liegt daran, das er ab dem Index in dem Array das Objekt nicht
mehr eineindeutig Identifizieren kann, selbst wenn das Array
ausschliesslich diesen einen Objekttyp beinhaltet. Das ist ein Bug(?),
oder ein fehlendes Feature der IDE.
Grüßle,
Sebastian
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!