2009-07-09 22 views
2
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,但不是當應用程序被關閉(即沒有被保存到註冊表)。我錯過了什麼?德爾福:寫入註冊表FormDestroy不工作

'...'代表註冊表項名稱。既然它適用於FormCreate,我不認爲這是一個問題。

如果我添加MainForm.Destroy的程序代碼:

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

沒有什麼變化。如果我還將FormDestroy設置爲MainForm的OnDestroy事件,則在關閉應用程序時會出現「訪問衝突」錯誤。

+0

通常調用_free_而不是_destroy_更安全,因爲free會在調用destroy之前檢查nil指針。無論如何,你不需要釋放mainform,因爲它會爲你解放。 – Argalatyr 2009-07-11 21:34:36

回答

2

的OnDestroy是罰款寫入註冊表。其他事情正在發生。代碼中代表'...'代表什麼?

因爲您所描述的聲音聽起來像是某個地方存在bug,是否可以在測試應用程序中重現該問題?

+0

其他一切正常。包括FormCreate基本相同的過程。這只是代碼似乎無法在FormDestroy上運行。 – Mikhail 2009-07-09 04:57:01

2

以下代碼按預期工作(運行應用程序,單擊按鈕5-10次將主窗體移動到右側,關閉應用程序,然後再次運行並且mainform位置是您離開它的位置)。

創建VCL窗體應用程序,將其扔一個TButton,大小形式所以它只是大到足以容納按鈕,在下面的更換1單元貼:

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. 
+0

我不知道什麼是錯的,但是你的代碼也不起作用。無論如何,使用FormClose會做。謝謝。 – Mikhail 2009-07-09 05:43:02

+0

我在WinXP下使用D2006。也許你正在使用Vista?報告問題時總是最好描述你的設置! – Argalatyr 2009-07-09 05:45:46

+0

我想如果FormClose不止一次觸發,多次寫入註冊表都不會造成任何傷害。無論如何,我希望所有這些都能爲你解決。 – Argalatyr 2009-07-09 05:50:55

4

你居然曾經摧毀表格?

默認情況下,窗體是自動創建的,「關閉」它們並不會銷燬它們,它只是隱藏它們。

如果您實際上沒有在OnClose事件中調用「MyForm.Free」或將Action設置爲caFree,則表單永遠不會被銷燬,因此OnDestroy事件永遠不會被觸發,並且您的代碼永遠不會被調用。

2

您的FormDestroy是否可以執行?

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

在您的應用中出現其他問題。編寫一個小型的Delphi程序,可以訪問FormDestroy中的註冊表,你會發現一切正常(如果沒有,你會有一個小程序,你可以在這裏作爲例子)。

+0

我已經給了他一個適用於我的小應用程序,他評論說它不適合他。 – Argalatyr 2009-07-09 15:41:05

+0

因爲他不知道如何調試應用程序將保持這種狀態,我相信:( – gabr 2009-07-09 16:03:06

0

OnCreate和OnDestroy不是加載/保存影響窗口定位的註冊表值的好地方。改爲改寫CreateWnd()和DestroyWnd()方法。此外,而不是加載/保存個別屬性,如左,使用Win32 API SetWindowPlacement()和GetWindowPlacement()函數,而這也允許您加載/保存最大化/最小化狀態準確。