零代码保存窗口运行状态
一些比较专业的软件都有自动保存窗口运行状态的功能,具体的方法都是在窗口关闭前将其状态保存到注册表中或ini文件中,而这些代码一般都是相同的,所以可以将其集中在一起,重复使用。本文将相应的代码用一个控件TPosition来实现,使用时只要将此控件放到相应的Form上即可,不需要增加任何代码,从而实现了“零”代码保存窗口运行状态。 下面是这个控件的主要实现文件Position.pas的内容,包括相应的注释。为了保持注册表的整洁,这里把信息保存到ini文件中。 unit Position; interface uses Forms, Classes, SysUtils, Windows, IniFiles; type //TPosition是不可视控件,由TComponent继承 TPosition = class(TComponent) private //用此变量保存父窗口的OnDestroy事件 FOnDestroy: TNotifyEvent; //用此函数替换父窗口的OnDestroy事件 procedure FormDestroy(Sender: TObject); protected //在控件加载时恢复父窗口状态 procedure Loaded; override; end; //恢复窗口位置函数 procedure ReadFormPos(Form:TForm); //保存窗口位置函数 procedure SaveFormPos(Form:TForm); //控件注册函数 procedure Register; implementation //连接此控件的图标 {$R Position.Dcr} //恢复窗口位置函数,窗口状态存放在ini文件中。 procedure ReadFormPos(Form : TForm); var RegFile : TIniFile; SectName : string; begin //ini文件中存放Form信息的节名称 SectName := Form.Name + ' Position'; //打开与可执行文件名相同的ini文件 RegFile := TIniFile.Create( ChangeFileExt(Application.ExeName,'.ini')); //恢复窗口状态 with Form do begin Left := RegFile.ReadInteger(SectName,'Left',Left); Top := RegFile.ReadInteger(SectName,'Top',Top); Width := RegFile.ReadInteger(SectName,'Width',Width); Height := RegFile.ReadInteger(SectName,'Height',Height); WindowState := TWindowState( RegFile.ReadInteger(SectName,'WindowState',0)); end; //关闭ini文件 RegFile.Free; end; //保存窗口位置函数 procedure SaveFormPos(Form:TForm); var RegFile : TIniFile; SectName : string; begin SectName := Form.Name + ' Position'; RegFile := TIniFile.Create( ChangeFileExt(Application.ExeName,'.ini')); with Form do begin RegFile.WriteInteger(SectName,'WindowState', integer(WindowState)); //最大化时,不保存窗口位置 if WindowState <> wsMaximized then begin RegFile.WriteInteger(SectName,'Left',Left); RegFile.WriteInteger(SectName,'Top',Top); RegFile.WriteInteger(SectName,'Width',Width); RegFile.WriteInteger(SectName,'Height',Height); end; //当要保存状态的窗口是程序主窗口时,要特殊处理。因为主窗口收到最小化消息时,只是把此消息转至Application处理,本身并不最小化。所以我们要判断Application的状态。 if Form = Application.MainForm then begin if IsIconic(Application.Handle) then begin Reg File.Write Integer(Sect Name,'WindowState', Integer(wsMinimized)); end; end; end; RegFile.Free; end; //注册控件 procedure Register; begin RegisterComponents('XDCtls', [TPosition]); end; //TPositon类的实现 //当主窗口Destroy时,调用此函数,此函数又调用保存的OnDestoy事件处理函数 procedure TPosition.FormDestroy(Sender: TObject); begin SaveFormPos(Owner as TForm); if Assigned(FOnDestroy) then FOnDestroy(Sender); end; //控件加载时,恢复父窗口位置,并对父窗口的OnDestroy事件进行替换 procedure TPosition.Loaded; begin inherited Loaded; //非设计状态才进行处理 if not (csDesigning in Componentstate) then begin ReadFormPos(Owner as TForm); FOnDestroy := (Owner as TForm).OnDestroy; (Owner as TForm).OnDestroy := FormDestroy; end; end; end. 完成此单元后,新建一个Package,将此单元包含在其中,编译、安装即可。资源文件Position.dcr,可自行创建合适的图标。使用时,只要将这个控件放到相应的Form即可。下面是我测试时的窗体代码,不用加任何语句就可以自动保存窗体状态。 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Position; type TForm1 = class(TForm) Position1: TPosition; private public end; var Form1: TForm1; implementation {$R *.DFM} end. 此程序在PWIN97+Delphi5.0下通过