Mikhail
Mikhail

Reputation: 1356

Delphi: Writing to Registry Not Working on FormDestroy

procedure TMainForm.FormDestroy(Sender: TObject);
var
  Registry: TRegistry;
begin
  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_CURRENT_USER;
    if Registry.OpenKey('...', True) then
    begin
      Registry.WriteInteger('MainLeft', Self.Left);
      Registry.CloseKey;
    end;
  finally
    Registry.Free;
  end;
end;

Similar code works for FormCreate, but not when the application is closed (i.e. nothing is saved to the registry). What am I missing?

The '...' stands for the registry key name. Since it works for FormCreate, I don't think it's an issue.

If I add MainForm.Destroy to the program code:

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
  MainForm.Destroy;
end.

nothing changes. If I also set FormDestroy as MainForm's OnDestroy event, I get "Access violation" error upon closing the application.

Upvotes: 2

Views: 1915

Answers (6)

Remy Lebeau
Remy Lebeau

Reputation: 598309

OnCreate and OnDestroy are not good places to load/save Registry values that affect the positioning of the window. Override CreateWnd() and DestroyWnd() methods instead. Also, instead of loading/saving individual properties, like Left, use the Win32 API SetWindowPlacement() and GetWindowPlacement() functions instead, which also allows you to load/save maximized/minimized states accurately as well.

Upvotes: 0

gabr
gabr

Reputation: 26850

Does your FormDestroy execute at all?

RE: P.S. and P.P.S.

Something else is going wrong in your app. Write a small Delphi program that will access registry in FormDestroy and you'll see that everything is working fine (if not, you'll have a small program that you can post here as a example).

Upvotes: 2

Argalatyr
Argalatyr

Reputation: 4659

The following code works as expected (run the app, click the button 5-10 times to move the mainform to the right, close the app, then run it again and the mainform position is where you left it).

Create a VCL forms application, drop a tbutton on it, size the form so it's just large enough to hold the button, and paste in the following to replace unit1:

unit Unit1;

interface

uses
  Windows, Forms, StdCtrls, Classes, Controls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    procedure InitializeVariables;
    procedure FinalizeVariables;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  registry;

procedure TForm1.Button1Click(Sender: TObject);
begin
  self.Left := self.Left + 10;
end;

procedure TForm1.InitializeVariables;
var
  TheReg : tregistry;
begin
  TheReg := tregistry.Create;
  try
    TheReg.RootKey := HKEY_CURRENT_USER;
    if TheReg.OpenKey('\Software\killme', false) then
    begin
      if TheReg.ValueExists('MainLeft') then
        self.Left := TheReg.ReadInteger('MainLeft');
    end;
  finally
    TheReg.Free;
  end;
end;

procedure TForm1.FinalizeVariables;
var
  TheReg : tregistry;
begin
  TheReg := tregistry.Create;
  try
    TheReg.RootKey := HKEY_CURRENT_USER;
    if TheReg.OpenKey('\Software\killme', true) then
      TheReg.WriteInteger('MainLeft', self.Left);
  finally
    TheReg.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  InitializeVariables;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FinalizeVariables;
end;

end.

Upvotes: 2

Nick Hodges
Nick Hodges

Reputation: 17138

Are you actually ever destroying the form?

By default, forms are auto-created, and "closing" them doesn't destroy them, it just hides them.

If you aren't actually calling "MyForm.Free" or setting Action to caFree in the OnClose event, the form is never getting destroyed, and hence the OnDestroy event is never getting fired, and your code is never getting called.

Upvotes: 4

Argalatyr
Argalatyr

Reputation: 4659

OnDestroy is fine for writing to the registry. Something else is going on. What does '...' represent in your code?

Because what you describe sounds like there's a bug somewhere, can you reproduce the problem in a test application?

Upvotes: 2

Bob S
Bob S

Reputation: 423

Try TMainForm.OnCloseQuery instead:

http://delphi.about.com/od/formsdialogs/a/delphiformlife.htm

Upvotes: 1

Related Questions