Delphi:写入注册表不能在FormDestroy上工作

时间:2009-07-09 02:04:37

标签: delphi forms registry

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;

类似的代码适用于 FormCreate ,但不适用于应用程序关闭时(即没有任何内容保存到注册表中)。我错过了什么?

'...'代表注册表项名称。由于它适用于FormCreate,我认为这不是问题。

如果我将 MainForm.Destroy 添加到程序代码中:

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
  MainForm.Destroy;
end.
没有什么变化。如果我还将FormDestroy设置为MainForm的OnDestroy事件,则在关闭应用程序时会出现“访问冲突”错误。

6 个答案:

答案 0 :(得分:4)

你真的在破坏表格吗?

默认情况下,表单是自动创建的,“关闭”它们不会破坏它们,它只是隐藏它们。

如果您实际上没有在OnClose事件中调用“MyForm.Free”或将Action设置为caFree,则表单永远不会被破坏,因此OnDestroy事件永远不会被触发,并且您的代码永远不会被调用。

答案 1 :(得分:2)

OnDestroy可以写入注册表。还有其他事情正在发生。 “......”代表什么代码?

因为您所描述的内容听起来像某个地方存在错误,可以在测试应用中重现问题吗?

答案 2 :(得分:2)

以下代码按预期工作(运行应用程序,单击按钮5-10次以将主窗体向右移动,关闭应用程序,然后再次运行它,主窗体位置就在您离开的位置)。

创建一个VCL表单应用程序,在其上放置一个tbutton,调整表单的大小,使其足够大以容纳按钮,并粘贴以下内容以替换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.

答案 3 :(得分:2)

您的FormDestroy是否完全执行?

RE:P.S。和P.P.S。

您的应用中出现了其他问题。写一个小的Delphi程序,它将访问FormDestroy中的注册表,你会发现一切正常(如果没有,你会有一个小程序,你可以在这里发布作为例子)。

答案 4 :(得分:1)

尝试使用TMainForm.OnCloseQuery:

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

答案 5 :(得分:0)

OnCreate和OnDestroy不是加载/保存影响窗口定位的注册表值的好地方。改为覆盖CreateWnd()和DestroyWnd()方法。此外,不是加载/保存单个属性(如Left),而是使用Win32 API SetWindowPlacement()和GetWindowPlacement()函数,这也允许您准确地加载/保存最大化/最小化状态。