[fpc-pascal] Re: Fpc Access Violation if AppConfigDir doesn't exist.

Giuliano Colla giuliano.colla at fastwebnet.it
Tue Feb 12 13:29:02 CET 2013


On 02/11/2013 09:14 PM, Sven Barth wrote:
> It would be nice if you could minimize the problemematic code further 
> step by step so that we can see what caused the "missing dialog". 
> Maybe it's a bug somewhere else...
>
I've made some further experiments with my minimal test.
Test form is just a Form with a Close button (BitBtn Kind=bkClose).
The full code is the following:

unit uinitfile;

{$mode objfpc}{$H+}

interface

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

type

   { TForm1 }

   TForm1 = class(TForm)
     BitBtn1: TBitBtn;
     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
     procedure FormCreate(Sender: TObject);
   private
     { private declarations }
   public
     { public declarations }
   end;

var
   Form1: TForm1;
   ini: TIniFile;
   AppConfigFileName: string;
   SomeData: boolean;
   SomeOtherData: boolean;
implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  AppConfigFileName:= '/not/existing/path/inifile.cfg';
  ini := TIniFile.Create(AppConfigFileName);
  try
    SomeData:= ini.ReadBool('Section','Val',true);
    SomeOtherData:= ini.ReadBool('Section','Val1',true);
  finally
    ini.Free;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
   ini:= TIniFile.Create(AppConfigFileName);
{$DEFINE Finally}
{$IFDEF Finally}
   try
     ini.WriteBool('Section','Val',SomeData);
     ini.WriteBool('Section','Val1',SomeOtherData);
   finally
     ini.Free;
   end;
{$ELSE}
   try
     ini.WriteBool('Section','Val',SomeData);
     ini.WriteBool('Section','Val1',SomeOtherData);
   except
     MessageDlg('Error while writing '+AppConfigFileName,mtError,[mbOK],0);
   end;
   ini.Free;
{$ENDIF}
end;

end.

One may test two conditions: with try..finally and with try..except.
Even with this minimal sheds some light on the matter.

Try..finally situation, with IDE and Debugger.
Press the Close button. A debugger error notification is shown. Pressing 
"Continue", an error dialog is displayed: "Unable to create ... press OK 
to Ignore...etc.":
Pressing OK (no harm should come, just the file can't be written) the 
form isn't closed as it should, and it's still there.
Pressing again the close Button, FormClose is executed again, and the 
same dialog is shown. No way to close the form, unless you press Cancel 
on the error dialog.
Why FormClose doesn't close the form in presence of an error (handled by 
a try..finally) when writing the ini file?
Launching from command line, you have the same behavior, and an 
additional information when you select Cancel:

WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?


Try..except situation, from IDE and Debugger.
Press the Close button. Debugger Notification. Pressing Continue my 
message dialog is shown. Pressing OK on my dialog the form is closed and 
the program is terminated.
Launching from command line, no console messages.

My conclusion is that one can't properly handle INI files with just a 
try..finally construct, as all examples show, because a possible error 
will propagate outside the construct, with unpredictable effects (in 
this case the FormClose procedure doesn't properly complete).

Giuliano




More information about the fpc-pascal mailing list