專業軟體通常能記住上次關閉時的窗口位置、大小、最大化狀態,下次啟動自動恢復。本文演示如何在 Delphi 中使用註冊表(TRegistry)持久化窗口狀態,涵蓋首次運行默認值、最大化狀態處理、資源管理等完整邏輯。
| 方案 | 優點 | 缺點 |
|---|---|---|
| INI 文件 | 簡單、可攜帶 | 無安全性、Win95+ 不推薦、易被用戶誤刪 |
| 自定義二進制文件 | 結構靈活 | 需自行解析、維護成本高 |
| 資料庫 | 查詢強大 | 過重、需驅動、部署複雜 |
| 註冊表 | 系統原生、API 簡單、用戶難發現修改、性能好 | 需管理權限寫 HKLM(但 HKCU 無需)、結構固定 |
推薦:使用 HKEY_CURRENT_USER\Software\廠商名\應用名\ 路徑,無需管理員權限,用戶隔離,安全可靠。
procedure TForm1.FormCreate(Sender: TObject);
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('Software', False);
Reg.CreateKey('王偉'); {廠商名}
Reg.OpenKey('王偉', False);
Reg.CreateKey('XX單位XX管理系統'); {應用名}
Reg.OpenKey('XX單位XX管理系統', True);
Reg.CreateKey('位置'); {配置項}
Reg.OpenKey('位置', True);
if Reg.ReadString('first') <> '1' then begin {首次運行}
Reg.WriteString('first', '1');
WindowState := wsNormal;
Top := 10; Left := 10; Height := 100; Width := 100; {默認值}
end else begin
if Reg.ReadString('max') = 'y' then
WindowState := wsMaximized
else begin
WindowState := wsNormal;
Top := StrToInt(Reg.ReadString('top'));
Left := StrToInt(Reg.ReadString('left'));
Height := StrToInt(Reg.ReadString('height'));
Width := StrToInt(Reg.ReadString('width'));
end;
end;
finally
Reg.Free;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('Software\王偉\XX單位XX管理系統\位置', False);
if WindowState = wsMaximized then
Reg.WriteString('max', 'y')
else begin
Reg.WriteString('max', 'n');
Reg.WriteString('top', IntToStr(Top));
Reg.WriteString('left', IntToStr(Left));
Reg.WriteString('height', IntToStr(Height));
Reg.WriteString('width', IntToStr(Width));
end;
finally
Reg.Free;
end;
end;
WriteInteger 讀回需轉換;統一用 WriteString/ReadString + IntToStr/StrToInt 更直觀、跨版本兼容。first='1' 判斷是否為首次,避免讀取不存在的鍵值導致異常或錯誤默認值。Top/Left/Width/Height 不具備參考意義,單獨存 max='y',恢復時直接設置 wsMaximized。TRegistry 必須成對 Create/Free,建議用 try..finally 確保釋放。type
TWindowStatePersist = class
private
FReg: TRegistry;
FAppPath: string;
public
constructor Create(const Vendor, AppName: string);
destructor Destroy; override;
procedure LoadWindow(Form: TForm);
procedure SaveWindow(Form: TForm);
end;
{實現略: 封裝上述邏輯, 支援多窗口、多顯示器邊界檢查、DPI 感知調整}
切勿將密碼、Token、加密鑰等敏感信息明文寫入註冊表! 任何用戶均可通過 regedit 查看。敏感數據必須加密(如 DPAPI CryptProtectData)後再存儲。
使用 TRegistry 操作 HKEY_CURRENT_USER 實現窗口狀態記憶,代碼簡潔、無需外部文件、用戶感知度低,是 Delphi 桌面應用提升專業度的「小功能、大細節」典範。