AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Objekte in verschiedenen Formularen zentral initialisieren
Thema durchsuchen
Ansicht
Themen-Optionen

Objekte in verschiedenen Formularen zentral initialisieren

Ein Thema von Smiley · begonnen am 11. Jan 2025 · letzter Beitrag vom 12. Jan 2025
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
210 Beiträge
 
Delphi 12 Athens
 
#1

Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 17:11
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:
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;
Dies rufe ich z.B. aus form1 auf mit:

Code:
procedure TfrmForm1.FormShow(Sender: TObject);
begin
  InitFormControls(Sender as TForm);
end;
Dies funktioniert soweit ich es getestet habe.

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?
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.642 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 17:18
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:
constructor TForm5.Create(Owner: TComponent);
begin
  inherited;
  InitFormControls(Self);
end;
Oder aus dem OnCreate-Event der Form.

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.
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.207 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 17:22
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:
procedure TMyForm.InitFormControls;
begin
  for var i := 0 to ComponentCount - 1 do
  begin
Sehe das dummzeuch auch schon was geschrieben habe.
Das wäre mein nächsteer Punkt gewesen
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
210 Beiträge
 
Delphi 12 Athens
 
#4

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 19:15
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.
  Mit Zitat antworten Zitat
DaCoda

Registriert seit: 21. Jul 2006
Ort: Hamburg
164 Beiträge
 
Delphi 12 Athens
 
#5

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 23:25
Du kannst es ja eventuell so machen wie ich im beigefügten Bild zeige.
Miniaturansicht angehängter Grafiken
beispiel.jpg  
Debuggers don’t remove bugs, they only show them in slow-motion.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.525 Beiträge
 
Delphi 12 Athens
 
#6

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 23:29
Bei VCL wird aber das als erstes erzeugte Formular zum MainForm...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
DaCoda

Registriert seit: 21. Jul 2006
Ort: Hamburg
164 Beiträge
 
Delphi 12 Athens
 
#7

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 23:39
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.
Angehängte Dateien
Dateityp: zip Mini-Sample.zip (79,2 KB, 1x aufgerufen)
Debuggers don’t remove bugs, they only show them in slow-motion.

Geändert von DaCoda (12. Jan 2025 um 00:07 Uhr) Grund: Anhang vergessen :-)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.524 Beiträge
 
Delphi 7 Professional
 
#8

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 00:27
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 von Frage:
Wenn ich in einem Delphiprogramm nach der Initialisierung aller Formulare für die darauf befindlichen TControl-Nachfahren eine einheitliche Konfiguration an einer zentralen Stelle durchführen möchte, wie ließe sich dies realisieren? Die Konfigurationsdaten sollten ggfls. aus einer Ini-Datei (oder auf ähnlichem Weg) ausgelesen werden. Im Idealfall wäre dies alles an einer zentralen Stelle, eventuell einer eigenen Unit, zu realisieren.
Zitat von Antwort:
Um eine einheitliche Konfiguration für alle TControl-Nachfahren in allen Formularen eines Delphi-Programms nach der Initialisierung durchzuführen, können Sie die folgende Lösung implementieren:

Erstellen Sie eine separate Unit für die zentrale Konfiguration, z.B. "ConfigManager.pas".
In dieser Unit definieren Sie eine Klasse TConfigManager mit Methoden zum Laden der Konfiguration aus einer INI-Datei und zum Anwenden der Konfiguration auf die Formulare.
Verwenden Sie die Loaded-Methode des Hauptformulars, um die Konfiguration nach der Initialisierung aller Formulare anzuwenden.

Hier ist ein Beispiel für die Implementierung:
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:
Im Hauptformular überschreiben Sie die Loaded-Methode, um die Konfiguration anzuwenden:
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:
Diese Lösung bietet folgende Vorteile:

Zentralisierte Konfiguration in einer separaten Unit.
Automatische Anwendung der Konfiguration auf alle Formulare und Controls nach der Initialisierung.
Einfache Erweiterbarkeit für verschiedene Control-Typen und Konfigurationsoptionen.

Stellen Sie sicher, dass Sie die ConfigManager-Unit in den Uses-Klauseln aller Formulare einbinden, die konfiguriert werden sollen. Diese Methode ermöglicht eine flexible und wartbare Lösung für die einheitliche Konfiguration aller Formulare und Controls in Ihrem Delphi-Programm.
Nur so als Idee. Etwas vom Prinzip sehr Ähnliches, bei dem die Konfigurationsdaten aus der Registry gelesen werden und beim Programmende zurückgeschrieben werden, hab' ich vor Jahren mal für Delphi 7 implementiert. Das Grundprinzip des KI-Beispiels kommt dem sehr nahe, so dass ich davon ausgehe, dass Du das Beispiel übernehmen kannst und eine Anpassung an Deine Anforderungen möglich sein sollte.

Geändert von Delphi.Narium (12. Jan 2025 um 00:45 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
379 Beiträge
 
#9

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 08:44
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:
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;
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.

https://github.com/MahdiSafsafi/DDetours
Kas
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
210 Beiträge
 
Delphi 12 Athens
 
#10

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 14:26
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;
  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 06:25 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