Reputation: 1356
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
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
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
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
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
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
Reputation: 423
Try TMainForm.OnCloseQuery instead:
http://delphi.about.com/od/formsdialogs/a/delphiformlife.htm
Upvotes: 1