Autor |
Beitrag |
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.01.15 19:31
Hallo!
Man kann ja eine Variable im Private-Abschnitt deklarieren, zB. für MDI-Forms. Der Zweck ist klar, sie gilt dann nur für das jeweilige MDIChild.
Nun erzeuge ich aber keine MDI-Forms, sondern Komponenten zur Laufzeit. So, wie man das halt macht: MyKomponente := TWasweissIch.Create(Self). Jetzt brauche ich für jede dieser Komponenten eine spezielle, nur für diese Komponente geltende Variable, die ich aber dennoch global in Form1 verwenden können muss. Das bedeutet, wenn eine dieser Komponenten den Fokus hat, man also mit ihr arbeitet, und ich spreche "ihre" Variable an, soll das keine Auswirkungen auf die gleichartigen Variablen der anderen Komponenten haben.
Frage: Wie mache ich das?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 18.01.15 20:11
Das hört sich so an als wäre eine eigene abgeleitete Klasse dieser Komponente das Richtige, damit du dort ein solches Feld unterbringen kannst. Das würde ich hier sehr empfehlen.
Wenn du über die Komponente auf deine Variable zugreifen willst, könntest du auch ein TDictionary<TYourComponent, TYourField> benutzen. Das halte ich aber für nicht so sauber im Vergleich zu der anderen Lösung.
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.01.15 20:25
jaenicke hat folgendes geschrieben : | Das hört sich so an als wäre eine eigene abgeleitete Klasse dieser Komponente das Richtige, damit du dort ein solches Feld unterbringen kannst. |
Das habe ich mir zuerst auch gedacht, scheue aber den Aufwand!
Einfachere Lösung: Ich füge die Variable in den Quelltext der Komponente unter public ein, so kann ich auf sie zugreifen. Ist nicht sauber, aber geht. Naja, geht nur mit weiteren Tricks im Quelltext von Form1, scheint aber bisher zu funktionieren.
Konkret: Undo/Redo für TJvWideHLEditor, hatte das hier schon mal angefragt, mit MDI klappt das:
www.entwickler-ecke....8&highlight=undo
Undo/Redo: [url]development.mwcs.de/tutundoredo.html[/url]
Ich machte dann die Titelleiste der MDI's weg: www.entwickler-ecke....ewtopic.php?t=113837, dann kam es zu einem Fehler beim Erstellen des Fenster-Gerätekontexts. Also dachte ich, ich programmiere alles ohne MDI neu. Jetzt habe ich eine TabBar, jedes Tab hat eine TJvWideHLEditor-Komponente. Dann wurde mir klar, dass jede Komponente eine eigene Variable braucht.
Abgeleitete Klasse dieser Komponente - gut, werde ich wohl hinbekommen, aber wo gehört da korrekterweise die Variable hin? So wie ich es jetzt habe, scheint es zu funktionieren, aber es ist halt ein Murks...
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
WasWeißDennIch
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 18.01.15 20:59
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.01.15 21:17
WasWeißDennIch hat folgendes geschrieben : | galagher hat folgendes geschrieben : | Delphi-Quelltext 1:
| MyKomponente := TWasweissIch.Create(Self) | |
|
Ja, mein Fehler, korrekt ist natürlich: MyKomponente := TWasWeißDennIch.Create(Self)
Ok, danke erstmal für deine Beispiele. Wenn ich es so mache, wäre es natürlich sinnvoll, gleich auch den ganzen Undo/Redo-Code da reinzupacken, dann ist das alles in einem Paket. Ob ich das hinbekomme? Noch dazu, wo da ein Timer benötigt wird.
Und das alles nur, weil TJvWideHLEditor kein Redo hat. Ob ich mir das antue? Also, als Lernprojekt wäre das schon gut!
Habe ja schon ein paar Komponenten entwickelt, aber fremden Code einbauen, ich weiss nicht...
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
ub60
Beiträge: 762
Erhaltene Danke: 127
|
Verfasst: So 18.01.15 21:52
Eventuell brauchst Du gar nichts so Kompliziertes. Jede Komponente besitzt eine Eigenschaft "Tag", die Du eventuell für Deine Zwecke "missbrauchen" kannst.
Aus der Hilfe:
Zitat: | Beschreibung
Tag hat keine vordefinierte Bedeutung. Die Eigenschaft Tag steht zur freien Benutzung durch Entwickler zur Verfügung. Sie können in dieser Eigenschaft zusätzliche Informationen über die Komponente in Form einer Ganzzahl speichern oder die Eigenschaft in einen 32-Bit-Wert, wie z.B. in eine Komponentenreferenz oder einen Zeiger, umgewandelt werden. |
ub60
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 19.01.15 06:15
galagher hat folgendes geschrieben : | Das habe ich mir zuerst auch gedacht, scheue aber den Aufwand!
Einfachere Lösung: Ich füge die Variable in den Quelltext der Komponente unter public ein, so kann ich auf sie zugreifen. |
Noch höher ist der Aufwand, wenn du dann die Komponenten einmal aktualisieren möchtest.
Denn da du den Quelltext der Komponente angepasst hast, musst du deine Änderungen jedes Mal in die aktuelle Version wieder einbauen...
Aber wo ist das ein großer Aufwand? Du erstellst einfach deine abgeleitete Klasse statt der Standardklasse. Du musst ja nichts registrieren oder irgendwas, da du die Klasse ohnehin manuell erstellst!
Also einfach nur das Feld in die neue Klasse rein wie WasWeißDennIch geschrieben hat, die Unit unter uses schreiben und beim Erstellen und in Variablentypen überall die neue Klasse statt der bisherigen nutzen.
ub60 hat folgendes geschrieben : | Eventuell brauchst Du gar nichts so Kompliziertes. Jede Komponente besitzt eine Eigenschaft "Tag", die Du eventuell für Deine Zwecke "missbrauchen" kannst. |
Das sollte man nur machen, wenn man keine andere Möglichkeit hat, sprich in diesem Fall sehe ich keinen Sinn darin das so zu machen. Wenn man dann mal vergisst, dass man die Eigenschaft schon einmal verwendet hat, wundert man sich später und sucht ggf. lange nach dem Fehler.
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 19.01.15 18:51
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 19.01.15 20:50
galagher hat folgendes geschrieben : | Klappt! Wobei ich den public-Abschnitt mit der property gar nicht brauche: |
Solange du nicht von außerhalb der Klasse darauf zugreifst, nicht, nein.
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 19.01.15 21:04
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 19.01.15 22:01
Bei der Verwendung ist die Verwendung des privaten Felds von außerhalb extrem schlechter Programmierstil. Da solltest du besser eine Property nutzen.
Am besten packst du solche Klassen jeweils in eine eigene Unit, dann kann es auch nicht passieren, dass man private Felder von außen anspricht.
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 19.01.15 22:57
jaenicke hat folgendes geschrieben : | Bei der Verwendung ist die Verwendung des privaten Felds von außerhalb extrem schlechter Programmierstil. Da solltest du besser eine Property nutzen.
Am besten packst du solche Klassen jeweils in eine eigene Unit, dann kann es auch nicht passieren, dass man private Felder von außen anspricht. |
Dann sollte ich am Besten gleich eine eigene Unit basteln, mit Register, und auch versuchen, den ganzen Undo/Redo-Kram, der jetzt in separaten Units vorliegt, da reinzupacken...
Ansonsten: Wenn ich es so lasse, wie du vorschlägst, wo muss die Variable dann hin? Sie muss ausschliesslich nur für die jeweilige Komponente gelten ("privat" sein), da sonst das Undo/Redo auch versucht, auf die andere Komponenten zu wirken, was ja nicht erwünscht ist.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 20.01.15 07:32
galagher hat folgendes geschrieben : | Ansonsten: Wenn ich es so lasse, wie du vorschlägst, wo muss die Variable dann hin? Sie muss ausschliesslich nur für die jeweilige Komponente gelten ("privat" sein), da sonst das Undo/Redo auch versucht, auf die andere Komponenten zu wirken, was ja nicht erwünscht ist. |
Das hast du falsch verstanden glaube ich. Die property unter public ist schon richtig. Das wird auch in den ganzen Komponenten, die du nutzt, so benutzt.
Private bezieht sich auf die Sichtbarkeit, das hat nichts mit Klassenfeldern oder ähnlichem zu tun.
Sprich alles unter private kann nur von innerhalb der gleichen Klasse (und leider auch der gleichen Unit) benutzt werden und alles unter public auch von anderen Units aus. Das ändert aber nichts daran, dass das Feld zu der aktuellen Instanz der Klasse gehört. Sprich wenn du mehrere solcher Objekte hast, sind dessen Felder auch unabhängig voneinander, egal ob sie unter private, public, protected oder published stehen.
Anders sieht es mit Klassenfeldern, Klasseneigenschaften und Klassenmethoden aus. Die funktionieren unabhängig von einer konkreten Instanz und sind daher immer nur einmal vorhanden: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| type TExample = class private class var FTest: Integer; public class property Test: Integer read FTest write FTest; end; | Das ist wohl das wie du es gedacht hast. Aber das passiert nur, wenn du eine class var oder class property deklarierst.
|
|
WasWeißDennIch
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Di 20.01.15 09:26
Wenn das für jede Instanz separat gelten soll (so habe ich es verstanden), ist eine Klassenproperty aber genau der falsche Weg.
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 20.01.15 11:10
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
WasWeißDennIch
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Di 20.01.15 11:16
Wenn Du keine Schnittstelle nach außen brauchst, kannst Du die Property auch ersatzlos streichen, so dass nur das private Feld übrig bleibt. Der Casus knacktus ist jetzt, ob jede Instanz ihr eigenes Feld braucht, das nur innerhalb der jeweiligen Instanz gültig ist, oder ob alle Instanzen auf dasselbe Feld zugreifen sollen. Wenn Ersteres, dann hast Du es oben schon richtig skizziert, ansonsten muss es eine Klassenvariable sein.
|
|
Stundenplan
Beiträge: 128
Erhaltene Danke: 32
Win 7
Delphi 7 Pers., C# (VS 2010 Express)
|
Verfasst: Di 20.01.15 11:21
@jaenicke: strict private gibt es ja auch noch, das unterbindet willkürlichen Zugriff aus derselben Unit.
|
|
jaenicke
Beiträge: 19274
Erhaltene Danke: 1740
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 20.01.15 14:09
galagher hat folgendes geschrieben : | Also doch so?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| type TDeineKomponente = class(TVorfahr) private FDeinFeld: DeinDatentyp; ... public property DeinFeld: DeinDatentyp read FDeinFeld write FDeinFeld; ... end; | |
Ja, genau.
Ich hatte mich etwas missverständlich ausgedrückt fällt mir auf. Mit "Das ist wohl das wie du es gedacht hast." meinte ich nicht was du wolltest, sondern was du offenbar dachtest was der Quelltext von WasWeißDennIch macht.
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2510
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 20.01.15 19:08
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|