![]() |
Objekte in verschiedenen Formularen zentral initialisieren
Ich möchte in verschiedenen Formularen alle Objekte eines Typs auf feste Werte setzen, in einer zentralen procedure.
Dafür verwende ich folgende procedure in meiner Unit uInitForm.pas.
Code:
Dies rufe ich z.B. aus form1 auf mit:
procedure InitFormControls(lfrm: TForm);
var i: Integer; component: TComponent; begin with lfrm do begin for i := 0 to ComponentCount - 1 do begin component := Components[i]; // Prüfen, ob die Komponente eine Font-Eigenschaft besitzt if component is TControl then begin // Fontname setzen für Textobjekte TControlAccess(component).Font.Name := FontNameGlobal; end; if component is TGraphicControl then begin // Fontname setzen für Grafikelemente TControlAccess(component).Font.Name := FontNameGlobal; end; if component is TPanel then // Prüfen, ob die Komponente ein TPanel ist begin (component as TPanel).Color := clFormBackground; (component as TPanel).BevelOuter := bvNone; (component as TPanel).Caption := ''; (component as TPanel).Color := clFormBackground; (component as TPanel).ParentColor := True; (component as TPanel).ParentFont := True; (component as TPanel).ShowCaption := False; end; end; end; end;
Code:
Dies funktioniert soweit ich es getestet habe.
procedure TfrmForm1.FormShow(Sender: TObject);
begin InitFormControls(Sender as TForm); end; Jetzt möchte ich aber alle Forms aus eine zentralen Form FormMain aufrufen: Dabei will ich dann die Form übergeben die initialisiert werden soll (Form1 oder Form2 oder Form3) wie übergebe ich hier den Sender-Parameter. Wenn ich die jeweilige Form übergebe, bekomme ich eine Memory Exception. InitFormControls(Form1); Oder geht das alles noch einfacher? |
AW: Objekte in verschiedenen Formularen zentral initialisieren
Die Exception kommt vermutlich deshalb, weil die FormX noch nicht erzeugt wurde und deshalb die FormX-Variable keinen gültigen Wert enthält.
Vielleicht könntest Du InitFormControls einfach aus dem jeweiligen Constructor der Form aufrufen statt aus Deiner Hauptform?
Delphi-Quellcode:
Oder aus dem OnCreate-Event der Form.
constructor TForm5.Create(Owner: TComponent);
begin inherited; InitFormControls(Self); end; Oder Du leitest alle Forms von einer Standard-Form ab und rufst in deren Constructor InitFormControls auf, dann passiert das für alle abgeleiteten Forms automatisch. |
AW: Objekte in verschiedenen Formularen zentral initialisieren
1, Sorge dafür das alle Formulare eine eigene Basisklasse haben.
Also statt TForm dann TMyForm. 2, Definiere in der TMyForm eine Methode InitFormControls Dort wird dann dein Code ausgeführt ohne with (Halte ich wie viele andere als ein zu vermeidendes Sprachkonstrukt) und übergabeparameter Also dann
Delphi-Quellcode:
Sehe das dummzeuch auch schon was geschrieben habe.
procedure TMyForm.InitFormControls;
begin for var i := 0 to ComponentCount - 1 do begin Das wäre mein nächsteer Punkt gewesen :-) |
AW: Objekte in verschiedenen Formularen zentral initialisieren
Danke für die Vorschläge.
Das Ausführen der gleichen Zeilen in jeder Form wollte ich ja gerade vermeiden um Änderungen nur an einer Stelle zu machen. Ist das Ändern der Komponenten im Create-Ereignis denn möglich, wenn die Komponenten noch gar nicht erzeugt wurden? Dass die Fehlermeldung möglicherweise auf ein nicht erstelltes Element zurückzuführen ist vermute ich auch, habe es aber extra in eine procedure gelegt die nach dem Erstellen der Forms aufgerufen wird. Ich wollte etwas Hilfe zum übergeben der Form in der InitFormControls Procedure, warum ich frmForm1 nicht übergeben kann, wenn doch der Übergabeparameter ein TForm Typ ist. |
AW: Objekte in verschiedenen Formularen zentral initialisieren
Liste der Anhänge anzeigen (Anzahl: 1)
Du kannst es ja eventuell so machen wie ich im beigefügten Bild zeige.
|
AW: Objekte in verschiedenen Formularen zentral initialisieren
Bei VCL wird aber das als erstes erzeugte Formular zum MainForm...
|
AW: Objekte in verschiedenen Formularen zentral initialisieren
Liste der Anhänge anzeigen (Anzahl: 1)
Uwe, danke für den Hinweis. Dann kann er aber die zusätzlichen Formulare aus der automatischen Initialisierung rüber schieben nach "Verfügbare Formulare und dann im OnCreate oder OnShow selber erzeugen,
danach hätte er dann ja das nötige Erreicht. |
AW: Objekte in verschiedenen Formularen zentral initialisieren
Hatte gerade mal ein bisserl "Langeweile" und da viel mir ein, dass es doch die Methode Loaded gibt, die erst nach dem Erstellen aller automatisch zu erstellenden Formulare eines Programmes aufgerufen wird.
Da ich das nicht so mal eben implementieren kann, hab' ich mal 'ne KI befragt: Zitat:
Zitat:
Delphi-Quellcode:
unit ConfigManager;
interface uses System.SysUtils, System.Classes, Vcl.Forms, Vcl.Controls, System.IniFiles; type TConfigManager = class private FIniFile: TIniFile; public constructor Create; destructor Destroy; override; procedure LoadConfig; procedure ApplyConfigToForms; end; implementation constructor TConfigManager.Create; begin inherited; FIniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI')); end; destructor TConfigManager.Destroy; begin FIniFile.Free; inherited; end; procedure TConfigManager.LoadConfig; begin // Laden Sie hier Ihre Konfigurationsdaten aus der INI-Datei // Beispiel: // FButtonColor := FIniFile.ReadInteger('Controls', 'ButtonColor', clBtnFace); end; procedure TConfigManager.ApplyConfigToForms; var i, j: Integer; Form: TForm; Control: TControl; begin for i := 0 to Screen.FormCount - 1 do begin Form := Screen.Forms[i]; for j := 0 to Form.ComponentCount - 1 do begin if Form.Components[j] is TControl then begin Control := TControl(Form.Components[j]); // Wenden Sie hier Ihre Konfiguration auf die Controls an // Beispiel: // if Control is TButton then // TButton(Control).Color := FButtonColor; end; end; end; end; end. Zitat:
Delphi-Quellcode:
unit MainForm;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ConfigManager; type TFormMain = class(TForm) private FConfigManager: TConfigManager; protected procedure Loaded; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; var FormMain: TFormMain; implementation {$R *.dfm} constructor TFormMain.Create(AOwner: TComponent); begin inherited; FConfigManager := TConfigManager.Create; end; destructor TFormMain.Destroy; begin FConfigManager.Free; inherited; end; procedure TFormMain.Loaded; begin inherited; FConfigManager.LoadConfig; FConfigManager.ApplyConfigToForms; end; end. Zitat:
|
AW: Objekte in verschiedenen Formularen zentral initialisieren
Well, if all your forms are already dpr created, meaning they are in the available forms in project options, then something like this should work
Delphi-Quellcode:
For runtime created forms and to minimize and centralize the code, use DDetours to hook TForm.Create then execute the original code followed by your InitFormControls after checking that the TForm is one of yours, if you would use DDetours then you don't any any code like the above.
procedure TMainForm.FormCreate(Sender: TObject);
begin // These also could be adjusted and moved to initialization section FAlreadyActivated := False; // in case OnActivate is used in the project then it should be stored and restored later* Application.OnActivate := OnApplicationActivate; end; procedure TMainForm.OnApplicationActivate(Sender: TObject); var C: Integer; begin // ExitProc assigned in TApplication.Run meanning it could be used as indicator for done creating forms // can help in case Application.Activate wrongly (missused by) being called from a form constructor if not Assigned(ExitProc) then Exit; if not FAlreadyActivated then begin C := Application.ComponentCount; while C > 0 do begin Dec(C); if Application.Components[C] is TForm then // InitFormControls(Application.Components[C]); end; end; FAlreadyActivated := True; // here is later* ,( to restore original or more useful OnActivate) end; ![]() |
AW: Objekte in verschiedenen Formularen zentral initialisieren
Ich habe berücksichtigt, dass die Formulare erst erstellt werden müssen.
Dazu habe ich im frmMain.Activate die Formulare erst created, dann einem Tab des OfficePagers von TMS zugewiesen und danach erst das Show und LoadKunden mit dem InitFormControls ausgeführt. Bei Ausführung von LoadKunden bzw. InitFormControls(frmKunden As TForm) tritt dann die Exception: "Zugriffsverletzung an Adresse xxxx in Modul 'Programm.exe' (Offset(xxx)). Lesen von Adresse 00000010."
Code:
procedure TfrmMain.FormActivate(Sender: TObject);
var frmTabKunden: TfrmKunden; frmTabInteressent: TfrmInteressent; frmTabPartner: TfrmPartner; frmTabAngestellte: TfrmAngestellte; frmTabKassen: TfrmKassen; PagerHeight: Integer; begin // -------------------------------------------- // Größe und Positionierung des Hauptformulars PagerHeight := 540; // Höhe des inneren Tabs bis vor das Grid frmMain.Top := 20; // Main Formular Position Top und Left frmMain.Left := 20; frmMain.Height := 1000; // Größe des Main Formulars frmMain.Width := 1830; // -------------------------------------------- OfficePager.Height := PagerHeight; // -------------------------------------------- // Formulare in das OfficePager Element einbinden // -------------------------------------------- // TabKunden frmTabKunden := TfrmKunden.Create(TabKunden); frmTabKunden.Parent := TabKunden; frmTabKunden.Align := alClient; frmTabKunden.BorderStyle := bsNone; frmTabKunden.Show; LoadKunden; // -------------------------------------------- . . . OfficePager.ActivePage := TabKunden; end; procedure TfrmMain.LoadKunden; var s:string; i, sp: Integer; begin s:='-----------Kunden----------'; DebugOut(s); InitFormControls(frmKunden); // Hier tritt das Problem auf frmKunden.InitFormKunden; . . . end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:45 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 by Thomas Breitkreuz