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
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 22: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
187 Beiträge
 
Delphi 12 Athens
 
#2

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 22: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 (11. Jan 2025 um 23:07 Uhr) Grund: Anhang vergessen :-)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.598 Beiträge
 
Delphi 7 Professional
 
#3

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 11. Jan 2025, 23: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 (11. Jan 2025 um 23:45 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#4

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 07: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
 
#5

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 13: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
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 13:43
Fu erzeugst das Formular in FormActivate auf einer lokalen Variablen frmTabKunden, der Zugriff erfolgt aber auf der globalen Variablen frmKunden. Das kann natürlich nicht klappen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

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

AW: Objekte in verschiedenen Formularen zentral initialisieren

  Alt 12. Jan 2025, 14:45
Danke Uwe das hast Du richtig erkannt, durch die Zuweisung auf frmTabKunden muss ich diese auch ansprechen und nicht das Original-Formular.
Die Initialisierung der Controls in den Formularen soll nur einmal gemacht werden
und nicht bei jedem Aufruf des Formulars
daher kann ich das nicht im Create der Formulare machen, da dort noch nichts angelegt ist
und im .Show würde er es jedesmal ausgeführt wenn das Formular aufgerufen wird.
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:17 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-2025 by Thomas Breitkreuz