Delphi的注册表操做

转帖:Delphi的注册表操做 2009-12-21 11:12:52

分类:html

Delphi的注册表操做
 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息。
 
   1、建立和释放TRegistry对象
  1.建立TRegistry对象。为了操做注册表,要建立一个TRegistry对象:
      ARegistry := TRegistry.Create;
  2.释放TRegistry对象。对注册表操做结束后,应释放TRegistry对象所占内存:
      ARegistry.Destroy;
  2、指定要操做的键
  操做注册表时,首先应指定操做的主键:先给属性RootKey赋值以指定根键,而后用方法OpenKey来指定要操做的主键名。
 
  1.指定根键(RootKey)。举例:
    ARegistry.RootKey:=HKEY_LOCAL_MACHINE;
  根键是注册表的入口,也注册表信息的分类,其值可为:
  HKEY_CLASSES_ROOT:存储整个系统对象类信息,如ActiveX对象注册、文件关联等信息。
  HKEY_CURRENT_USER:存储当前用户的配置信息。为属性RootKey的默认值。
  HKEY_LOCAL_MACHINE:存储当前系统的软硬件配置信息。应用程序本身的信息能够存储在该根键下。
   HKEY_USERS:存储全部用户通用的配置信息。
  还能够是HKEY_CURRENT_CONFIG、HKEY_DYN_DATA。
 
  2.指定要操做的主键。
  Function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    Key:主键名,是键名全名中除去根键的部分,如Software\Borland\Delphi。
    CanCreate:在指定的主键名不存在时,是否容许建立该主键,True表示容许。
    返回值True表示操做成功。
 
  3.关闭当前主键。
  在读取或存储信息以后,应及时将关闭当前主键:
    procedure CloseKey;
  3、从注册表中读取信息
  Read系列方法从注册表读取指定的信息(字符串、二进制和十六进制),并转换为指定的类型。
 
  1.Read系列方法。
  function ReadString(const Name: string): string;
     读取一个字符串值,Name为字符串名称。
  function ReadInteger(const Name: string): Integer;
    读取一个整数值,Name为整数名称。
  function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer):Integer;
    读取二进制值,Name为二进制值名称,Buffer为接收缓冲区,BufSize为缓冲区大小,返回为实际读取的字节数。
  其它方法还有:ReadBool、ReadCurrency、ReadDate、ReadDateTime、ReadFloat、ReadTime。
   founction ReadFloat(const Name : string) : Double;
   founction ReadTime(const Name : string) : TdateTime;
   founction ReadBool(const Name) : Boolean;

  2.读取信息一例(显示Windows的版本)。
    在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion下,有三个字符串值 Version、VersionNumber和SubVersionNumber,用于记录当前Windows的版本号。
 
  {请在Uses中包含Registry单元}
  procedure TForm1.Button1Click(Sender:TObject);
  var
    ARegistry : TRegistry;
  begin
    ARegistry := TRegistry.Create;  //创建一个TRegistry实例
    with ARegistry do
    begin
      RootKey := HKEY_LOCAL_MACHINE;  //指定根键为HKEY_LOCAL_MACHINE
      //打开主键Software\Microsoft\Windows\CurrentVersion
      if OpenKey('Software\Microsoft\Windows\CurrentVersion',false) then
      begin
        memo1.lines.add('Windows版本:'    + ReadString('Version'));
        memo1.lines.add('Windows版本号:'  + ReadString('VersionNumber'));
        memo1.lines.add('Windows子版本号:'+ ReadString('SubVersionNumber'));
      end;
      CloseKey;//关闭主键
      Destroy;//释放内存
    end;
  end;
 
  4、向注册表中写入信息
  Write系列方法将信息转化为指定的类型,并写入注册表。
 
  1.Write系列方法。
  procedure WriteString(const Name, Value: string);
    写入一个字符串值,Name为字符串的名称,Value为字符串值。
  procedure WriteInteger(const Name: string; Value: Integer);
    写入一个整数值。
  procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    写入二进制值,Name为二进制值的名称,Buffer为包含二进制值的缓冲区,BufSize为缓冲区大小。
  其它方法还有:WriteBool、WriteCurrency、WriteDate、WriteDateTime、WriteFloat、WriteTime。
 
   procedure WriteFloat(const Name : string ; Value : Double);
   procedure WriteTime(const Name : string ; Value : TDateTime);
   procedure WriteBool(const Name : string ; Value : Boolean);

  2.写入信息一例。
  下面程序使Delphi随Windows启动而自动运行。
 
  var
    ARegistry : TRegistry;
  begin
    ARegistry := TRegistry.Create;  //创建一个TRegistry实例
    with ARegistry do
    begin
      RootKey:=HKEY_LOCAL_MACHINE;
      if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',True) then
        WriteString('delphi','C:\Program Files\borland\delphi3\bin\delphi32.exe');
      CloseKey;
      Destroy;
    end;
  end;
 
  5、键值维护
  除了在注册表中读取、存储外,程序可能还须要增长主键、删除主键、主键更名、数据值更名等。
 
  1.建立新主键:function CreateKey(const Key: string): Boolean。
    Key即为主键名,返回值True表示操做成功。
 
  2.删除主键:function DeleteKey(const Key: string): Boolean。
    Key即为主键名,返回值True表示操做成功。
     删除键值:function DeleteValue(const Key : string) : Boolean;
    使用DeleteKey方法删除指定的关键字时,若是被删除的关键字在任何层次有子关键字,它们将同时被删除。上面两个方法在执行时,若是删除成功,则返回True;不然返回False。

  3.复制或移动主键:procedure MoveKey(const OldName, NewName: string; Delete: Boolean)。
    OldName、NewName分别表示源主键名和目标主键名;Delete表示是否删除源主键,True表示删除,False表示保留。
    复制或移动一个主键将复制或移动该子键下的全部数据值和子键内容。
 
  4.判断指定主键是否存在,其下是否有主键,并获取主键名称。
  
    KeyExists用于判断指定主键是否存在:
  function KeyExists(const Key: string): Boolean;//返回值为True表示主键存在。
    HasSubKeys用于判断指定主键下是否有子键:function HasSubKeys: Boolean;
    返回值为True表示主键下有子键。
   
    GetKeyNames用于获取子键名称:
    procedure GetKeyNames(Strings: TStrings);
     Strings用于返回当前主键下各子键的名称。
 
  5.获取主键下的数据值名称:
    procedure GetValueNames(Strings: TStrings)。
    Strings用于返回当前主键下各数值名称。
    如要获取当前系统中的拨号链接名称,可利用获取主键HKEY_USERS\.DEFAULT\RemoteAccess\Addresses下的数值名称的方法来进行。
 
  6.判断数值名称存在、数值名称更名。
  ValueExists用于判断数值名称是否存在:
  function ValueExists(const Name: string): Boolean;
    返回值为True表示数值名称存在。
 
   RenameValue用于数值名称更名:
  procedure RenameValue(const OldName, NewName: string);
 
   以上是注册表经常使用操做所对应的TRegistry的方法和属性,其它方法和属性请参见Delphi联机帮助文件。
    以上程序在PWIN 98+Delphi 3.0下调试经过。
 
    6、注册表中对编程经常使用的几项(ODBC/BDE/Internet/Windows)  
  
    一、关于 ODBC 和 DBE:
    HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\ODBC File DSN
      有你的 COMPUTER 上 ODBC 的 FILE DSN 的存放的缺省路径,若是你创建 FILE DSN 的时候选择了本身的路径,那你就得当心了,系统不会为你保存该路径,你的本身记住它,:-(;
   
    HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers
      列出了你的全部 ODBC DRIVER,关于 ODBC DRIVER 的名称,有一个比较有趣的地方:不知你们又没有用TSession.GetDriverNames 取过系统 ODBC DRIVER 名,我用的时候 DRIVER 名最长只能取
到 31 个字符,剩下的就被截掉了,不知是我编程有问题仍是 DELPHI 的 BUG;
    HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI
      列出了你的全部 ODBC DRIVER 的详细配置;
    HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI
      列出了你的全部 SYSTEM DSN 以及它们的配置状况;
    HKEY_CURRENT_USER\Software\ODBC\ODBC.INI
      列出了你的全部 USER DSN 以及它们的配置状况;
    知道了以上的几个主键后,你就能够在程序中实现 %SystemRoot%\system32\odbcad32.exe 的大部分功能了。
    HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine
      下面是你的 DBE 的配置,我就很少说了,你们拿它和 BDE 用户界面一比较就明白了。
 
    二、关于 INTERNET 编程:
    HKEY_CLASSES_ROOT\htmlfile
      系统对 HTMLFILE 的处理定义;
    HKEY_LOCAL_MACHINE\SOFTWARE\Clients
      INTERNET Option 中 INTERNET PROGRAM 的设定,尤为重要的是其中的
    HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail。
    三、关于 WINDOWS 编程
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
      每次该用户启动 WINDOWS 一定执行下面的命令(若是有,固然通常都有),
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runonce
      该用户启动 WINDOWS 一定执行下面的命令(若是有),执行完后由 WINDOWS 把命令删掉,安装软件的时候特别有用,
    以上两处是针对特定用户的,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion 下还有相似的地方,是针对全部用户的,我就不罗嗦了。

    7、Delphi 中注册表构件TRegistry 的应用  
    在Delphi3.0 及以上版本中,提供了一个构件TRegistry。在程序中能够利用它来实现对WIN95/98/NT 注册表的操做,能够很方便地在注册表中增长、修改和删除键值。这样能够在程序中完成一些特
殊的功能。
    一、TRegistry 经常使用的属性和方法有(具体做用和用法请参考Delphi 帮助):
 
    RootKey、CreateKey、OpenKey、CloseKey、DeleteKey、ReadXXXX、WriteXXXX(XXXX表示数据类型如String、Integer等)
      咱们用到的属性和方法有:
    RootKey:注册表的根键名( 如HKEY_LOCAL_MACHINE等)
 
    OpenKey( KeyName:string; CanCreate:boolean ):
      使当前键为KeyName,CanCreate 表示当指定的键不存在时是否建立,True 表示建立
    SetKey( KeyName,KeyValue : string ):使键KeyName的值为KeyValue
     二、几种应用:
应用之一:让本身的程序随WIN95/98/NT 的启动而运行
    固然,你能够在"启动"程序组中加入程序的快捷方式,但这样作好象不大明智,由于大多数程序在安装时不会这样作,而是在经过在注册表增长键值,让WIN95/98/NT 在启动时运行本身的程序。
若是打开注册表,找到HKEY_LOCAL_MACHINE \Software \Microsoft\Windows \CurrentVersion \Run,就会发现这个秘密了,原来许多自动运行的程序都在这里。你也能够在这里增长一个键,让你的程
序也随着 WIN95/98/NT 的启动而本身运行,成为WINDOWS 下的TSR 程序。实现方法以下:
    首先,在Uses 中加上Registry 单元;而后,写下面代码。
    {将程序strExeFileName置为自动启动 }
    function StartUpMyProgram ( strPrompt,strExeFileName : string ) : boolean;
    var
      registerTemp : TRegistry;
    begin
      registerTemp := TRegistry.Create;  //创建一个Registry实例
      with registerTemp do
      begin
        RootKey:=HKEY_LOCAL_MACHINE;    //设置根键值为HKEY_LOCAL_MACHINE
        //找到Software\Microsoft\Windows\CurrentVersion\Run
        if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',True) then
        //写入本身程序的快捷方式信息
        begin
          WriteString( strPrompt, strExeFileName );
          result := true;
        end
        else
          result := false;
        //善后处理
        CloseKey;
        Free;
      end;
    end;
 
{调用StartUpMyProgram,使Delphi随WINDOWS启动而自动运行 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.lines.add('开始');
  if StartUpMyProgram('delphi','C:\Program Files\borland\delphi3\bin\delphi32.exe') then
     memo1.lines.add('成功')
  else
     memo1.lines.add('失败');
end;
应用之二:实现文件关联
    当MS WORD 安装在你的系统中时,它会把.DOC 文件与本身关联,当你双击一个DOC 文件,就会启动MS WORD,打开你指定的DOC文件。你也能够把一个文件类型与一个程序关联起来,其秘密仍是在注册表中。若是打开注册表,找到 HKEY_CLASSES_ROOT,就会发现这里已经有不少文件类型。
    你也能够在这里增长一个键,创建本身的文件关联。
    创建文件关联,通常应有两个步骤:
    (1)根据文件类型的扩展名,指定对应的键名(如doc 文件对应的键为doc_auto_file)
    该键及其子键的值,将定义该类型的文件的类型说明和操做(如打开、编辑)说明
    (2)在指定的键名下,创建子键,指明文件类型说明和操做对应的程序信息
    例如,咱们能够为.DBF 文件创建文件关联,其文件类型说明为"xBase 数据表",使其打开(Open)文件的操做对应程序C:\ProgramFiles\Borland\DBD\DBD32.EXE。首先,应在注册表的根 键HKEY_CLASSES_ROOT 下创建一个键,键名为.DBF,默认值为DBF_Auto_File,表示DBF 类型文件的关联操做信息记录在键HKEY_CLASSES_ROOT\DBF_Auto_File 下;而后,创建键
HKEY_CLASSES_ROOT\DBF_Auto_File, 并设其默认值为"xBase 数据表",表示文件类型说明;再创建键HKEY_CLASSES_ROOT\DBF_Auto_File\Shell\open\command,设置其 默认值为C:\Program Files\Borland\DBD\DBD32.EXE  %1(其中"%1 "为命令行参数),表示打开操做对应的程序信息。
具体实现以下:一样,在Uses 中加上Registry 单元,  而后,写下面代码。
{将文件类型strFileExtension与程序
strExeFileName相关联,strDiscription为文件类型说明 }
function AssignToProgram(strFileExtension,strDiscription,strExeFileName : string ) : boolean;
var
  registerTemp : TRegistry;
begin
  registerTemp := TRegistry.Create;
  //创建一个Registry实例
  with registerTemp do
    begin
      RootKey:=HKEY_CLASSES_ROOT;
      //设置根键值为HKEY_CLASSES_ROOT
      //根据文件类型的扩展名,建立或打开对应的键名.FileExt,如DBF对应'.DBF'
      if OpenKey( '.' + strFileExtension, true ) then
        begin
          result := false;
          exit;
        end;
      //设置键.FileExt默认值为FileExt_Auto_File,如'.DBF'对应'DBF_Auto_File'
      WriteString('',strFileExtension + '_Auto_File');
      CloseKey;
      //写入本身程序的信息
      //根据文件类型的扩展名,建立或打开对应的键名
      FileExt_Auto_File
      //'.DBF'对应'DBF_Auto_File'
      if OpenKey(strFileExtension + '_Auto_File', true ) then
        begin
          result := false;
          exit;
        end;
      //设置默认值文件类型说明,如DBF可对应'xBase数据表'
      WriteString('',strDiscription);
      CloseKey;
      //建立或打开键名FileExt_Auto_File\Shell\open\command,该键为表示操做为'打开'
      //'.DBF'对应'DBF_Auto_File\shell\open\command'
      if OpenKey(strFileExtension + '_Auto_File\shell\open\command', true ) then
        begin
          result := false;
          exit;
        end;
      //设置该键的默认值为打开操做对应的程序信息
      //如DBF可对应'C:\Program Files\Borland\DBD\DBD32.EXE'
      WriteString('',strExeFileName + ' %1');
      CloseKey;
      Free;
  end;
end;
{调用AssignToProgram,使DBF文件与DBD32.EXE关联 }
procedure TForm1.Button3Click(Sender: TObject);
begin
   memo1.lines.add('开始');
   if AssignToProgram('DBF','xBase数据表','C:\Program Files\borland\dbd\dbd32.exe') then
     memo1.lines.add('成功')
   else
     memo1.lines.add('失败')
end;
 
应用之三:检测Win95/98/NT 系统中是否安装了Borland Database Engine
    当你的应用程序是一个基于BDE 的数据库应用程序时,若是运行在一个没有安装BDE 的Win95/98/NT 中,会出现让用户疑惑不解的错误。你可能须要在程序正常运行以前,检查系统中是否安装了BDE。因为 BDE 安装后会在注册表进行注册,你能够经过查询注册表来肯定系统中是否安装了BDE,而后决定下一步采起什么行动。BDE 在注册表中的位置为:
    HKEY_LOCAL_MACHINE\Software\Borland\Database Engine,该键存在说明 BDE 已经安装。
具体的例子以下。
一样,在Uses 中加上Registry 单元
而后,写下面代码。
{检测系统中是否安装了BDE }
function IsBDEInstalled : boolean;
var
  registerTemp : TRegistry;
begin
  registerTemp := TRegistry.Create;
  //创建一个Registry实例
  with registerTemp do
    begin
      RootKey:=HKEY_LOCAL_MACHINE;
      //设置根键值为HKEY_LOCAL_MACHINE
      //查询Software\Borland\Database Engine
      result := OpenKey('Software\Borland\Database Engine',false);
      //善后处理
      CloseKey;
      Free;
    end;
end;
{调用IsBDEInstalled,检测系统中是否安装了BDE }
procedure TForm1.Button4Click(Sender: TObject);
begin
   memo1.lines.add('开始');
   if IsBDEInstalled then
     memo1.lines.add('已安装了BDE')
   else
     memo1.lines.add('未安装BDE')
end;
 
应用之四:在桌面创建程序的快捷方式
    当你的WIN95/98/NT 桌面上整齐地排列着各类程序的快捷方式时,也许你会体会到快捷方式的方便。你也可将本身设计的程序的快捷方式放在别人的桌面上。
    桌面上的一个快捷方式,对应Windows 目录下Destop 子目录中的一个ShellLink 文件(.LNK),你只要在这个目录下增长一个.LNK 文件就能够了。
    咱们的任务,主要是利用TRegistry 从注册表中获取Desktop 的实际路径,默认为Windows 目录下的Desktop 子目录,如C:\PWIN98\Desktop。在注册表中Desktop 的实际路径对应的键为HKEY_CURRENT_USER \Software\MicroSoft \Windows \CurrentVersion \Explorer \Shell Folders \Desktop。
一样,在Uses 中加上Registry 单元
而后,写下面代码。
{为程序strExeFileName在桌面创建快捷方式,运行参数为strParameters }
function CreateShortcutOnDesktop( strExeFileName, strParameters : string ) : boolean;
var
  registerTemp : TRegistry;
  strDesktopDirectory : widestring;
  shelllinkTemp : IShellLink;
  persistfileTemp : IPersistFile;
begin
  registerTemp := TRegistry.Create;
  //创建一个Registry实例
  with registerTemp do
    begin
      RootKey:=HKEY_CURRENT_USER;
      //设置根键值为HKEY_CURRENT_USER
      //找到Software\MicroSoft\Windows\CurrentVersion\Explorer\Shell Folders
      if not OpenKey('Software\MicroSoft\Windows\CurrentVersion\Explorer\Shell Folders',True) then
      //写入本身程序的信息
        begin
          result := false;
          exit;
        end;
      //读取项目Desktop的值,即Desktop的实际路径
      strDesktopDirectory := ReadString('Desktop');
      //善后处理
      CloseKey;
      Free;
  end;
  //设置快捷方式的参数
  shelllinkTemp := IShellLink( CreateComObject(CLSID_ShellLink));
  with shelllinkTemp do
    begin
      SetPath( PChar( strExeFileName ) );
      //设置程序文件全名
      SetArguments( PChar( strParameters) );
      //设置程序的命令行参数
      //设置程序的工做目录 
      SetWorkingDirectory( Pchar( ExtractFilePath( strExeFileName ) ) );
    end;
 //构造快捷方式的文件名(.LNK)
  strDesktopDirectory := strDesktopDirectory + '\' + ExtractFileName( strExeFileName );
  strDesktopDirectory := copy( strDesktopDirectory, 1, length( strDesktopDirectory ) - length( ExtractFileExt( strExeFileName ) ) ) + '.LNK';
 //保存快捷方式的文件
  persistfileTemp := shelllinkTemp as IPersistFile;
  if S_OK = persistfileTemp.Save( PWChar( strDesktopDirectory ) , false ) then
    result := true //保存成功,返回True
  else result := false;
end;
{调用CreateShortcutOnDesktop,为Delphi在桌面上创建快捷方式 }
procedure TForm1.Button2Click(Sender: TObject);
begin
   memo1.lines.add('开始');
   if CreateShortcutOnDesktop('C:\Program Files\borland\delphi3\bin\delphi32.exe','%1') then
     memo1.lines.add('成功')
   else
     memo1.lines.add('失败')
end;
 
【结语】:上面几个应用只是TRegistry 一些简单的应用,有了这些知识,你就能够根据本身的须要来定制和改善Winodws 系统了。
 
三、备份部分注册表的代码
Procedure ExportRegistryBranch (rootsection : Integer; regroot:String; filename:String);
implementation
Function dblBackSlash(t:string):string;
var k:longint;
begin
  result:=t;                                       {Strings are not allowed to have}
  for k:=length(t) downto 1 do                     {single backslashes}
     if result[k]='\' then insert('\',result,k);
end;
Procedure ExportRegistryBranch (rootsection : Integer; regroot:String; filename:String);
var
  reg:tregistry;
  f:textfile;
  p:PCHAR;
  Procedure ProcessBranch(root:string);         {recursive sub-procedure}
  var
    values,
    keys:tstringlist;
    i,j,k:longint;
    s,t:string;                                 {longstrings are on the heap, not on the stack!}
  begin
    writeln(f);                                 {write blank line}
    case rootsection of
     HKEY_CLASSES_ROOT    : s :=  'HKEY_CLASSES_ROOT';
     HKEY_CURRENT_USER    : s :=  'HKEY_CURRENT_USER';
     HKEY_LOCAL_MACHINE   : s :=  'HKEY_LOCAL_MACHINE';
     HKEY_USERS           : s :=  'HKEY_USERS';
     HKEY_PERFORMANCE_DATA: s :=  'HKEY_PERFORMANCE_DATA';
     HKEY_CURRENT_CONFIG  : s :=  'HKEY_CURRENT_CONFIG';
     HKEY_DYN_DATA        : s :=  'HKEY_DYN_DATA';
    end;
    Writeln(f,'['+s+'\'+root+']');                {write section name in brackets}
    reg.OpenKey(root,false);
    values := tstringlist.create;
    keys:=tstringlist.create;
    reg.getvaluenames (values);                   {get all value names}
    reg.getkeynames   (keys);                     {get all sub-branches}
    for i:=0 to values.count-1 do                 {write all the values first}
    begin
      s := values[i];
      t := s;                                     {s=value name}
      if  s= ''then
        s:='@'                                    {empty means "default value", write as @}
      else
        s:='"' + s + '"';                         {else put in quotes}
      write(f,dblbackslash(s)+ '=' );             {write the name of the key to the file}
      Case reg.Getdatatype(t) of                  {What type of data is it?}
        rdString,
        rdExpandString:                           {String-type}
          Writeln(f,'"' + dblbackslash(reg.readstring(t) + '"'));
        rdInteger:                              {32-bit unsigned long integer}
          Writeln(f,'dword:' + inttohex(reg.readinteger(t),8));
        { write an array of hex bytes if data is "binary." Perform a line feed after approx. 25 numbers so the line length stays within limits }
        rdBinary       :
          begin
            write(f,'hex:');
            j := reg.getdatasize(t);              {determine size}
            getmem(p,j);                          {Allocate memory}
            reg.ReadBinaryData(t,p^,J);           {read in the data, treat as pchar}
            for k:=0 to j-1 do begin
              Write(f,inttohex(byte(p[k]),2));    {Write byte as hex}
              if k<>j-1 then                      {not yet last byte?}
              begin
                write(f,',');                     {then write Comma}
                if (k>0) and ((k mod 25)=0) then  {line too long?}
                  writeln(f,'\');                 {then write Backslash + lf}
              end;                                {if}
            end;                                  {for}
            freemem(p,j);                         {free the memory}
            writeln(f);                           {Linefeed}
          end;
      ELSE
        writeln(f,'""');                          {write an empty string if datatype illegal/unknown}
      end;                                        {case}
    end; {for}
    reg.closekey;
    {value names all done, no longer needed}
    values.free;
    {Now al values are written, we process all subkeys}
    {Perform this process RECURSIVELY...}
    for i := 0 to keys.count -1 do
      ProcessBranch(root+'\'+keys[i]);
    keys.free; {this branch is ready}
  end;
begin
  if regroot[length(regroot)]='\' then          {No trailing backslash}
    setlength(regroot,length(regroot)-1);
  Assignfile(f,filename);                       {create a text file}
  rewrite(f);
  IF ioresult<>0 then
    EXIT;
  Writeln(f,'REGEDIT4');                        {"magic key" for regedit}
  reg:=tregistry.create;
  try
    reg.rootkey:=rootsection;
    ProcessBranch(regroot);                     {Call the function that writes the branch and all subbranches}
  finally
    reg.free;                                   {ready}
    close(f);
  end;
end;
end.
 
四、读写网络上其余计算机注册表的代码
procedure NetReg;
var
  R: TRegistry;
  S: TStringList;
begin
  R:=TRegistry.Create;
  S:=TStringList.Create;
  WriteLn(R.RegistryConnect('\\OtherPC'));
  WriteLn(R.OpenKeyReadOnly('Software'));
  R.GetKeyNames(S);
  WriteLn(S.CommaText);
  S.Free;
  R.Free;
end;
 
五、关于查看注册表的程序
unit regform;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Registry;
type
  TForm1 = class(TForm)
    ListSub: TListBox;
    ListValues: TListBox;
    ComboKey: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    ComboLast: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ListSubClick(Sender: TObject);
    procedure ComboKeyChange(Sender: TObject);
    procedure ComboLastChange(Sender: TObject);
  private
    Reg: TRegistry;
  public
    procedure UpdateAll;
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
  Reg := TRegistry.Create;
  Reg.OpenKey ('\', False);
  UpdateAll;
  // select the current root(选择当前的根目录)
  ComboKey.ItemIndex := 1;
  ComboLast.Items.Add('\'); ///////
  ComboLast.ItemIndex := 0;
end;
//更新
procedure TForm1.UpdateAll;
begin
  Caption := Reg.CurrentPath;
  if Caption = ' then
    Caption := '[Root]';
  if Reg.HasSubKeys then
    Reg.GetKeyNames(ListSub.Items)
  else
    ListSub.Clear;
  Reg.GetValueNames(ListValues.Items);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Reg.CloseKey;
  Reg.Free;
end;
procedure TForm1.ListSubClick(Sender: TObject);
var
  NewKey, Path: string;
  nItem: Integer;
begin
  // get the selection(获取选择项)
  NewKey := ListSub.Items [ListSub.ItemIndex];
  Reg.OpenKey (NewKey, False);
  // save the current path (eventually adding a \)(在不列出于列表时保存路径)
  // only if the it is not already listed
  Path := Reg.CurrentPath;
  if Path < '\' then
    Path := '\' + Path;
  nItem := ComboLast.Items.IndexOf (Path);
  if nItem < 0 then
  begin
    ComboLast.Items.Insert (0, Path);
    ComboLast.ItemIndex := 0;
  end
  else
    ComboLast.ItemIndex := nItem;
  UpdateAll;
end;
procedure TForm1.ComboKeyChange(Sender: TObject);
begin
  case ComboKey.ItemIndex of
    0: Reg.RootKey := HKEY_CLASSES_ROOT;
    1: Reg.RootKey := HKEY_CURRENT_USER;
    2: Reg.RootKey := HKEY_LOCAL_MACHINE;
    3: Reg.RootKey := HKEY_USERS;
    4: Reg.RootKey := HKEY_CURRENT_CONFIG;
    5: Reg.RootKey := HKEY_DYN_DATA;
  end;
  Reg.OpenKey ('\', False);
  UpdateAll;
  ComboLast.Items.Clear;
end;
procedure TForm1.ComboLastChange(Sender: TObject);
begin
  Reg.OpenKey (ComboLast.Text, False);
  UpdateAll;
end;
end.
 
六、得到注册表项下的全部值
Var
    Reg : TRegistry;
    list : TStrings;
    i    : Integer;
Begin
  Reg:=TRegistry.Create;
  Reg.RootKey:='HKEY_LOCAL_MACHINE'; 
  If Reg.OpenKey('\Software\Microsoft\CurrentVersion\Run', false) then
  Begin
    List:=TStringList.Create;
    Reg.GetValueNames(List);
    For i:=0 to list.Count-1 do
      If Reg.ValueExists(List[i]) then
      Begin
        Case Reg.GetDataType(List[i]) of rdInteger: Reg.ReadInteger(List[i]);
        rdBinary: Reg.ReadBinaryData(List[i]);
      else
        Reg.ReadString(List[i]);
      End; 
  End;
End;
 
七、利用Windows API 函数和注册表获取系统信息  
    在开发应用程序时,增长一项显示计算机系统信息的功能,例如已安装的软盘、硬盘、光驱、网络驱动器,硬盘的容量和剩余空间,显示器分辨率、键盘类型、鼠标 的键数,内存大小、CPU 类型,Windows 的版本号、产品标识、注册用户单位名和用户名、当前操做用户名等( 见运行图示),固然还有更多的信息,这样会使你的程序更友好。其实,有不少应用程序就是这样作的。
    经过调用Windows 的API 函数和访问Windows 注册表,能够获取大量的系统信息。Delphi 为绝大多数Windows API 函数提供了调用接口( 可参见DELPHI3\SOURCE\RTL\WIN\windows.pas 文件),并提供了一个功能全面的TRegistry 类,使咱们能够方便的调用Windows API 函数和访问注册表,例如:
    -一、function GetDriveType(lpRootPathName: PChar): UINT; 返回指定驱动器的类型。
    -二、function GetDiskFreeSpace(lpRootPathName: PChar; var lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; 返回指定驱动器的总簇数、剩余簇数及每簇扇区数、每扇区字节数,从而能够计算出总容量和剩
余空间。
    -三、function GetSystemMetrics(SM_CXSCREEN或 SM_CYSCREEN): Integer; 返回显示器分辨率。
    -四、function GetSystemMetrics(SM_CMOUSEBUTTONS): Integer; 返回鼠标的按键数目。
    -五、在windows 注册表的HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion \RegisteredOwner 主键下存放着Windows 安装时输入的用户名, 可用如下语句读取。
myreg:=Tregistry.Create;
//必须在程序单元的uses部分加入Registry
   myreg.RootKey:=HKEY_LOCAL_MACHINE;
   if myreg.openkey('software\microsoft\windows\currentversion',false) then
memo1.lines.add(' 注册用户名:'+myreg.readstring('RegisteredOwner'));
   myreg.closekey;
    以上仅举几例,获取其余一些信息的方法与此相似,详见源程序。
【附】: 源程序清单。
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,Registry;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var  i,x,y:integer;
     ch:char;
     //驱动器字符'A'~'Z'
     buffer:string;
     cpuinfo:TSYSTEMINFO;
     //存放系统信息的记录类型,在Windows.pas中查到详细内容。
     meminfo:TMemoryStatus;
     //存放系统内存信息的记录类型。
     computername,username:pchar;
     //计算机名称、用户名
     spc,bps,nofc,tnoc:longint;
     //用于存放磁盘容量的变量
     myreg:Tregistry;
     //用于访问注册表的TRegistry变量
begin
  memo1.Lines.Clear;
  for ch:='A' to 'Z' do begin
    i:=getdrivetype(pchar(ch+':\'));
    buffer:='  '+ch+': ';
    case i of
      DRIVE_UNKNOWN : buffer:=buffer+'未知类型';
      DRIVE_REMOVABLE: buffer:=buffer+'软盘';
      DRIVE_FIXED : begin
           buffer:=buffer+'硬盘';
           if getdiskfreespace(pchar(ch+':\'),spc,bps,nofc,tnoc) then begin
              buffer:=buffer+'总容量:'+inttostr((spc*bps*tnoc) div (1024*1024))+'MB';
              buffer:=buffer+'剩余:'+inttostr((spc*bps*nofc) div (1024*1024))+'MB';
         end;
       end;
      DRIVE_REMOTE : buffer:=buffer+'网络驱动器';
      DRIVE_CDROM :buffer:=buffer+'CD-ROM驱动器';
      DRIVE_RAMDISK:buffer:=buffer+'RAM虚拟驱动器';
    end;
    if (ch >'D') and (i=1) then break;
    if i< >1 then memo1.Lines.Add(buffer);
  end;
  case getkeyboardtype(0) of  //获取键盘类型
    1: buffer:='  键盘: IBM PC/XT或兼容类型(83键)';
    2: buffer:='  键盘: Olivetti "ICO"(102键)';
    3: buffer:='  键盘: IBM PC/AT(84键)';
    4: buffer:='  键盘: IBM加强型(101或102键)';
    5: buffer:='  键盘: Nokia 1050';
    6: buffer:='  键盘: Nokia 9140';
    7: buffer:='  键盘: Japanese';
  end;
  memo1.lines.add(buffer);
  //获取键盘功能键数目
  memo1.lines.add(' 功能键数目:'+inttostr(getkeyboardtype(2)));
  memo1.Lines.add('显示器分辨率:'+inttostr(getsystemmetrics(SM_CXSCREEN))
   +'x'+inttostr(getsystemmetrics(SM_CYSCREEN)));
  //获取鼠标按键数目
  memo1.Lines.add(' 鼠标:'+inttostr(getsystemmetrics(SM_CMOUSEBUTTONS))+'键');
  globalmemorystatus(meminfo); //获取系统内存数量
  memo1.lines.add('   物理内存:'+inttostr(meminfo.dwTotalPhys div 1024)+' KB');
  i:=getsystemmetrics(SM_CLEANBOOT);
  case i of
    0:buffer:='系统启动模式:正常模式';
    1:buffer:='系统启动模式:保护模式';
    2:buffer:='系统启动模式:网络保护模式';
  end;
  memo1.lines.add(buffer);
  x:=getsystemmetrics(SM_ARRANGE);
  //获取系统最小化窗口的起始位置和排列方式
  y:=x;
  x:=x and 3;
  y:=y and 12;
  case x of
    ARW_BOTTOMLEFT :  buffer:=' 最小化窗口:自左下角';
    ARW_BOTTOMRIGHT : buffer:=' 最小化窗口:自右下角';
    ARW_TOPLEFT :  buffer:=' 最小化窗口:自左上角';
    ARW_TOPRIGHT : buffer:=' 最小化窗口:自右上角';
  end;
  case y of
    ARW_LEFT : buffer:=buffer+'横向排列';
    ARW_UP :   buffer:=buffer+'纵向排列';
    ARW_HIDE : buffer:=buffer+'隐藏';
  end;
  memo1.lines.add(buffer);
  getmem(computername,255);  //获取计算机名称和用户名
  getmem(username,255);
  i:=255;
  getcomputername(computername,i);
  memo1.lines.add(' 计算机名称: '+computername);
  getusername(username,i);
  memo1.lines.add(' 用户名: '+username);
  freemem(computername);
  freemem(username);
  getsysteminfo(cpuinfo);  //获取CPU类型
  case cpuinfo.dwProcessorType of
     386 : buffer:='  CPU类型: 386';
     486 : buffer:='  CPU类型: 486';
     586 : buffer:='  CPU类型: Pentium';
  end;
  memo1.Lines.add(buffer);
  //从注册表中获取CPU标识,Windows版本,产品标识,注册单位名称及用户名
  myreg:=Tregistry.Create;
  myreg.RootKey:=HKEY_LOCAL_MACHINE;
  if myreg.OpenKey('hardware\description\system\centralprocessor\0',false) then
     memo1.lines.add(' CPU标识:'+myreg.ReadString('VendorIdentifier'));
  myreg.closekey;
  if myreg.openkey('software\microsoft\windows\currentversion',false) then begin
     memo1.lines.add(' windows版本:'+myreg.ReadString('Version'));
     memo1.lines.add(' 版本号:'+myreg.ReadString('VersionNumber')+''+myreg.ReadString('Subversionnumber'));
     memo1.lines.add(' 产品标识:'+myreg.Readstring('ProductID'));
     memo1.lines.add('注册单位名称:'+myreg.readstring('RegisteredOrganization'));
     memo1.lines.add(' 注册用户名:'+myreg.readstring('RegisteredOwner'));
  end;
  myreg.CloseKey;
  myreg.Free;
end;
end.
 
八、注册表配置ODBC的详细例子【思路】:
  先在ODBC中配置而后到注册表中去看有什么增长,而后照样写进去就能够了,可是这样作有一个问题,SQL Server默认是用命名管道,若是要用TCP/IP协议请在注册表中找1433,就能找到它是在那里.照样写进去就OK了。
var
  reg : TRegistry;
begin
  reg := TRegistry.Create;
  //创建一个Registry实例
  with reg do
  begin
     RootKey:=HKEY_LOCAL_MACHINE;
     //设置根键值为HKEY_LOCAL_MACHINE
     //找到Software\ODBC\ODBC.INI\ODBC Data Sources
     if OpenKey('Software\ODBC\ODBC.INI\ODBC Data Sources' True) then
       begin
         //注册一个DSN名称
         WriteString( 'DSN'  'SQL Server' );
       end
     else
       begin
         //建立键值失败
         ShowMessage('增长ODBC数据源失败');
         exit;
       end;
     CloseKey;
//找到或建立Software\ODBC\ODBC.INI\masdsn 写入DSN配置信息
     if OpenKey('Software\ODBC\ODBC.INI\DSN' True) then
       begin
         WriteString( 'Driver'  'C:\Windows\System\sqlsrv32.dll' );
         WriteString( 'LastUser'  'Username' );
         WriteString( 'Password'  'password' );
         WriteString( 'Server'  'ServerName' );
       end
     else
     //建立键值失败
     begin
       Showmessage('增长ODBC数据源失败');
       exit;
     end;
  CloseKey;
  Free;
  ShowMessage('增长ODBC数据源成功');
end;
   
//以上程序是写到system里的,固然一样能够写到当前用户里!
 
 
九、经过注册表读取设置字体
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Registry;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure WriteFontToRegistry(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ReadFontFromRegistry(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    Font : TFont;
  public
    { Public-Deklarationen }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
type
  TFontRegData = record
   Name : string[100];
   Size : integer;
   Color : TColor;
   Style : set of TFontStyle;
   Charset : byte;
   Height : integer;
   Pitch : TFontPitch;
   PixelsPerInch : integer;
end;
// Before writing font data to the registry you have to copy all needed data to a record of fixed size
procedure PrepareFontDataForRegistry(Font : TFont;var RegData : TFontRegData);
begin
  { Copy font data to record for saving to registry }
  //复制字体数据到记录并保存到注册表中
  with RegData do
  begin
    Name:=Font.Name;
    Size:=Font.Size;
    Color:=Font.Color;
    Style:=Font.Style;
    Charset:=Font.Charset;
    Height:=Font.Height;
    Pitch:=Font.Pitch;
    PixelsperInch:=Font.PixelsPerInch;
  end;
end;
procedure PrepareFontfromRegData(Font : TFont;RegData : TFontRegData);
begin
  { Set font data to values read from registry }
  //设置来自注册表的字体数据的值
  with Font do
  begin
    Name:=RegData.Name;
    Size:=RegData.Size;
    Color:=RegData.Color;
    Style:=RegData.Style;
    Charset:=RegData.Charset;
    Height:=RegData.Height;
    Pitch:=RegData.Pitch;
    PixelsperInch:=RegData.PixelsPerInch;
  end;
end;
//初始化
procedure TForm1.FormCreate(Sender: TObject);
begin
  Font:=TFont.Create;
  Font.Name:='Arial';
end;
//写入注册表
procedure TForm1.WriteFontToRegistry(Sender: TObject);
  var
  rd : TFontRegData;
  reg : TRegistry;
begin
  PrepareFontDataForRegistry(Font,rd);
  Reg:=TRegistry.Create;
  Reg.OpenKey('Software\Test',true);
  Reg.WriteBinaryData('FontData',rd,Sizeof(rd));
  reg.Free;
end;
//从注册表中读取字体设置值
procedure TForm1.ReadFontFromRegistry(Sender: TObject);
  var
  rd : TFontRegData;
  reg : TRegistry;
begin
  Reg:=TRegistry.Create;
  Reg.OpenKey('Software\Test',true);
  if Reg.ValueExists('FontData') then
    Reg.ReadBinaryData('FontData',rd,Sizeof(rd));
  reg.Free;
  PrepareFontFromRegData(Font,rd);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Font.Free;
end;
end.
 
十、系统注册表读写操做的例子代码  
操做注册表须要认识到注册表的六个根键。看看DELPHI的定义:
    const
     { Reserved Key Handles. }
     {$EXTERNALSYM HKEY_CLASSES_ROOT}
     HKEY_CLASSES_ROOT = DWORD($80000000);
     {$EXTERNALSYM HKEY_CURRENT_USER}
     HKEY_CURRENT_USER = DWORD($80000001);
     {$EXTERNALSYM HKEY_LOCAL_MACHINE}
     HKEY_LOCAL_MACHINE = DWORD($80000002);
     {$EXTERNALSYM HKEY_USERS}
     HKEY_USERS = DWORD($80000003);
     {$EXTERNALSYM HKEY_PERFORMANCE_DATA}
     HKEY_PERFORMANCE_DATA = DWORD($80000004);
     {$EXTERNALSYM HKEY_CURRENT_CONFIG}
     HKEY_CURRENT_CONFIG = DWORD($80000005);
     {$EXTERNALSYM HKEY_DYN_DATA}
     HKEY_DYN_DATA = DWORD($80000006);
    它们必须在TRegistry变量的RootKey属性中指定。
    要取得某一个路径的某个键值,必须找到某一个主键,例若有以下一个路径存放着WORD97存放的程序路径:
    \Software\Microsoft\Office\8.0\Word\InstallRoot\Path
其 中,PATH是键,在它前面的即是主键(键的路径),而这些键又是放在HKEY_LOCAL_MACHINE这个根键中的。固然,咱们想要的是PATH对 应的数据,而不是想知道有PATH这个键存在。PATH的类型是一个字符串,因此须要一个字符串变量存放它,例程中使用直接显示的方法表达它。
    所以,读出PATH键数据的过程就应该是,肯定根键,进入主键(路径),读出键的数据值。为了体现对注册表的写操做,咱们还特地建立一个主键\Software\3hsoft和里面一个字符串的键MyData。
下面是一小段关于此过程的程序,虽然内容很少,但基本上已经将读写的操做表现出来了。
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Registry; // 记得要加入这个红色的。
type
  TForm1 = class(TForm)
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
Const
  FPath = '\Software\Microsoft\Office\8.0\Word\InstallRoot';
  FKey = 'Path';
  FMyPath = '\Software\3hSoft';
  FMyKey = 'MyData';
Var
  Reg : TRegistry;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    If Reg.OpenKey(FPath, False) then
       ShowMessage(Reg.ReadString(FKey)); // 读出的 WinWord 的路径就显示出来了。
    Reg.CreateKey(FMyPath);      // 建立咱们的主键
    Reg.OpenKey(FMyPath, True);  // 进入咱们本身的主键中
    Reg.WriteString(FMyKey, 'This is a registry operation test program.');
        // 写进键值。
  finally
    Reg.Free; // 用 Try..Finally 结构确保 REG 变量可以释放。
  end;
end;
end. 
十一、用注册表对Delphi程序进行加密  
本加密方法分三部分:
  1. 根据对注册表的搜索结果断定设置对话框的内容。
  2. 若初次使用,则设新密码;如果已经设置密码,则进行验证。
  3. 一个密码变换小程序(比原来的复杂得多)。固然,若是须要修改密码的功能,只要将设置密码部分改动一下便可。
  (一)程序启动时,经过搜索注册表,判断是否已有密码,来肯定窗口的显示内容。不过事先应有如下的声明而后才能使用:
  在user中加入TRegistry,在var声明中加入如下几个窗体变量:
    var
     TheReg: TRegistry;
     KeyName,ValueStr,tempStr:String;
    procedure TfrmPass.FormShow(Sender: TObject);
  begin
    TheReg := TRegistry.Create;
    try TheReg.RootKey := HKEY-LOCAL-MACHINE;
    KeyName := ′SOFTWARE\Mypassword′;
    //有该键则打开,没有则建立
    if TheReg.OpenKey(KeyName, True) then begin
      tempStr:=ExtractFileName(Application.ExeName); //读取密码
      ValueStr:=TheReg.ReadString(tempStr);
      //密码不为空则修改窗体为验证密码
      if ValueStr<>′′ then begin
        edit2.Visible:=false; frmPass.Caption:=′验证密码′;
         edit1.SetFocus; OK.Caption:=′肯定′;
        end
      //密码为空则修改窗体为设置密码对话框
      else begin
        showmessage(′第一次使用请设置密码!′);
        edit2.Visible:=true; frmPass.Caption:=′请设置新密码′;
        edit1.SetFocus; OK.Caption:=′设置′;
      end;
        TheReg.CloseKey;
      end;
    finally
        TheReg.Free;
      end;
    end;
  (二)按钮的响应代码:包括新设密码和验证密码。
  procedure TfrmPass.OKClick(Sender: TObject);
  begin
    //根据Edit2的显示与否判断已有密码,进行验证
    if edit2.Visible=false then begin
      if pass(edit1.text)=ValueStr then begin
        showmessage(′密码正确!′);
        end
      else begin
        showmessage(′密码不正确!无权操做!′);
        halt;
        end;
      end //无密码,设置新密码
    else begin
      if edit1.text=edit2.text then begin
        TheReg := TRegistry.Create;
        TheReg.RootKey := HKEY-LOCAL-MACHINE;
        KeyName := ′SOFTWARE\Mypassword′;
        if TheReg.OpenKey(KeyName, True) then
          TheReg.WriteString(tempStr,pass(edit1.text));
        TheReg.CloseKey;
        end
      else begin
        showmessage(′再次键入的密码不一致,请重输!′);
        edit1.text:=′′; edit2.text:=′′;
        edit1.SetFocus;
        end; //进行下一步操做...
    end;
    end;
  (三)密码变换程序:注意要预先定义。
  这个变换小程序在笔者看来还不算很复杂,只进行了两次变换,不过,想要破译也是得费点劲。读者还能够采用其余的数学函数进行更为复杂的变换。
  function pass(pstr:string):string;
  var str,str1:string;
  i,j:integer;
  begin
   str:=pstr;
   for i:=1 to length(str) do begin
  //进行第一次变换
   j:=(i*i*i mod (i+20))+(i*i mod (i+10))+i*2+1;
   str1:=str1+chr(ord(str[i])+j); //第二次变换
   j:=(i*i*i mod (i+10))+(i*i mod (i+20))+i*2+1;
   str1:=str1+chr(ord(str[i])+j); end;
   pass:=str1;
  end;
 
十二、使Delphi程序记忆参数的设置 【王伟】
    咱们平时用的不少软件都具备一些记忆功能,如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一览无佘的看到,因此千万不能将一些重要的信息(如密码)不经加密而直接写入注册表,这样作是很是危险的!! 
1三、在DELPHI程序中动态设置ODBC数据源(使用注册表) 【编辑者说】:
    这个咚咚写得不错,比上面的那个更加详细,若是上面的那个看不明白就看这个吧,应该能看懂的吧,要否则....

    在DELPHI数据库应用程序中,咱们访问数据库一般有两种方法.一种是经过BDE数据库搜索引擎,即利用DELPHI自带的数据库驱动程序,这种方法的 优势是速度快,但应用范围有限,当数据库版本更新时,有可能不能用于操做新的数据库;另外一种方法是经过ODBC,这种方法的优势是能够随操做系统(如 WINDOWS)提供,做为标准接口能适应多种数据库,缺点是速度慢.在编程时,咱们能够根据须要选择其中的一种方法.
    在利用ODBC访问数据库时,一般的方法时是在ODBC管理面板中设置一个ODBC系统数据源 (系统DSN),而后在DBD中或在程序中设置一个数据库别名(Alias)对应该DSN,这样就能够如愿以偿地操做数据库了.相信用DELPHI作过数 据库应用的程序员对这方面已经很熟悉了,笔者就很少说了.在实际应用中,笔者曾遇到过这样的状况,咱们的数据库应用程序是依靠ODBC系统数据源访问和操 做数据库的,应用程序运行一直良好,直到某一天,一个对WINDOWS系统较为熟悉但又不太精通的用户不慎修改或删除了咱们预先设置的系统 DSN......
    因而,笔者就开始研究怎么在程序中动态地设置ODBC系统DSN的内容,这样就能够增长本身程序的坚固性了.通过整整一天对WINDOWS注册表的研究, 终于找到了ODBC管理程序设置DSN的秘密("天地自有公道,付出总会回报!",不是作广告!),现写出来与你们共享,也请高手指教.
    ODBC管理程序设置DSN的秘密在注册表中,不信能够到HKEY_LOCAL_MACHINE\Software\ODBC
去看看,确定让你感受已经成功了一半.
    首先来看看系统中已安装的ODBC数据库驱动程序.在HKEY_LOCAL_MACHINE\Software\ODBC\
ODBCInst.INI中,存放着已经安装了的ODBC数据库驱动程序的信息,从这里能够查到已安装的
ODBC 数据库驱动程序对应的DLL文件等信息.在ODBCInst.INI\ODBC Drivers的各个键值中,键名是驱动程序名称(如Microsoft Access Driver(*.mdb)),键值为“Installed”,表示驱动程序已安装.在 ODBCInst.INI\DriverName(DriverName为一个驱动程序名称,如Microsoft Access Driver(*.mdb)) 中,有驱动程序的详细信息,咱们主要从这里得到ODBC驱动程序对应的DLL文件的路径和文件名,即键名Driver的键值,通常 为"C:\WINDOWS\SYSTEM\FileName.DLL".
    而后来看系统DSN的注册信息,在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中,存放着系统 DSN的注册信息,咱们在ODBC管理面板设置的DSN参数就在这里.
    下面来看看建立一个ODBC系统DSN的步骤,即咱们在ODBC管理面板中完成参数设置后,ODBC
管理程序是怎么在注册表中 注册DSN信息的.以建立一个名称为MyAccess的Ms Access97类型的系统DSN为例,咱们指定的参数主要有数据库类型(Microsoft Access Driver(*.mdb))、数据源名称(MyAccess)、数据源描述(个人ACCESS)、数据库路径(C:\Inetpub\wwwroot \Test.mdb),其它参数如用户名称、用户密码、独占、只读、系统数据库、默认目录、缓冲区大小、扫描行数、页超时等采用系统缺省参数.这时,注册 系统DSN通常应有如下几个步骤:
  1.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\ODBC Data Sources中增长一个字符串
键值,为MyAccess = Microsoft Access Driver(*.mdb),其中分别为数据源名称和数据库类型.
这是在注册表中注册一个系统DSN名称.
  2.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中建立一个子键(SubKey)MyAccess,即
建立一个键为HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess,而后在其下建立一些键值,详细描述一个系统DSN的配置信息,主要信息有([]中的内容为笔者注释):
 DBQ=C:\Inetpub\wwwroot\Test.mdb
    [字符串,表示数据库路径]
 Description=个人ACCESS
   [字符串,表示数据库描述]
 Driver=C:\PWIN98\System\odbcjt32.dll
    [字符串,表示驱动程序,可见ODBCINST.INI]
 DriverId=0x00000019(25)
   [数字,表示驱动程序标识,不能改变]
 FIL=Ms Access;
    [字符串,可能与过滤Filter有关]
 SafeTransaction=0x00000000
    [数字,可能表示支持事务性操做的个数]
 UID=""
    [字符串,表示用户名称,此处为空字符串]
  3.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess中建立一个子键(SubKey)
Engines, 再在其下建立子键(SubKey)Jet,即建立一个键为 HKEY_LOCAL_MACHINE\Software
\ODBC\ODBC.INI\MyAccess\Engines\Jet,而后在其下建立一些 键值,详细描述一个系统DSN的数据库引擎配置信息,主要信息有([]中的内容为笔者注释):
 ImplicitCommitSync=Yes
    [字符串,可能表示是否当即反映数据修改]
 MaxBufferSize=0x00000200(512)
    [数字,表示缓冲区大小]
 PageTimeout=0x00000005(5)
    [数字,表示页超时]
 Threads=0x00000003(3)
    [数字,可能表示支持的最大线程数目]
 UserCommitSync=Yes
[字符串,可能表示是否当即将数据修改反映到用户]
    以上是创建一个系统DSN的基本信息(其它信息如选项或高级选项等信息也在这里设置,
只不过因采用默认信息,注册表里没有列出),咱们在程序中按上述步骤操做注册表,一样也能增长一个系统DSN或修改其配置.在下面的例子程序中,将按以上步骤创建一个系统DSN,请注意程序中的注释.
{*******************************************************
在本程序中,将建立一个ODBC系统数据源(DSN),
数据源名称:MyAccess  数据源描述:个人新数据源
数据库类型:ACCESS97
对应数据库:C:\Inetpub\wwwroot\test.mdb
*******************************************************}
{ 注意应在USES语句中包含Registry }
procedure TForm1.Button1Click(Sender: TObject);
var
  registerTemp : TRegistry;
  bData : array[ 0..0 ] of byte;
begin
  registerTemp := TRegistry.Create;
  //创建一个Registry实例
  with registerTemp do
    begin
      RootKey:=HKEY_LOCAL_MACHINE;
      //设置根键值为HKEY_LOCAL_MACHINE
      //找到Software\ODBC\ODBC.INI\ODBC Data Sources
      if OpenKey('Software\ODBC\ODBC.INI\ODBC Data Sources',True) then
      begin //注册一个DSN名称
        WriteString( 'MyAccess', 'Microsoft Access Driver (*.mdb)' );
      end
      else
      begin//建立键值失败
        memo1.lines.add('增长ODBC数据源失败');
        exit;
      end;
      CloseKey;
//找到或建立Software\ODBC\ODBC.INI\MyAccess,写入DSN配置信息
      if OpenKey('Software\ODBC\ODBC.INI\MyAccess',True) then
      begin
        WriteString( 'DBQ', 'C:\inetpub\wwwroot\test.mdb' );//数据库目录
        WriteString( 'Description','个人新数据源' );//数据源描述
        WriteString( 'Driver', 'C:\PWIN98\SYSTEM\odbcjt32.dll' );//驱动程序DLL文件
        WriteInteger( 'DriverId', 25 );
     //驱动程序标识
        WriteString( 'FIL', 'Ms Access;' );
     //Filter依据
        WriteInteger( 'SafeTransaction', 0 );
     //支持的事务操做数目
        WriteString( 'UID', '' );//用户名称
        bData[0] := 0;
        WriteBinaryData( 'Exclusive', bData, 1 );
     //非独占方式
        WriteBinaryData( 'ReadOnly', bData, 1 );
     //非只读方式
      end
      else//建立键值失败
      begin
        memo1.lines.add('增长ODBC数据源失败');
        exit;
      end;
      CloseKey;
//找到或建立Software\ODBC\ODBC.INI\MyAccess\Engines\Jet
    //写入DSN数据库引擎配置信息
      if OpenKey('Software\ODBC\ODBC.INI\MyAccess\Engines\Jet',True) then
      begin
        WriteString( 'ImplicitCommitSync', 'Yes' );
        WriteInteger( 'MaxBufferSize', 512 );//缓冲区大小
        WriteInteger( 'PageTimeout', 10 );//页超时
        WriteInteger( 'Threads', 3 );//支持的线程数目
        WriteString( 'UserCommitSync', 'Yes' );
      end
      else//建立键值失败
      begin
        memo1.lines.add('增长ODBC数据源失败');
        exit;
      end;
      CloseKey;
      memo1.lines.add('增长新ODBC数据源成功');
      Free;
    end;
end;
   
以上程序在PWIN98+DELPHI3.0下调试经过.
    下面是建立常见数据库类型的DSN须要设置的信息([]为注释内容,除特殊注释外,各参数可见前面说明):
 1.Access(Microsoft Access Driver(*.mdb))
     DBQ、Description、Driver[odbcjt32.dll]、DriverID[25]、FIL[Ms Access;]、SafeTransaction[默认为0]、UID[默认为空]、Engines\Jet \ImplicitCommitSync[默认为Yes]、Engines\Jet\MaxBufferSize[默认512]、Engines\Jet \PageTimeout[默认为512]、Engines\Jet\Threads[默认为3]、Engines\Jet \UserCommitSync[默认为Yes]
     可选设置:SystemDb[字符串,系统数据库的路径]、ReadOnly[二进制,是否以只读方式打开,1为是,默认为0]、Exclusive[二进制,是否以独占方式打开,1为是,默认为0]、PWD[字符串,用户密码]
2.EXCEL(Microsoft Excel Driver(*.xls))
    DBQ[Excel97(=path\xxx.xls)、5.0/7.0(=path\xxx.xls)、4.0(=path)、 3.0(=path)]、Description、Driver[odbcjt32.dll]、DefaultDir[Excel97(< >DBQ)、5.0/7.0(< >DBQ)、4.0(=DBQ)、3.0(=DBQ)]、DriverID[790(Excel97)、22(5.0/7.0)、 278(4.0)、534(3.0)]、FIL[Excel5.0;]、ReadOnly、SafeTransaction、UID、 Engines\Excel\ImplicitCommitSync、
Engines\Excel\MaxScanRows[数字,扫描行数,默 认为8]、Engines\Excel\Threads、Engines\Excel\UserCommitSync、Engines\Excel \FirstRowHasName[二进制,第一行是不是域名,1表示是,默认为1]
    【注】: Excel97和Excel7.0/5.0的DBQ对应一个XLS文件,而Excel4.0和Excel3.0则对应一个目录;DefaultDir对应 一个目录,在Excel97和Excel7.0/5.0中是DBQ所对应的路径,而在Excel4.0和Excel3.0下则与DBQ相同;各个版本的 DriverID不一样.
3.dBase(Microsoft dBase Driver(*.dbf))
    DefaultDir[字符串,数据库文件所在目录]、Description、Driver[odbcjt32.dll]、
 DriverID[277(IV)、 533(5.0)]、FIL[dbase III;]、SafeTransaction、UID、Engines\Xbase\ImplicitCommitSync、Engines\Xbase \Collating[字符串,排序依据,可为ASCII、International、Norwegian-Danish、Swedish- Finnish]、Engines\Xbase\Deleted[二进制,是否不显示被软删除的记录,0表示显示,默认为1]、Engines \Xbase\PageTimeout[默认为600]、Engines\Xbase\UserCommitSync、Engines\Xbase \Threads、Engines\Xbase    \Statistics[二进制,是否用大约的行数,1为是,默认0]
     【注】:(dBaseIV和dBase5.0两个版本的DriverId有不一样)
4.Foxpro(Microsoft Foxpro Driver(*.dbf))
    DefaultDir[数据库文件所在目录]、Description、Driver[odbcjt32.dll]、 DriverID[536(2.6)、280(2.5)]、FIL[Foxpro 2.0;]、SafeTransaction、UID、Engines\Xbase\Collating[字符串,排序依据,可为ASCII、 International]、Engines\Xbase\Deleted[二进制,是否不显示 被软删除的记录,0表示显示,默认为1]、Engines\Xbase\PageTimeout[默认为600]、Engines\Xbase \UserCommitSync、Engines\Xbase\Threads、Engines\Xbase\Statistics[二进制,是否用大约 的行数,1为是,默认0]
    【注】:(Foxpro2.5和Foxpro2.6两个版本的DriverId有不一样)
     把上面程序作成一个COM或ActiveX控件吧,在不少高级程序设计语言如DELPHI、 C++Buider、VB、VC、PB中都能用到的
 
 2003-11-20 14:30:46    如何在注册表中注册BDE【编者语】:
    上面讲了几个注册ODBC的例子,这回咱们来讲说怎样注册BDE
只拷贝BDE文件是不行的,还要写注册表:
必需的注册表项目包括:
1. BDE动态链接库文件位置设置
Key : "HKEY_LOCAL_MACHINE\Software\Borland\Database Engine"
Item : "DLLPATH"
Value : BDE动态链接库文件所在位置,如"C:\Program Files\Borland\Common Files\BDE"
(打开"C:\Program Files\Borland\Common Files\BDE\BDE32.hlp",查找"Core Files"便可了解BDE各动态链接库文件的做用)
2. BDE语言驱动文件路径设置
Key : "HKEY_LOCAL_MACHINE\Software\Borland\BLW32"
Item : "BLAPIPATH"
Value : BDE语言驱动文件所在路径,如"C:\Program Files\Borland\Common Files\BDE"
(BDE语言驱动就是那些*.BLL文件)
3. 指定可用的BDE语言驱动文件
Key : "HKEY_LOCAL_MACHINE\Software\Borland\BLW32"
Item : "LOCALE_LIB#" (#表示数字, 如"LOCALE_LIB1"、"LOCALE_LIB3"等)
Value : 指定各BDE语言驱动文件,如"C:\Program Files\Borland\Common Files\BDE\USA.BLL"
(通常必需的语言驱动文件有"USA.BLL","EUROPE.BLL"和"FAREAST.BLL",为保险起见,建议将全部语言驱动都设置上。在安装了Delphi3的机器上,用Regedit打开注册表,一看你就明白了怎么设了)
 
1四、用DEPHI为应用软件创建注册机制【编者语】:
    上面给了一个“使用DELPHI给程序加密的方法”,想对这个方法作一些补充说明,由于资料较老,请酌情参考。

  如何保护本身的软件不被非受权盗用的问题,始终困扰着每个程序员。当前世界上保护
软件的方法有不少,主要是采用加密(如加软件狗)方式或软件注册方式。使用软件狗等加密方
法,虽然其保护最有效,但对受权用户的正常使用有必定的影响,并且软件发放比较复杂,在实
际运用中比较少被采用。而注册登记方式则是当前最流行、运用最普遍的方法,虽然有许多通用
软件其注册码能够很容易地被发烧友们所解,但对于独立程序员为某特定应用设计的应用软件而
言,采用注册机制显得最经济、最方便,并且在必定的范围内很是有效。笔者在实际工做中,广
泛使用了软件注册方法,有效地维护了软件的权益。
  DEPHI软件的功能极为强大,深受程序员喜欢。用DEPHI开发的软件,能够很方便地加入注册机制。下面笔者就如何在DEPHI开发的软件中加入注册机制与朋友们交流心得。
  要实现软件注册机制,需解决如下几个问题:
    一、如何加入注册检测,判断软件是否注册;
    二、如何隐藏注册码,及是否注册的标志;
    三、在软件不注册状况下,如何限制软件的使用时间或次数;
    四、对正经常使用户而言,不该形成使用不便。
对 于以上四个问题,如何隐藏注册码及是否注册的标志是关键。在WINDOWS95中,WIN95自己及大多数的应用软件都将其各类参数放入注册表中,于是注 册表内的数据显得极为庞大和复杂。若是将注册标志隐藏在注册表的某一角落中,想要找到它并理解它是极其困难的事。所以咱们能够利用这一点,在注册表的某个 分支上设置一个从名称上看毫无特殊意义的关键字,将本身软件的注册标志数据存放在这里。
    整个注册机制主要由两个部分组成:检查和注册。经过检查标志值,得出软件是否已注册;若没有注册,则要看它容许使用的次数是否已达到;若可以使用的次数已用 完,则应提示用户输入注册码,进行注册;只有用户输入的注册码正确时,才让用户继续使用软件,同时将标志置为已注册,让用户永久性使用;不然容许使用的次 数未达到,应将次数加一;
若用户注册输入的注册码错误或拒绝注册,则直接关闭软件,拒绝其继续使用。固然,在软件允
许使用次数未达到时,也应经过菜单项为用户提供机会进行注册登记。如下是笔者在实际开发
中,创建注册机制的程序代码及注释。
假设软件的主程序窗口为FORM1,则将该段代码置放在FORM1.CREATE事件中。代码以下:
procedure TForm1.form1create(Sender: TObject);
var
  re_id:integer;
  registerTemp : TRegistry;
  inputstr,get_id:string;
  dy,clickedok:boolean;
begin
 dy:=false; //软件是否已到注册期、及是否容许继续使用的标志,当值为FALSE是为容许使
用。
 registerTemp := TRegistry.Create; //准备使用注册表
 with registerTemp do
 begin
   RootKey:=HKEY_LOCAL_MACHINE; //存放在此根下
   if OpenKey('Software\Microsoft\Windows\CurrentVersion\Mark',True) then
   // 建一目录,存放标志值。固然也能够存放在已存在的目录下。怎么样,很难发现吧?
    begin
     if valueexists('gc_id') then begin
          //用gc_id的值做为标志,首先判断其存在否?
       re_id:=readinteger('gc_id');//读出标志值
       if (re_id<>0) and (re_id<>100) then begin
              //若标志值为0,则说明已注册。
        //若不为0且值不到100,说明虽未注册,但容许使用的次数还没有达到。
        re_id:=re_id+5;
                //容许标志的最大值为100,每次加5,则最多只可用20次。
        Writeinteger('gc_id',re_id);//将更新后的标志值写入注册表中。
     end;
     if re_id=100 then dy:=true; //假如值已到100,则应注册。
    end
   else Writeinteger('gc_id',5);//创建标志,并置初始标志值。
  end;
  if dy then begin //若dy值为TRUE,则应提示用户输入注册码,进行注册。
    clickedok:=InputQuery('您使用的是非注册软件,请输入注册码:',' ',inputstr);
    if clickedok then begin
      get_id:=inttostr(27593758*2);//注册码为55187516,固然可加入更杂的算法。
      if get_id=inputstr then begin
        Writeinteger('gc_id',0);
                //若输入的注册码正确,则将标志值置为0,即已注册。
        CloseKey;
        Free;
       end
      else begin //若输入的注册码错误,应做出提示并拒绝让其继续使用
        application.messagebox('注册码错误!请与做者联系!','警告框',mb_ok);
        CloseKey;
        Free;
        application.terminate; //停止程序运行,拒绝让其继续使用
       end;
      end
    else begin //若用户不输入注册码,也应做出提示并拒绝让其继续使用
      application.messagebox('请与做者联系,使用注册软件!','警告框',mb_ok);
      CloseKey;
      Free;
      application.terminate;
     end;
  end;
 end;
end;
(注:经过菜单进行注册的方法同本段提示用户进行注册的内容雷同,这里不提供代码。)
  以上程序代码已在DEPHI3.0/WIN95环境中运行经过,并在实际运用中获得验证。对合法用户而言,这样的机制,只要其录入注册码一 次就能够,不增长其平常使用的负担;而对非法用户而言,除非他获得注册码或重装WINDOWS95,不然超过使用次数后,将没法继续使用。固然在实际应用 中还有许多地方能够进一步增强反破解能力,欢迎朋友们提出批评和指导。 
 
1五、经过对注册表进行修改,能够删除资源管理器上下文件菜单中对某类文件的处理命令【问题】:
    经过对注册表进行修改,能够删除资源管理器上下文件菜单中对某类文件的处理命令程序例以下:
procedure FileTDelAction(key, name: String);
//key:关联键值为后缀的描述键值,如.tst对应testfile,则key:=testfile
//name:命令名称
var
    myReg: TRegistry;
begin
    myReg:=TRegistry.Create;
    myReg.RootKey:=HKEY_CLASSES_ROOT;
    //若是给出的是一个文件后缀,则转换成对应的描述键值
    //在生成文件关联时,若是未给出描述键值,则会自动生成,此处与上面是联系的
    {if key[1] = '.' then
     key:= copy(key,2,maxint)+'_auto_file';}
    if key[1] = '.' then
    begin
        if myReg.KeyExists(key) then  //首先看注册表中是否有此键,有则取出
        begin
            myReg.OpenKey(key, false);
            key:=myReg.ReadString ('');
        end
        else
            key:= copy(key,2,maxint)+'_auto_file';
    end;
    if key[Length(key)-1] <> '\' then
        key:=key+'\';
    myReg.OpenKey('\'+key+'shell\', true);
    if myReg.KeyExists(name) then
        myReg.DeleteKey(name);
    myReg.CloseKey;
    myReg.Free;
end;
调用例子:
    Example:
       FileTDelAction('test','edit');
原理说明:
将注册表中对应的键值删除就能够了。
 
 
1六、用Delphi实现壁纸更换(适用于Windows95/98)   在Windows95/98中,都是使用注册表对系统数据进行管理,有关壁纸的设置数据保存在
Hkey_Current_User\Control Panel\Desktop的Wallpaper和TileWallpaper 等键值中,只要成功修改了这两个键值,而后发消息给Windows便可更换壁纸。在本例的程序中,使用了一个Tform;两个 Tspeedbutton(Speedbutton1用于接受用户的浏览命令,Speedbutton2用于接受用户的更换壁纸命令);一个 Timage(用于显示图片)。另外,还用到一组文件控件:
    Tfilelistbox,Tdrivecombobox,Tdirectorylistbox,用于选择图片文件,能够设置FileListBox的 mask属性,筛选显示在FileListBox 中的文件类型(如只显示.bmp文件)。下面的两个程序段是实现浏览图片和更换壁纸的关键代码。
    Procedure Tform1.SpeedButton1Click(Sender:Tobject);
    Begin
    If (filelistbox1.FileName=′′) Then {判断Filelistbox1中文件有没有被选中}
      Messagedlg(′请先选择一幅位图′,mtInformation,[mbOK],0)
    Else
      Image1.Picture.LoadFormFile(Filelistbox1.FileName);{加载图片文件并显示}
    End;
    ProcedureTform1.SpeedButton2Click(Sender:TObject);
    Var
      Reg:Tregistry;
      {Tregistry 对象在Registry 单元中声明,需用Uses令引用Registry单元}
    }
    Begin
      If (Filelistbox1.FileName=′′) Then
        Messagedlg(′请先选择一幅位图′,mtinformation,[mbOK],0)
      Else
      Begin
        Reg:=Tregistry.Create;{建立Tregistry对象的实例}
        Reg.Rootkey:= Hkey_Current_User;{设置根键名称}
        Reg.OpenKey′Control Panel\Desktop′,False);
        {打开Control Panel\Desktop路径对应的主键}
        Reg.WriteString (′TileWallPaper′, ′0′);
        Reg.WriteString ′Wallpaper′,fileli?stbox1.FileName);
        {向TileWallpaper 和Wallpaper串覆盖写入新值}
        Systemparametersinfo(SPI_SETDESKWallpaper,0,Nil,SPIF_SendChange);
        {向Windows发送消息,通知Windows更换壁纸}
        Reg.CloseKey;{将更改内容写入注册表并关闭}
        Reg.Free;{释放对象}
      End;
    End;
    代码中用到的一些函数能够察看Delphi的联机帮助。须要注意的是:调用打开子键的函数OpenKey时,第二个参数必定要设为False。
    经过对注册表进行修改,能够在资源管理器上下文菜单中增长对某类文件的处理命令程序例以下:
procedure FileTAddAction(key, name, display, action: String);
//key:关联键值为后缀的描述键值,如.tst对应testfile,则key:=testfile
//name:命令名称
//display:在上下文件菜单上显示的提示信息
//action:对应的命令
var
    myReg:TRegistry;
begin
    myReg:=Tregistry.Create;
    myReg.RootKey:=HKEY_CLASSES_ROOT;
    if name='' then name:=display;
    //若是给出的是一个文件后缀,则转换成对应的描述键值
    //在生成文件关联时,若是未给出描述键值,则会自动生成,此处与上面是联系的
{    if key[1] = '.' then
        key:= copy(key,2,maxint)+'_auto_file';}
    if key[1] = '.' then
    begin
        if myReg.KeyExists(key) then  //首先看注册表中是否有此键,有则取出
        begin
            myReg.OpenKey(key, false);
            key:=myReg.ReadString ('');
        end
        else
            key:= copy(key,2,maxint)+'_auto_file';
    end;
    if key[Length(key)-1] <> '\' then
        key:=key+'\';
    if name[Length(name)-1] <> '\' then
        name:=name+'\';
    myReg.OpenKey(key+'Shell\'+name, true);
    myReg.WriteString('', display);
    MyReg.CloseKey;
    MyReg.OpenKey(key+'Shell\'+name+'Command\', true);
    MyReg.WriteString('', action);
    myReg.Free;
end;
调用例子:
 Example:
       FileTAddAction('testfile','edit','Edit',Application.ExeName+'-e "%1"');
原理说明:
    如.txt对应的描述键值为testfile
    则在testfile的键值下面,增长动做子键
    如:  testfile\shell\         '', Edit
          testfile\shell\Command\ '', 'c:\testfile -e "%1"'
 
1七、如何建立程序快捷方式实现原理:
    经过OLE Interface 来实现,通时要处理注册表。
    对于快捷方式的存储位置能够指定为桌面,开始菜单,发送到等,这样首先经过对系统注册
表的读取,获取相应的真正地址,将用于保存快捷方式文件。
    使用三个接口:IUnknown, IShellLink, IPersistFile
    IUnknown取得通常性的com 对象
    IShellLink取得对快捷方式的处理,能够设置执行文件名,快捷键,描述,参数等
    IPersistFile对生成的快捷方式进行保存
程序以下:
//加入以下单元
uses
  Registry, ShlObj, ActiveX, ComObj;
//定义快捷方式存放位置桌面,发送,开始菜单
type
  ShortcutType = (_DESKTOP, _QUICKLAUNCH, _SENDTO, _STARTMENU);
procedure CreateShortcut(
  FileName: string;               //执行文件名,全路径
  description: string;            //快捷方式描述
  arguments: string;              //参数
  Location: ShortcutType          //存放位置
);
var
  MyObject : IUnknown;
  MySLink : IShellLink;
  MyPFile : IPersistFile;
  Directory,
  LinkName : string;
  WFileName : WideString;
  MyReg,
  QuickLaunchReg : TRegIniFile;
begin
  MyObject := CreateComObject(CLSID_ShellLink);    //建立com对象
  MySLink := MyObject as IShellLink;               //转化为IShellLink接口
  MyPFile := MyObject as IPersistFile;             //转化为IPersistFile接口
  MySLink.SetPath(PChar(FileName));                //设置执行文件名
  MySLink.SetArguments(PChar(arguments));          //设置执行参数
  MySLink.SetDescription(PChar(Description));      //设置描述
  MySLink.SetWorkingDirectory(PChar(ExtractFilePath(application.exename)));
                                                   //设置工做路径为执行程序所在目录
 
//下面开始取存放位置的实际目录
  MyReg :=TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer');
  try
    LinkName := ChangeFileExt(FileName, '.lnk');   //生成快捷方式文件名
    LinkName := ExtractFileName(LinkName);         //取文件主名
    case Location of
      _DESKTOP    : Directory := MyReg.ReadString('Shell Folders','Desktop', '');
      _STARTMENU  : Directory := MyReg.ReadString('Shell Folders','Start Menu', '');
      _SENDTO     : Directory := MyReg.ReadString('Shell Folders','SendTo', '');
      _QUICKLAUNCH:
        begin
          QuickLaunchReg :=
            TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\GrpConv');
          try
            Directory := QuickLaunchReg.ReadString('MapGroups', 'Quick Launch', '');
          finally
            QuickLaunchReg.Free;
          end;
        end;
    end;
    if Directory <> '' then
      begin
        WFileName := Directory + '\' + LinkName;   //合成存放快捷方式文件全路径名
        MyPFile.Save(PWChar(WFileName), False);    //保存快捷文件
      end;
  finally
    MyReg.Free;
  end;
end;
【注】:关于更详细的IShellLink的说明能够查看相关的帮助文档。若是要删除快捷方式,则将.LNK文件删除便可。
Delphi 4.0 [Help]->[MS SDK Help Files]->《Win32 Developer's References》
 
 
1八、问:如何让个人程序像“Explorer”同样,系统重启后能恢复到系统关闭时的状态?【答】:
    实际上是注册表在做怪,你可能已经注意到,让本身的程序随着Windows的启动而启动是在“HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\Windows\CurrentVersion\Run”下注册,而要达到你的目的就是在“..\RunOnce”下注册便可。当 然,余下的问题就是在何时写入这个信息?若是你当心的话,就会发现Delphi自己附带了一个例子(Tregistry下)。说到这里,咱们又要提到 Windows的消息了,只是限于篇幅,就这个问题这里就再也不赘述了,我我的建议你们注意一下Delphi的Messages.pas单元中关于 WM_XXX的定义及Windows API的帮助。
uses
  Windows, Messages,..., Registry;
private
  procedure WMEndSession(var Msg:TWMEndSession); message WM_ENDSESSION;
procedure TForm1.WMEndSession(var Message: TWMEndSession);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\RunOnce',
True) then
      Reg.WriteString('MyApp','"' + ParamStr(0) + '"');
    finally
      Reg.CloseKey;
      Reg.Free;
      inherited;
    end;
end;
 
1九、经过对注册表进行修改,能够在资源管理器上下文件菜单中的新建子菜单中增长新的命令   同时请参考“经过对注册表进行修改,能够删除资源管理器上下文件菜单中对某类文件的处理命令”的文章。
程序例以下:
type
     TFileNewType = (ftNullFile, ftFileName, ftCommand);
procedure FileTAddNew(ft, param: String; newType: TFileNewType);
//fp:文件后缀键值,如.tst
//param:传递参数
//newType:新建的类型,有空文件, 文件名, 命令
var
    myReg:TRegistry;
begin
    myReg:=TRegistry.Create;
    myReg.RootKey:=HKEY_CLASSES_ROOT;
    if not myReg.KeyExists(ft) then
        begin
          MyReg.Free;
          Exit;
        end;
    myReg.OpenKey(ft+'\ShellNew', true);
    case NewType of
        ftNullFile : MyReg.WriteString('NullFile', '');
        ftFileName : MyReg.WriteString('FileName', param);
        ftCommand  : MyReg.WriteString('Command', param);
    end;
    MyReg.CloseKey;
    MyReg.Free;
end;
调用例子:
 Example:
       FileTAddNew('.tst','', ftNullFile);
原理说明:
    在后缀键的下面增长子键ShellNew。如在上下文菜单中增长新建.tst文件的命令
    在.tst键值下面增长子键    .tst\ShellNew     'NullFile', ''
 
20、如何用DELPHI搜索注册表的所有项、鍵unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 Grids, Registry,  StdCtrls, ExtCtrls, ComCtrls;
type
 TForm1 = class(TForm)
   StatusBar1: TStatusBar;
   Panel1: TPanel;
   StringGrid1: TStringGrid;
   btnStart: TButton;
   btnRemove: TButton;
   edKey: TEdit;
   edTime: TEdit;
   edValueName: TEdit;
   edValue: TEdit;
   btnStop: TButton;
   procedure btnStartClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure FormShow(Sender: TObject);
   procedure btnRemoveClick(Sender: TObject);
   procedure StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
     var CanSelect: Boolean);
   procedure btnStopClick(Sender: TObject);
 private
   { Private declarations }
   fRegistry: TRegistry;
   fRowCount: Integer;
   fCurrentKeyValue: String;
   fStopFlag: Boolean;
   fNoSelection: Boolean;
   procedure DoAnalyzeRegistry;
   procedure DoAnalyzeBranch;
   procedure DoAnalyzeKey(const Key: String);
   function  DoAnalyzeValue(const Key, Value: String): Boolean;
 public
   { Public declarations }
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
const Root : Array[0..3] of Char = ('A', ':', '\', #0);
const
 nKeyName     = 0;
 nFileTime    = 1;
 nValueName   = 2;
 nValueString = 3;
procedure NormalizeRegistryPath(var Path: String);
begin
 if (Path = '') or (Path[1] <> '\') then
   Path := '\' + Path;
end;
procedure TForm1.btnStartClick(Sender: TObject);
begin
 btnStop.Enabled  := TRUE;
 fRowCount := 1;
 StringGrid1.RowCount := 2;
 StringGrid1.Cells[nKeyName, 1]     := '';
 StringGrid1.Cells[nFileTime, 1]    := '';
 StringGrid1.Cells[nValueName, 1]   := '';
 StringGrid1.Cells[nValueString, 1] := '';
 DoAnalyzeRegistry;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 fRegistry := TRegistry.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 fRegistry.Free;
end;
procedure TForm1.DoAnalyzeRegistry;
begin
 fStopFlag    := FALSE;
 fNoSelection := TRUE;
 if not fStopFlag then
 begin
   fCurrentKeyValue  := 'HKEY_CURRENT_USER';
   fRegistry.RootKey := HKEY_CURRENT_USER;
   fRegistry.OpenKey('\', FALSE);
   DoAnalyzeBranch();
 end;
 if not fStopFlag then
 begin
   fCurrentKeyValue  := 'HKEY_USERS';
   fRegistry.RootKey := HKEY_USERS;
   fRegistry.OpenKey('\', FALSE);
   DoAnalyzeBranch();
 end;
 if not fStopFlag then
 begin
   fCurrentKeyValue  := 'HKEY_LOCAL_MACHINE';
   fRegistry.RootKey := HKEY_LOCAL_MACHINE;
   fRegistry.OpenKey('\Software', FALSE);
   DoAnalyzeBranch();
 end;
 StringGrid1.RowCount := fRowCount;
 StatusBar1.SimpleText := 'Number of invalid references: '+IntToStr(fRowCount - 1);
 btnStop.Enabled := FALSE;
 if fRowCount = 1 then
 begin
   MessageDlg('No invalid references detected.',mtInformation,[mbOK],0);
   btnRemove.Enabled := FALSE;
 end
 else
 begin
   btnRemove.Enabled := TRUE;
 end;
end;
procedure TForm1.DoAnalyzeBranch;
var
 I: Integer;
 Keys: TStringList;
 Path: String;
begin
 Keys := TStringList.Create;
 try
   Path := fRegistry.CurrentPath;
   fRegistry.GetKeyNames(Keys);
   for I := 0 to Keys.Count - 1 do
   begin
     if fRegistry.OpenKey(Keys[I], FALSE) then
     begin
       DoAnalyzeKey(Keys[I]);
       if fStopFlag then Break;
       if fRegistry.HasSubKeys then DoAnalyzeBranch;
     end;
     if fStopFlag then Break;
     NormalizeRegistryPath(Path);
     if not fRegistry.OpenKey(Path, FALSE) then
       raise exception.Create('Can not open key '+Path);
   end;
 finally
   Keys.Free;
 end;
end;
procedure TForm1.DoAnalyzeKey(const Key: String);
var
 I: Integer;
 Values: TStringList;
 DataType: TRegDataType;
 StringValue: String;
 RegKeyInfo: TRegKeyInfo;
 SystemTime: TSystemTime;
 StringDate: String;
begin
 Values := TStringList.Create;
 try
   fRegistry.GetValueNames(Values);
   for I := 0 to Values.Count - 1 do
   begin
     DataType := fRegistry.GetDataType(Values[I]);
     if (DataType = rdString) or (DataType = rdExpandString) then
     begin
       StatusBar1.SimpleText := 'Analyzing: '+Key;
       { Let the applocation to process messages,
         so the text would be on the status bar
         while we are still in the loop }
       Application.ProcessMessages;
       if fStopFlag then Break;
       StringValue := fRegistry.ReadString(Values[I]);
       if (not DoAnalyzeValue(Key, Values[I])) or
          (not DoAnalyzeValue(Key, StringValue)) then
       begin
         if StringGrid1.RowCount = fRowCount then
           StringGrid1.RowCount := fRowCount + 10;
         fRegistry.GetKeyInfo(RegKeyInfo);
         FileTimeToSystemTime(RegKeyInfo.FileTime, SystemTime);
         DateTimeToString(StringDate, 'mm/dd/yyyy hh:mmAM/PM', SystemTimeToDateTime(SystemTime));

         StringGrid1.Cells[nKeyName, fRowCount] := fCurrentKeyValue + ': ' +fRegistry.CurrentPath;
         StringGrid1.Cells[nFileTime, fRowCount]:= StringDate;
         StringGrid1.Cells[nValueName, fRowCount]   := Values[I];
         StringGrid1.Cells[nValueString, fRowCount] := StringValue;
         { If there is no rows selected yet then select the first one }
         if fNoSelection then
         begin
           fNoSelection := FALSE;
           StringGrid1.Selection := TGridRect(Rect(0, 1, 4, 1));
         end;
         Inc(fRowCount);
       end;
     end;
   end;
 finally
   Values.Free;
 end;
end;

function TForm1.DoAnalyzeValue(const Key, Value: String): Boolean;
var
 DriveType: UINT;
 Path: String;
 FileName: String;
begin
 Result := TRUE;
 { Verify if the string can be treated as path (and file name)}
 if Length(Value) < 3 then Exit;
 if not (UpCase(Value[1]) in ['C'..'Z']) then Exit;
 if Pos(';', Value) > 0 then Exit;
 if Pos(',', Value) > 0 then Exit;
 if Pos(' ', Value) > 0 then Exit;
 if (Value[2] <> ':') or (Value[3] <> '\') then Exit;

 Root[0] := Value[1];
 DriveType := GetDriveType(Root);
 if (DriveType = DRIVE_FIXED) then
 begin
   if (ExtractFileExt(Value) = '') then
   begin
     { No extension, try to treat the value as path }
     Path := Value;
     if (Path[Length(Path)] <> '\') then
       Path := Value + '\';
     if not SetCurrentDirectory(PChar(Path)) then
     begin
       Result := FALSE;
       Exit;
     end;
   end
   else
   begin
     Path := ExtractFilePath(Value);
     if not SetCurrentDirectory(PChar(Path)) then
     begin
       Result := FALSE;
       Exit;
     end;
     FileName := ExtractFileName(Value);
     if (GetFileAttributes(PChar(Value)) = -1) then
     begin
       Result := FALSE;
       Exit;
     end;
   end;
 end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 StringGrid1.Cells[nKeyName, 0] := 'Registry Key';
 StringGrid1.Cells[nFileTime, 0] := 'Last Modification';
 StringGrid1.Cells[nValueName, 0] := 'String Value';
 StringGrid1.Cells[nValueString, 0] := 'File/Path reference';
 fRowCount := 1;
 btnRemove.Enabled := FALSE;
 btnStop.Enabled := FALSE;
 fNoSelection := TRUE;
end;

procedure TForm1.btnRemoveClick(Sender: TObject);
var
 I: Integer;
 Msg: String;
 Count: Integer;
 Selection: TGridRect;
 RootKey: Longint;
 Path: String;
 procedure ParseKeyValue(const S: String);
 var
   I: Integer;
   Key: String;
 begin
   I := Pos(':', S);
   Key := Copy(S, 1, I-1);
   Path := Copy(S, I+2 , Length(S));
   NormalizeRegistryPath(Path);
   if Key = 'HKEY_CURRENT_USER' then
     RootKey := HKEY_CURRENT_USER
   else if Key = 'HKEY_USERS' then
     RootKey := HKEY_USERS
   else if Key = 'HKEY_LOCAL_MACHINE' then
     RootKey := HKEY_LOCAL_MACHINE;
 end;
begin
 Selection := StringGrid1.Selection;
 Count := Selection.Bottom - Selection.Top + 1;
 if Count = 1 then
   Msg := 'Are you sure you want to remove selected entry from the Registry?'
 else
   Msg := 'Are you sure you want to remove ' +
                  IntToStr(Selection.Bottom - Selection.Top + 1) +
               ' selected entries from the Registry?';
 if MessageDlg(Msg, mtWarning, [mbYes,mbNo], 0) = mrYes then
 begin
   for I := Selection.Top to Selection.Bottom do
   begin
     ParseKeyValue(StringGrid1.Cells[nKeyName, I]);
     fRegistry.RootKey := RootKey;
     if not fRegistry.OpenKey(Path, FALSE) then
       raise Exception.Create('Error opening registry key '+Path);
     fRegistry.DeleteValue(StringGrid1.Cells[nValueName, I]);
   end;
   { Initiate re-scanning }
   btnStartClick(self);
 end;
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
 var CanSelect: Boolean);
begin
 { Display values in the edit controls
   only when there is any data in the grid }
 if not (fNoSelection) then
 begin
   edKey.Text        := StringGrid1.Cells[nKeyName, Row];
   edTime.Text       := StringGrid1.Cells[nFileTime, Row];
   edValueName.Text  := StringGrid1.Cells[nValueName, Row];
   edValue.Text      := StringGrid1.Cells[nValueString, Row];
 end;
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
 { Set the stop flag, so the registry scanning process can stop }
 fStopFlag := TRUE;
end;
end.
 
2一、这个程序能够得到注册表下的所有值(另一种方法) Var Reg : TRegistry;
   list : TStrings;
   i    : Integer;
Begin
Reg:=TRegistry.Create;
Reg.RootKey:='HKEY_LOCAL_MACHINE';
If Reg.OpenKey('\Software\Microsoft\CurrentVersion\Run', false) then
 Begin
  List:=TStringList.Create;
  Reg.GetValueNames(List);
  For i:=0 to list.Count-1 do
   If Reg.ValueExists(List[i]) then
    Begin
     Case Reg.GetDataType(List[i]) of
      rdInteger: Reg.ReadInteger(List[i]);
      rdBinary: Reg.ReadBinaryData(List[i]);
     else
       Reg.ReadString(List[i]);
     End; 
    End;
 End;
End;
 
另外,ReadBinaryData能够读取二进制键值  
 
  8、Delphi TRegistry 应用举例:
 
一、例一:
 
procedure TForm1.Button1Click(Sender: TObject);
var
  reg:TRegistry;{声明Regstry对象}
  typ:TRegDataType;{注册表数据类型.经常使用的有字符串类型(rdString)、数值类型(rdInteger)、二进制类型(rdBinary)}
  str:string; {用于显示操做信息}
  i:integer; {注册表的数据大小,以字节为单位}
  vv:integer;{注册表的数据内容}
begin
  reg:=TRegistry.Create;{建立注册表对象}
  reg.RootKey :=HKEY_LOCAL_MACHINE;{设置根键}
  reg.OpenKey ('MYSOFT',TRUE);{打开主键}
  typ:=reg.GetDataType('ccc');{获得所需数据的类型}
  i:=reg.GetDataSize('ccc');{获得所需数据的大小}
  case typ of {根据数据类型显示提示信息}
    rdstring:
      str:='This is String Type';
    rdInteger:
      str:='This is Integer Type';
    rdBinary:
      str:='This is Binary Type';
    else
      str:='This is Unknown Type';
  end;
  memo1.Lines.Add(str);
  memo1.lines.Add(inttostr(i));{提示信息结束}
  reg.ReadBinaryData('ccc',vv,i);{读取数据的内容,返回数据内容的大小[本例中未写出返回值]}
  memo1.Lines.add(inttostr(vv));
  vv:=1; {设定数据内容vv=1}
  reg.WriteBinaryData('ccc',vv,i); {把数据内容写入注册表中}
  reg.CloseKey;{关闭主键}
  reg.Free;{释放注册表对象}
end;
 
二、例二:
 
uses registry
var
  reg: TRegistry;
  bData : array[ 0..0 ] of byte;
  DrvPath : string;
begin
  reg := TRegistry.Create;
  reg.RootKey := HKEY_LOCAL_MACHINE;
 
  if reg.OpenKey('SOFTWARE\ODBC\ODBC.INI\'+AODBCName,True) then
  begin
    reg.writestring('Database',   ADataBaseName);
    reg.writestring('Driver',     'sqlsrv32.dll');
    reg.writestring('Server',     ASqlServerName);
    reg.writestring('Description',ADescription);
    reg.writestring('LastUser',   username);
  end;
 
  if  reg.OpenKey('\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources\',false) then
  begin
    reg.writestring(AODBCName,'SQL Server');
    result := True;
  end
  else
    result := false;
  reg.closekey;
  reg.free;
end;
 
三、例三:delphi设置开机自动运行程序
 
uses Registry
{假如你的程序是project1.exe,那么}
procedure TForm1.FormCreate(Sender: TObject);
var
  myReg:TRegistry;
begin
  myReg:=TRegistry.Create;
  myReg.RootKey:=HKEY_LOCAL_MACHINE;
  myReg.OpenKey('SoftWare\Microsoft\Windows\CurrentVersion\Run',True);
  myReg.WriteString('Project',ExtractFilePath(Application.ExeName)+'Project1.exe');
  //myReg.WriteString('Project',Paramstr(0)); //Paramstr(0)函数返回本程序的路径、文件名
  myReg.CloseKey;
  myReg.Free;
end;
 
四、例四:delphi 读写删注册表
 
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls,registry;
type
TForm1 = class(TForm)
  Button1: TButton;
  Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
    { Private declarations }
public
    { Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}

procedure tform1.Button1Click(Sender: TObject);
var
  ARegistry : TRegistry;
begin
  ARegistry := TRegistry.Create; //创建一个TRegistry实例
  with ARegistry do
  begin
    RootKey := HKEY_LOCAL_MACHINE;  //指定根键为HKEY—LOCAL—MACHINE
    //打开主键Software\Microsoft\Windows\CurrentVersion
    if OpenKey('Software\Microsoft\Windows\CurrentVersion',false ) then
    begin
      WriteString('version','1') ;
      form1.memo1.lines.add('Windows版本:'+ ReadString('Version'));
      deletevalue('version');
      WriteString ('VersionNumber','af') ;
      form1.memo1.lines.add('Windows版本号:'+ ReadString('VersionNumber'));
      deletevalue('VersionNumber') ;
      WriteString ('deletevalue','3')   ;
      form1.memo1.lines.add('Windows子版本号:'+ ReadString('SubVersionNumber'));
      deletevalue ('deletevalue');
    end;
    CloseKey;//关闭主键
    Destroy;//释放内存
  end;
end;
end.
 
五、例五:
    Delphi为程序员提供了专门用于操做注册表的类型TRegistry,用它声明一个变量,而后使用这个变量来访问注册表。对于TRegistry类型的变量,有一些重要且经常使用的属性和方法,以下:
 
   属性RootKey:代表当前是对哪个根键进行操做。
   方法OpenKey:打开指定的子键。其格式为function OpenKey(const Key:String; CanCreate:Boolean):Boolean; 参数Key指定要操做的子键,若此子键不存在,返回值False;参数CanCreate用来决定当子键不存在时,是否建立此子键。
   方法ReadString:读取子键的值(字符串型)。其格式为function ReadString(const Name:string):String; 参数Name指定要读的值,读缺省值时采用空串。
   方法WriteString:写子键的值(字符串型)。其格式为procedure WriteString(const Name, Value: String); 参数Name和Value表示值的名称及其数据。
   方法CloseKey:关闭对应的子键。
   经过上面的学习,咱们来看两个具体的例子,以帮助理解。
   (1)在Windows中,多数应用程序都有其相关联的数据文件(如Word与DOC文件,Excel与XLS文件),注册表的 HKEY_CLASSES_ROOT根键的全部子键指明了这种关联关系,咱们能够读取子键的值以找出某种文件类型与哪一个程序相关联。窗体中放置一个文本框 Edit1用于输入文件类型(即扩展名),再放置一按钮Button1,代码以下:
 
uses Registry;  //声明注册表单元
procedure TForm1.Button1Click(Sender: TObject);
var s:string;
  RegF:TRegistry;  //定义变量
begin
  s:='.'+Edit1.text;  //获得扩展名
  RegF:=TRegistry.Create;  //建立变量
  RegF.RootKey:=HKEY_CLASSES_ROOT;  //指定要操做的根键
 
  if RegF.OpenKey(s,False) then  //若是该子键存在
  begin
    s:=RegF.ReadString('');
    RegF.CloseKey;
    s:=s+'\Shell\Open\Command';
    RegF.OpenKey(s,False);
    s:=RegF.ReadString('');  //读取关联信息
    ShowMessage(s);  //显示
  end
  else
    ShowMessage('没有相关信息');
  RegF.CloseKey;  //关闭子键
  RegF.Free;  //释放变量
end;
 
    (2)若是但愿本身的程序在系统启动时自动运行,须要将程序信息加入到注册表中。启动后自动运行程序的信息存放于注册表 HKEY_LOCAL_MACHINE根键的Software\Microsoft\Windows\CurrentVersion\Run子键中。咱们 能够利用WriteString方法写入子键内容来实现此功能,单击Button1后将程序信息加入注册表,代码以下:
 

uses Registry;
procedure TForm1.Button1Click(Sender: TObject);
var RegF:Tregistry;
begin
  RegF:=Tregistry.Create;
  RegF.RootKey:=HKEY_LOCAL_MACHINE;
  if RegF.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',true) then
    RegF.WriteString('MyProgram',Paramstr(0));
  //如子键存在则写入信息,Paramstr(0)函数返回本程序的路径、文件名
  RegF.Free;
end;程序员