[gelöst]Verständnisfrage: Ändern von Eigenschaften einer Form

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
Beach
Lazarusforum e. V.
Beiträge: 60
Registriert: Di 2. Nov 2021, 22:41
OS, Lazarus, FPC: Lazarus 3.0RC1 (rev lazarus_3_0_RC1-10-gfe49fef4fc) FPC 3.2.2 x86_64-win64-win32
CPU-Target: 64Bit
Wohnort: Hunsrück

[gelöst]Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von Beach »

Hallo zusammen,
ich stehe mal wieder total auf dem Schlauch. Bitte helft mir mal einen Schritt zur Seite.
Ich möchte Eigenschaften einer Form in einer INI Datei speichern und beim erneuten Aufruf der Form wieder übernehmen.
Ich möchte damit ein bestehendes Projekt erweitern.

In dem Projekt habe ich eine neue Form (Unit2) erzeugt und diese bei uses der Hauptform (Unit1) eingefügt.
Ein Button auf die mainform, welcher mir dann die neue Form (Unit2) Modal aufruft.
Das neue Fenster wird auch erstellt, aber die Eigenschaften werden nicht entsprechend geändert.
Fehlermeldungen sehe ich auch keine.

Nehme ich nun den Grundlegenden Code und schreibe das alles in ein neues Projekt mit lediglich einer Form, klappt das wie vorgesehen.
Ich bin im Moment maximal verwirrt

Hier mal die Variante die Funktioniert:

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, IniFiles, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
const
  inifile = 'goarista.ini';

implementation

{$R *.lfm}

{ TForm1 }

procedure setupForm(ini: TIniFile);
var
  i: integer;
begin
  i := ini.ReadInteger('window', 'height', 240);

  Form1.Height := i; //ini.ReadInteger('window', 'height', 240);
  Form1.Width := ini.ReadInteger('window', 'width', 320);
  Form1.Color := ini.ReadInteger('window', 'color', clNone);

end;


procedure TForm1.FormCreate(Sender: TObject);
var
  ini: TIniFile;
begin
  ini := TIniFile.Create(inifile);
  try
    setupForm(ini);  {hier kommen gleich die Lese/Schreibbefehle rein}
  finally
    Form1.Caption:= inttoStr(Form1.Height) + ' x ' + IntToStr(Form1.Width);
    ini.Free;
  end;
end;
end.
Habe ich nun eine Form mit einem Button, welcher diese Unit Modal aufruft klappt es nicht:

Aufruf mit:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(nil);   //Form wird erstellt
  Form2.ShowModal;               //Form wird angezeigt
  FreeAndNil(Form2);             //Form wieder freigegeben;

end;

Code: Alles auswählen

unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, IniFiles, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private


  public

  end;

var
  Form2: TForm2;

const
  inifile = 'goarista.ini';

implementation

{$R *.lfm}

{ TForm2 }
procedure setupForm(ini: TIniFile);
var
   i: integer;
begin
  i := ini.ReadInteger('window', 'height',240);

  Form2.Height := i; //ini.ReadInteger('window', 'height', 240);
  Form2.Width := ini.ReadInteger('window', 'width', 320);
  Form2.Color := ini.ReadInteger('window', 'color', clNone);

end;


procedure TForm2.Button1Click(Sender: TObject);
begin
  Form2.Caption:='Schließen';
  sleep(5000);
  close;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  ini : TIniFile;

begin
   ini := TIniFile.Create(inifile);
  try
     setupForm(ini);  {hier kommen gleich die Lese/Schreibbefehle rein}
  finally
    ini.Free;
  end;

end;

end.
Inhalt des INI File:

Code: Alles auswählen

[window]
height=625
width=789
color=15461355
Lazarus 3.0RC1 (rev lazarus_3_0_RC1-10-gfe49fef4fc) FPC 3.2.2 x86_64-win64-win32/win64
Zuletzt geändert von Beach am Mi 24. Apr 2024, 19:11, insgesamt 1-mal geändert.
MfG
Beach

Shit happens... Always in my shift

wp_xyz
Beiträge: 5129
Registriert: Fr 8. Apr 2011, 09:01

Re: Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von wp_xyz »

Ich denke, das liegt daran, dass beide Forms mit denselben Schlüsseln in dieselbe Ini-Datei schreiben. Konkret: Wenn du Form2 schließt schreibt es seine Daten in die Ini-Datei - das müsstest du prüfen können, wenn du einen Breakpoint auf dem "end" von TForm1.Button1Click setzt und dann mit einem Editor dir die Ini-Datei ansiehst. Wenn aber dann später Form1 geschlossen wird, überschreibt dieses die von Form2 geschriebenen Werte (das ist eine Vermutung, weil du den Code zum Schreiben nicht zeigst; aber auch beim Lesen machen die beiden Forms keinen Unterschied). Als Lösung müsstest du den Formularnamen im Ini-Datei-Schlüssel unterbringen:

Code: Alles auswählen

// in unit1:
procedure setupForm(ini: TIniFile);
begin
  Form1.Height := ini.ReadInteger('Form1', 'height', 240);
  Form1.Width := ini.ReadInteger('Form1', 'width', 320);
  Form1.Color := ini.ReadInteger('Form1', color', clNone);
end;

// in unit2:
procedure setupForm(ini: TIniFile);
begin
  Form2.Height := ini.ReadInteger('Form2', 'height', 240);
  Form2.Width := ini.ReadInteger('Form2', 'width', 320);
  Form2.Color := ini.ReadInteger('Form2', color', clNone);
end;
Als Bemerkung noch generell: Das ist zweimal derselbe Code, genauso der OnCreate-Handler. Ich würde das mit ein paar Zusatzparametern allgemeiner gestalten und in eine eigene Unit packen. Diese Unit kannst du in Unit1 und Unit2 verwenden und den Code dort aufrufen.

Code: Alles auswählen

unit Utils;
interface
uses IniFiles, Forms;

procedure ReadIni(IniFileName: String; AForm: TForm);

implementation

procedure SetupForm(ini: TIniFile; AForm: TForm; Abschnitt: String);
begin
  AForm.Height := ini.ReadInteger(Abschnitt, 'height', AForm.Height);
  AForm.Width := ini.ReadInteger(Abschnitt, 'width', AForm.Width);
  AForm.Color := ini.ReadInteger(Abschnitt, 'color', AForm.Color);
  AForm.Caption:= inttoStr(AForm.Height) + ' x ' + IntToStr(AForm.Width); 
end;

procedure ReadIni(IniFileName: String; AForm: TForm);
var
  ini: TIniFile;
  abschnitt: String;
begin
  ini := TIniFile.Create(IniFileName);
  try
    abschnitt := AForm.Name;
    if abschnitt = '' then abschnitt := AForm.ClassName;  // unschön, weil so nur 1 Instanz der AForm-Klasse verwendet werden kann.
    SetupForm(ini, AForm, abschnitt);
  finally
    ini.Free;
  end;
end;
end.
Aufruf:

Code: Alles auswählen

  // in Unit1
 uses Utils, ...;
 
 procedure TForm1.FormCreate(Sender: TObject);
 begin
   ReadFromIni(inifile, self);
end;

// Unit 2: analog

Benutzeravatar
Beach
Lazarusforum e. V.
Beiträge: 60
Registriert: Di 2. Nov 2021, 22:41
OS, Lazarus, FPC: Lazarus 3.0RC1 (rev lazarus_3_0_RC1-10-gfe49fef4fc) FPC 3.2.2 x86_64-win64-win32
CPU-Target: 64Bit
Wohnort: Hunsrück

Re: Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von Beach »

Danke für die Prompte Antwort.
Ich habe mich da aber wohl etwas undurchsichtig ausgedrückt.

Diese Unit1 die ich gepostet habe ist ein eigenständiges Testprojekt um zu sehen ob der Code überhaupt funktioniert.
Die Unit2 wir von einer anderen Unit aufgerufen. In dieser aufrufenden Unit wird kein Zugriff auf die INI Datei gemacht (noch nicht)

Ich möchte in einem bestehenden Projekt ein Extra Fenster haben, in welchem ich Einstellungen für das Projekt vornehmen kann.
Hoffe das ist nun besser verständlich.
MfG
Beach

Shit happens... Always in my shift

shokwave
Beiträge: 475
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von shokwave »

Ich hätte da 2, hoffentlich hilfreiche, Anmerkungen.

1. Benutze keinen relativen Pfad für den Dateinamen, denn der bezieht sich auf das aktuelle Arbeitsverzeichnis und das ist vielleicht nicht das, was du glaubst das es ist. Wenn du die INI also in deinem Programmverzeichnis suchst, könnte man das so machen:

Code: Alles auswählen

inifile = ExtractFilePath(ParamStr(0)) + 'goarista.ini';
Dazu müsste inifile aber eine Variable sein und der Code in OnCreate stehen.

2.Ich speichere meine Einstellungen inkl. Fensterposition und -größe auch meist in einer INI. Ich habe mir angewöhnt das Laden im OnShow zu machen, damit garantiert ist, das die Objekte existieren und fertig initialisiert sind. Damit die Einstellungen nur einmalig geladen werden, benutze ich eine Hilfsvariable. Das sieht dann in etwa so aus:

Code: Alles auswählen

procedure TMainForm.FormCreate(Sender: TObject);
begin
  IsProgramStart := True;
end;  

procedure TMainForm.FormShow(Sender: TObject);
begin
  if (IsProgramStart) then
  begin
    LoadConfig;
    IsProgramStart := False;
  end;
end;
Hoffe das hilft bei deinem Problem.
mfg Ingo

Benutzeravatar
Beach
Lazarusforum e. V.
Beiträge: 60
Registriert: Di 2. Nov 2021, 22:41
OS, Lazarus, FPC: Lazarus 3.0RC1 (rev lazarus_3_0_RC1-10-gfe49fef4fc) FPC 3.2.2 x86_64-win64-win32
CPU-Target: 64Bit
Wohnort: Hunsrück

Re: Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von Beach »

Danke @shokwave
Ich bin mir nicht sicher woran es nun im Endeffekt gelegen hat, aber nun macht es was es soll.

Was ich getan habe:
Den Aufruf hab ich in das ONShow Event verschoben und den Pfad mit

Code: Alles auswählen

  filename := ExtractFilePath(ParamStr(0))+inifile;
zusammengestellt.
Die Ladesperre werde ich noch nachrüsten.
MfG
Beach

Shit happens... Always in my shift

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst]Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von fliegermichl »

Oder noch einfacher.
Platziere in jedem Formular eine TIniPropStorage Komponente (Reiter Misc).
In dem Editor, der sich bei der Eigenschaft SessionProperties des jeweiligen Formulares öffnet, fügst du einfach alle Eigenschaften hinzu, welche gespeichert werden sollen.
Braucht keine einzige Zeile Code dafür.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6762
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: [gelöst]Verständnisfrage: Ändern von Eigenschaften einer Form

Beitrag von af0815 »

Achtung Falle bei dem Speichern von Größen und Positionen.

Ich arbeite mir mehreren Monitoren oder nur mit dem Laptop Bildschirm. Wenn man es blöd anlegt, wird das Programm zwar gestartet, ist aber am Desktop nicht sichtbar, weil die Koordinaten im Ar..h sind. Mühsam heraussuchen wo das Programm seine Koordinaten speichert, die löschen, damit der ganze Sche... wieder funktioniert. Betrifft durchaus auch teure professionelle Programme unter Windows.

Nur das so als Hinweis.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten