Delphi: запись в реестр не работает на FormDestroy - PullRequest
2 голосов
/ 09 июля 2009
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 в качестве события OnDestroy для MainForm, при закрытии приложения я получу ошибку «Нарушение доступа».

Ответы [ 6 ]

4 голосов
/ 09 июля 2009

Вы когда-нибудь разрушали форму?

По умолчанию формы создаются автоматически, и «закрытие» их не уничтожает, а просто скрывает их.

Если вы на самом деле не вызываете «MyForm.Free» или не устанавливаете Action для caFree в событии OnClose, форма никогда не уничтожается, и, следовательно, событие OnDestroy никогда не запускается, и ваш код никогда не вызывается.

2 голосов
/ 09 июля 2009

Ваш FormDestroy выполняется вообще?

RE: P.S. и P.P.S.

Что-то еще идет не так в вашем приложении. Напишите небольшую программу на Delphi, которая будет обращаться к реестру в FormDestroy, и вы увидите, что все работает нормально (если нет, у вас будет небольшая программа, которую вы можете опубликовать здесь в качестве примера).

2 голосов
/ 09 июля 2009

Следующий код работает, как и ожидалось (запустите приложение, нажмите кнопку 5-10 раз, чтобы переместить основную форму вправо, закройте приложение, затем снова запустите его, и позиция основной формы будет там, где вы ее оставили).

Создайте приложение форм VCL, поместите на него кнопку tb, измените размер формы, чтобы она была достаточно большой, чтобы удерживать кнопку, и вставьте следующее, чтобы заменить 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.
2 голосов
/ 09 июля 2009

OnDestroy отлично подходит для записи в реестр. Что-то еще происходит. Что означает «...» в вашем коде?

Поскольку то, что вы описываете, звучит так, будто где-то есть ошибка, Можете ли вы воспроизвести проблему в тестовом приложении?

1 голос
/ 09 июля 2009

Попробуйте вместо этого TMainForm.OnCloseQuery:

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

0 голосов
/ 10 июля 2009

OnCreate и OnDestroy не являются хорошими местами для загрузки / сохранения значений реестра, которые влияют на расположение окна. Вместо этого переопределите методы CreateWnd () и DestroyWnd (). Кроме того, вместо загрузки / сохранения отдельных свойств, таких как Left, используйте вместо этого функции WinW API API SetWindowPlacement () и GetWindowPlacement (), что также позволяет вам точно также загружать / сохранять максимизированные / минимизированные состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...