Recent

Author Topic: Sharing One INI File Between Forms  (Read 453 times)

Dennis1

  • Newbie
  • Posts: 3
Sharing One INI File Between Forms
« on: July 11, 2019, 04:24:26 am »
I'm a beginner working on a simple program that uses an INI file to save some short text data. The program has two forms. I need the second form to be able to overwrite the same INI file as the main form. This works just fine. BUT when I close the program the INI file has magically reverted to its previous values. I have no idea why, since the main form doesn't even contain any writing procedure at all; it just reads.

I've opened the INI file in Notepad between writing values from Form2 and closing the program, and the new data is indeed present. But it reverts with no apparent cause as soon as the program closes. What am I doing wrong?

This is how I call the write function in Form2:   
Code: Pascal  [Select]
  1. Unit1.Form1.INI.WriteString('0',TabCaption.Text);

Thanks.

trev

  • Full Member
  • ***
  • Posts: 106
Re: Sharing One INI File Between Forms
« Reply #1 on: July 11, 2019, 08:07:51 am »
Sounds like your program must be re-writing the INI file on exit with the original values then.

As for your one line of code it looks like it's missing something. Compare:

Code: Pascal  [Select]
  1. iniFile.WriteString(Section, Name, Value);
  2.  
o Lazarus v2.1.0 r61574, FPC v3.3.1, macOS 10.14.5
o Lazarus v2.0.0, FPC v3.0.4, FreeBSD 12.0
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04

Dennis1

  • Newbie
  • Posts: 3
Re: Sharing One INI File Between Forms
« Reply #2 on: July 11, 2019, 03:25:31 pm »
Sounds like your program must be re-writing the INI file on exit with the original values then.

As for your one line of code it looks like it's missing something. Compare:

Code: Pascal  [Select]
  1. iniFile.WriteString(Section, Name, Value);
  2.  

Thank you for your response.

That's what I thought, too, except the program contains no code devoted to writing except what I quoted. I even searched for the words "Write" and "INI" to be sure. It's an extremely basic notepad-type application with tabbed text boxes. The INI file stores tab labels that have been changed by the user.

In terms of the "Name" section, that seems to apply to DoWriteString rather than WriteString, as far as I can tell. I drew the INI control on Form1 and then provided the section name ("Settings") as a property in the properties window.

If this is a bug -- a big if, because I'm a total newb! -- the way to reproduce it would be to create two forms, add an INI control to Form1, then try to overwrite some preexisting values via Form2. The new data will be saved to disk from Form2, but then magically revert when the program exits.

Thanks.
« Last Edit: July 11, 2019, 03:36:30 pm by Dennis1 »

lucamar

  • Hero Member
  • *****
  • Posts: 1802
Re: Sharing One INI File Between Forms
« Reply #3 on: July 11, 2019, 03:45:59 pm »
You are not using the same file in a TIniPropStorage, are you? Because then it would get automaticaly written over on program exit.

If you're using a normal TIniFile, try setting CacheUpdates to False, even if just as a debug measure. Although from what you say it can be inferred that the writing is indeed being done.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

wp

  • Hero Member
  • *****
  • Posts: 5831
Re: Sharing One INI File Between Forms
« Reply #4 on: July 11, 2019, 03:51:55 pm »
[...] I'm a total newb! [...]
Then maybe a small demo is more worth than thousand words? The attached mini project has two forms with some primitive data entry. An ini file is used to store the data as well as form position and size. The ini file is read whenever the form opens, and is stored whenever the form closes. There are two separate sections, one for each form.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Dennis1

  • Newbie
  • Posts: 3
Re: Sharing One INI File Between Forms
« Reply #5 on: July 11, 2019, 04:14:05 pm »
You are not using the same file in a TIniPropStorage, are you? Because then it would get automaticaly written over on program exit.

If you're using a normal TIniFile, try setting CacheUpdates to False, even if just as a debug measure. Although from what you say it can be inferred that the writing is indeed being done.

You're right! I was using both. I thought I needed both "TIniPropStorage" and "IniFiles" in the "uses" section, but apparently not! I took out "TIniPropStorage," deleted the INI control from the form, and then re-wrote the save lines as

Code: Pascal  [Select]
  1. INI2.WriteString('Settings','0',TabCaption.Text);


That did the trick: both forms now use the same INI file. No more magical overwrites.

Thank you to all!

lucamar

  • Hero Member
  • *****
  • Posts: 1802
Re: Sharing One INI File Between Forms
« Reply #6 on: July 11, 2019, 05:17:39 pm »
Glad it helped ;)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 1656
Re: Sharing One INI File Between Forms
« Reply #7 on: July 11, 2019, 11:35:36 pm »
I usually have a UNIT in my project called "Common". That unit will get included in all other units.

It will contain all defines that all other units need including a Setupini handler..

In the initialization section I create the Object and in the finalization section I free the object..

Through out the app I access that ini file from that object because the unit COMMON is included..

 so its common to all other units..

lucamar

  • Hero Member
  • *****
  • Posts: 1802
Re: Sharing One INI File Between Forms
« Reply #8 on: July 12, 2019, 12:21:26 am »
I usually have a UNIT in my project called "Common". That unit will get included in all other units.

It will contain all defines that all other units need including a Setupini handler..

In the initialization section I create the Object and in the finalization section I free the object..

Through out the app I access that ini file from that object because the unit COMMON is included..

 so its common to all other units..

That's what a DataModule is for, though if it's just a few state/global vars, some common objects/components (not controls!), etc. a normal unit suffices usually.

I do the same in multiform applications for p.e. common dialogs, setup records, etc.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 1656
Re: Sharing One INI File Between Forms
« Reply #9 on: July 12, 2019, 11:27:06 pm »
I've used modules before, I guess I could do that at any time..

That's one thing I wish I could figure out with Laz and that is if I decide to have Tform inserted or module
placed in a ready made file I can and it will manage it.

 Currently if I want a new form it always starts a new unit.

Maybe someone could throw me a bone as to how starting a new form can be placed in a ready made unit
that has not any forms yet!

lucamar

  • Hero Member
  • *****
  • Posts: 1802
Re: Sharing One INI File Between Forms
« Reply #10 on: July 13, 2019, 01:01:44 am »
Maybe someone could throw me a bone as to how starting a new form can be placed in a ready made unit
that has not any forms yet!

Basic implementation of a form that can be placed inside any other unit. Then you can for example do
Code: Pascal  [Select]
  1. AForm :=  TDynamic.Create(Application);
  2. {or AForm := TDynamic.CreateNew(Application);}
  3. AForm.Show;

Code: Pascal  [Select]
  1. unit DynForm;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TDynamic }
  13.  
  14.   TDynamic = class(TForm)
  15.     InfoLabel: TLabel;
  16.     OKButton: TButton;
  17.     constructor Create(AOwner: TComponent); override;
  18.     destructor Destroy; override;
  19.     procedure OKClick(Sender: TObject);
  20.   end;
  21.  
  22. implementation
  23.  
  24. { TDynamic }
  25.  
  26. constructor TDynamic.Create(AOwner: TComponent);
  27. begin
  28.   inherited Create(AOwner);
  29.   InfoLabel := TLabel.Create(Self);
  30.   InfoLabel.Caption := 'I''m up, up, on top!';
  31.   InfoLabel.Alignment := taCenter;
  32.   InfoLabel.Align := alTop;
  33.   InfoLabel.Parent := Self;
  34.   OKButton := TButton.Create(Self);
  35.   OKButton.Caption := 'Huge "&Close" button!';
  36.   OKButton.OnClick := @OnClick;
  37. end;
  38.  
  39. destructor TDynamic.Destroy;
  40. begin
  41.   InfoLabel.Free;
  42.   OKButton.Free;
  43.   inherited Destroy;
  44. end;
  45.  
  46. procedure TDynamic.OKClick(Sender: TObject);
  47. begin
  48.   Close
  49. end;
  50.  
  51. end.

The lazarus examples folder is choked full of demos and tests built entirely like this :)
« Last Edit: July 13, 2019, 01:03:52 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 1656
Re: Sharing One INI File Between Forms
« Reply #11 on: July 13, 2019, 02:50:49 am »
yes I've done dynamic forms many times  :D

But if memory serves, I believe If I place a constructed form in the unit based on TForm, the next time I
open that unit the OI shows it and I can then start using OI to manage it..

lucamar

  • Hero Member
  • *****
  • Posts: 1802
Re: Sharing One INI File Between Forms
« Reply #12 on: July 13, 2019, 03:47:48 am »
yes I've done dynamic forms many times  :D

But if memory serves, I believe If I place a constructed form in the unit based on TForm, the next time I
open that unit the OI shows it and I can then start using OI to manage it..

Not unless you do have the corresponding .lfm. Note that the above code doesn't have the typical: {$R *.lfm} because there's no form "resource". That's why everything has to be created and setup in the constructor.

BTW:

yes I've done dynamic forms many times  :D

So ... what was you wanted, then?
« Last Edit: July 13, 2019, 03:49:57 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.