---- 我们平时用的很多软件都具有一些记忆功能,如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一览无佘的看到,所以千万不能将一些重要的信息(如密码)不经加密而直接写入注册表,这样做是非常危险的!!