Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Ansteuerung von Komponenten in Frame
steiniman1 - So 31.07.22 01:24
Titel: Ansteuerung von Komponenten in Frame
hallo,
nach langer Delphi-Abstinenz wollte ich ein Delphi 7 Projekt auf Delphi 11 umstellen mit gleichzeitigem Umbau von MDI zu Frames. Erste Erfolge haben sich schon eingestellt. Ich habe jedoch ein Problem, dass ich Komponenten in den Frames nicht vom Parentformular bestückt bekomme. Im ursprünglichen Script werden im Parentformular diverse MySQL-Abfragen durchgeführt und die Daten in die Komponenten der Frames eingetragen. Da augenscheinlich ein grundsätzliches Problem besteht, habe ich das Script runter gebrochen, damit das wesentliche erkannt werden kann:
Als Hintergrundinfo: Es wird ein Hauptformular erstellt, die eine Toolbar und ein PageControl enthält. Dieses enthält mehrere Tabs, in denen Frames eingebunden werden.
Klickt man auf eines der Button in der Toolbar, wird das entsprechende Tab aufgerufen und ich kann mit dem entsprechenden Frame ohne weiteres arbeiten. Eines der Frames hat eine Tabelle, das auf dessen Doppelklick eine neues Formular TForm2 als "StayOnTop" öffnet. Bis hierher ist alles schick und läuft so, wie es soll.
Auf dem Form2 ist u.A. ein PageControl (TAdvOfficePager von TMS) und weitere Edits. Im TAdvOfficePager wird dynamisch bis zu 20 Frames in jeweilige Pages packt. Nach ein bisschen herantasten hat dies auch geklappt. Die Prozeduren innerhalb des jeweiligen Frames funktionieren auch. Nur wenn ich die Frames aus Form2 füllen will, bekomme ich während der Laufzeit eine Zugriffsverletzung angezeigt. Die anderen Edits im Form2 werden ohne Probleme bedient.
Hier Code für Datei artikeldetails.pas
Delphi-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:
| unit artikeldetails;
interface
uses Windows, ..., frame_arttxt, ...
type TForm2 = class(TForm) ... arttxtpager: TAdvOfficePager; ... function ftxt_setzen(frame: TFrame2; framename: string; tabname: string): boolean; ... private public end;
var Form2: TForm2; ftxt1: TFrame2; ftxt2: TFrame2; ... function TForm2.ftxt_setzen(frame: TFrame2; framename: string; tabname: string): boolean; begin frame := TFrame2.Create(Self); frame.Name := framename; frame.Parent := arttxtpager.PageByCaption(tabname); frame.Align := alClient; end;
procedure TForm2.FormCreate(Sender: TObject); var arttab: TAdvOfficePage; i1, i2: integer; begin For i1:=1 to arttxtmg do begin arttab := TAdvOfficePage.Create(arttxtpager); arttab.AdvOfficePager := arttxtpager; arttab.Caption := 'Texte' + IntToStr(i1); case (i1) of 1: begin ftxt_setzen(ftxt1, 'Frame30', 'Texte' + IntToStr(i1)); end; 2: begin ftxt_setzen(ftxt2, 'Frame31', 'Texte' + IntToStr(i1)); end; .... end; end; end;
procedure TForm2.FormActivate(Sender: TObject); begin ftxt1.arttxtb.Text := 'hallo'; end;
end; |
Und hier für frame_arttxt.pas
Delphi-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:
| Unit frame_arttxt;
interface
uses Windows, ClipBrd,.., AdvEdit,...;
type TFrame2 = class(TFrame) Label108: TLabel; artcopyb: TAdvGlowButton; arttxtb: TAdvLUEdit; ... procedure artcopybClick(Sender: TObject); ... private public end;
implementation
{$R *.dfm}
procedure TFrame2.artcopybClick(Sender: TObject); begin Clipboard.AsText := arttxtb.Text; end; |
Ich hoffe, dass ich nicht zuviel entfernt habe. Vielleicht kann mir jemand einen Denkanstoß geben. Komischerweise wird der Zugriff
ftxt1.arttxtb.Text im Editor ohne Probleme zugelassen.
Vielen Dank im vorraus...
Th69 - So 31.07.22 08:44
Hallo und :welcome:
schau dir mal im Debugger in
FormCreate vor und nach dem Aufruf von
ftxt_setzen den Wert von
ftxt1 bzw.
ftxt2 an.
Ich könnte dir jetzt sofort die Lösung verraten, aber vllt. kommst du ja selber darauf?!
PS: Deine Schleife in Zusammenhang mit dem
case (...) of ist ein Anti-Pattern:
Loop-switch sequence [
https://en.wikipedia.org/wiki/Loop-switch_sequence].
Und du solltest deinen Klassen (und Variablen) bessere Namen als
TForm2 oder
TFrame2 geben (am besten so wie auch deine Dateien heißen).
steiniman1 - So 31.07.22 21:36
hallo Th69,
gleich mehrere Hausaufgaben auf einmal... mit dem Debugger habe ich bislang noch wenig Berührungspunkte gehabt, zumal mir dann zu viele "nil"-Pferde rumlaufen... :D Da werde ich wohl noch einige Tage brauchen, um richtig durchzusteigen
Ich bin eigentlich der Typ, der aus Beispielscripten am besten rumspielt und lernt. Leider fand ich nix, was für meine Idee passendsten war.
Bezüglich meines Anliegens habe ich einen Teilerfolg verbuchen können. Wenn ich in der ebenfalls als suboptimiere angesehene Case Lösung die nachfolgende Änderung vornehme, kann ich auf schon mal auf das gewünschte Edit zugreifen. Bei der Auslagerung klappt, trotz der entsprechenden Änderung (Self -> Form2) noch nicht. Da fehlt ihm also immer noch eine Zuordnung.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| case (i1) of 1: begin ftxt1 := TFrame2.Create(Form2); ftxt1.Name := 'Frame30'; ftxt1.Parent := arttxtpager.PageByCaption('Texte' + IntToStr(i1)); ftxt1.Align := alClient; ... end; |
Zu den anderen Hinweisen: Die Pages haben zwar die gleichen Frames, aber diese werden in dem Case individuell modifiziert, so dass ich denke, dass der Ansatz nicht ganz verkehrt ist. Sicher gibt es weitere Optimierungsmöglichkeiten, aber ich muss ja auch für später was zum basteln haben... ;)
Das TForm2 etc. hat mich nicht sonderlich gestört, da war ich eher bei den Komponentennamen zu Gange, aber hier gelobe ich Besserung.
Th69 - Mo 01.08.22 08:59
Wie kann man denn ohne Debugger (vernünftig) entwickeln?
Kennst du wenigstens die Schlüsselwörter
var und
out (als Referenz-Parameter)? Ansonsten s.
Parameter (Delphi) [
https://docwiki.embarcadero.com/RADStudio/Sydney/de/Parameter_(Delphi)].
Und wenn du mehrere Frames hast, warum nutzt du dann kein Array? So bräuchtest du nur einmal im Code
ftxt_setzen(...) verwenden.
Individuelle Änderungen kannst du ja dann nach der Schleife vornehmen.
Und sie (bzw. das Array) sollten
private Member der Klasse
TForm2 sein, keine globalen Variablen.
Außerdem ist mir noch aufgefallen, daß
ftxt_setzen zwar als
boolean definiert ist, du aber keinen Wert zurückgibst (sollte da nicht wenigstens eine Warnung beim Kompilieren erscheinen?). Alternativ zu
var bzw.
out könntest du auch (das erzeugte)
TFrame zurückgeben (und die Funktion dann in
CreateFrame umbenennen ;-)).
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 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!