我們平時用的很多軟件都具有一些記憶功能,如foxmail和TheBat等等。
這些軟件能在啟動時自動的保持上一次關閉軟件時的一些狀態,如窗口的初始位置,用戶在軟件中設置的一些特性(如窗口風格,橫相排列還是豎相排列等等),如果能讓我們的程序也具有這樣的一些功能可以使我們程序看起來更專業性一些:) 這裡我就來講一下怎樣使應用程序能記住上一次關閉時的窗口位置,並在下一次啟動時和上一次的位置一樣。
既然要保留信息,就一定要涉及到存貯的問題。數據的存貯有好幾種辦法,可以寫.ini或.inf文件,還可以用Delphi提供的文件類來自定義一個文件,還可以用數據庫接口(如ODBC)引入一種數據庫文件,foxpro 的.dbf和Access的.mdb比較常用,還可以直接往Windows的注冊表裡寫。寫.ini和.inf文件沒有任何的安全性,且不適合win95,還記得在94,95年時用中文的Windows3.2中大量的用到了.ini文件,但Windows95出現後,微軟建議盡可能的把信息寫到注冊表中。用ODBC的話會給程序帶來很多不必要的麻煩,如會使程序更加復雜,需要相應的DBMS的驅動程序的支持,如果沒有相應數據源的驅動程序,則該數據源就不能使用,還有安全性問題也不能很好的解決。
在這裡推薦使用寫注冊表的方法。因為這種方法很方便,不需太多額外的開銷,程序比較簡單,對一般的用戶來說在注冊表裡找到有用的信息比打開.ini文件要麻煩的多。所以注冊表的安全性比.ini文件要略強一些。
使應用程序能記住上一次關閉時的窗口位置,並在這一次啟動時和上一次的位置一樣。總體思路是這樣的:在關閉程序時要記錄下本次程序結束時的信息,寫入注冊表中,在下次程序啟動時讀注冊表中相應信息,並賦給程序。
對於我們這個程序來說主要需要記錄的信息是窗口關閉時的Top,Left,Height,Width。
注意:要想使Delphi可以操作注冊表,必須包括registry單元。
以下是源程序和相關注釋:
unit Unit1;
interface
uses
Windows, Messages,. . . . . . . ,registry;
//包括registry單元
type
TForm1 = class(Tform)
.
.
.
public
ww:Tregistry;
//聲明一個Tregistry對象,我們就通過ww來
實現對注冊表的操作
//啟動窗口時要做的一些工作
procedure TForm1.FormCreate(Sender: Tobject);
begin
ww:=Tregistry.Create;
//創建ww對象
ww.RootKey :=HKEY_CURRENT_USER;
//注意:通過修改RootKey可以把信息寫到注冊表的每一個角落
ww.OpenKey('software',FALSE);
//打開鍵software,可以看到Borland,Netscape
還有Microsoft也在這個software鍵中
ww.CreateKey( '王偉');
//在software鍵中創建一個名為“王偉“的鍵值,
使自己的名字和Borland,Netscape,
//Microsoft並排在一起,是不是很Cool啊:)
ww.OpenKey( '王偉',FALSE);
//打開鍵"王偉"
ww.CreateKey('XX單位XX管理系統');
//創建應用程序的名稱
ww.OpenKey('XX單位XX管理系統',TRUE);
ww.CreateKey('位置');
//創建應用程序中某一個要存貯的項目的名稱,便於管理
ww.OpenKey('位置',TRUE);
if (ww.ReadString('first')<>'1')then
//這是值得注意的一個地方,通過“first“來判斷程序是否
begin
//是第一次寫注冊表,如果是第一次寫則用程序給的默認值來
ww.WriteString('first','1');
//設置窗口的位置和大小。如果不是第一次啟動應用程序則說明
Form1.WindowState:=(wsNormal);
//注冊表中已經寫了位置信息,就讀這些信息並賦給Form。
Form1.Top:=10;
form1.Left:=10;
form1.Height:=100;
form1.Width:=100;
end
else
begin
if(ww.ReadString('max')='y') then
//判斷上次關閉程序時,窗口是否是最大化的。如果是的話,則
Form1.WindowState:=(wsMaximized)
//繼續使窗口擁有這一特征。
else
begin
Form1.top:=StrToInt(ww.ReadString('top'));
//如果不是最大化,則取位置和大小數據賦給From
Form1.left:=StrToInt(ww.ReadString('left'));
Form1.height:=StrToInt(ww.ReadString('height'));
Form1.width:=StrToInt(ww.ReadString('width'));
end;
end;
end;
//關閉窗口時要做的一些工作
procedure TForm1.FormDestroy(Sender: Tobject);
begin
ww.OpenKey('位置',FALSE);
//打開“位置”鍵
if Form1.WindowState=(wsMaximized) then
//如果當前程序是最大化,則把這一信息寫入注冊表,
ww.WriteString('max','y')
//便於下一次時使用。
else
begin
ww.WriteString('max','n');
//如果不是最大化,則把窗口的位置和大小數據寫入注冊表中。
ww.WriteString('top',IntToStr(Form1.top));
ww.WriteString('left',IntToStr(Form1.left));
ww.WriteString('height',IntToStr(Form1.Height));
ww.writeString('width',IntToStr(Form1.Width));
end;
end;
需要注意的幾點:
1:因為程序不可能在第一次使用時,就從注冊表裡讀數據,所以第一次必須由程序賦一個初值。然後做上標記,表示已經有過第一次了,以後只要判斷出不是第一次了,就可以讀數據了。(這點最重要,由這一點還可以引出一個話題,那就是可以做一個Demo版的軟件,每次啟動時往注冊表裡加個1,當>10時,就不許用該軟件了,cool吧)
2:往注冊表裡可以寫string型數據,也可以寫Integer型數據,但在注冊表中的Integer型數據是以16進制形式存在的,而我們在程序中用的都是10進制數,所以干脆寫string型,然後用StrToInt或IntToStr轉換
3:寫注冊表並不是很安全的,它的內容可以用RegEdit一覽無佘的看到,所以千萬不能將一些重要的信息(如密碼)不經加密而直接寫入注冊表,這樣做是非常危險的!!