delphi 操作登錄檔詳解
一、建立和釋放TRegistry物件
1.建立TRegistry物件。為了操作登錄檔,要建立一個TRegistry物件:ARegistry := TRegistry.Create;
2.釋放TRegistry物件。對登錄檔操作結束後,應釋放TRegistry物件所佔記憶體:ARegistry.Destroy。
二、指定要操作的鍵
操作登錄檔時,首先應指定操作的主鍵:先給屬性RootKey賦值以指定根鍵,然後用方法OpenKey來指定要操作的主鍵名。
1.指定根鍵(RootKey)。
根鍵是登錄檔的入口,也登錄檔資訊的分類,其值可為:
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。
三、從登錄檔中讀取資訊
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。
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;
四、向登錄檔中寫入資訊
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。
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;
五、鍵值維護
除了在登錄檔中讀取、儲存外,程式可能還需要增加主鍵、刪除主鍵、主鍵改名、資料值改名等。
1.建立新主鍵:function CreateKey(const Key: string): Boolean。
Key即為主鍵名,返回值True表示操作成功。
2.刪除主鍵:function DeleteKey(const Key: string): Boolean。
Key即為主鍵名,返回值True表示操作成功。
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下除錯通過。
2003-11-20 11:53:00
發表評語»»»
2003-11-20 11:59:20 登錄檔中對程式設計常用的幾項(ODBC/BDE/Internet/Windows) 我用的是 WINDOWS 2000, WIN2000 的 REGEDIT 提供了類似 IE 中收藏夾的功能,我的收藏夾中有幾個或許對大家程式設計時會有幫助(這是本人在程式設計過程中的探索出來的,請高手指教):
1。關於 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 使用者介面一比較就明白了。
2。關於 INTERNET 程式設計:
HKEY_CLASSES_ROOT\htmlfile
系統對 HTMLFILE 的處理定義;
HKEY_LOCAL_MACHINE\SOFTWARE\Clients
INTERNET Option 中 INTERNET PROGRAM 的設定,尤其重要的是其中的
HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail。
3。關於 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 下還有類似的地方,是針對所有使用者的,我就不羅嗦了。
2003-11-20 12:16:38 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 系統了。
---- 以上程式在PWin98+Delphi3.0 下除錯和通過。
2003-11-20 12:21:25 備份部分登錄檔的程式碼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.
2003-11-20 12:22:54 讀寫網路上其他計算機登錄檔的程式碼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;
2003-11-20 12:27:06 關於檢視登錄檔的程式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.
2003-11-20 13:30:00 獲得登錄檔項下的所有值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;
2003-11-20 13:38:19 利用Windows API 函式和登錄檔獲取系統資訊 在開發應用程式時,增加一項顯示計算機系統資訊的功能,例如已安裝的軟盤、硬碟、光碟機、網路驅動器,硬碟的容量和剩餘空間,顯示器解析度、鍵盤型別、滑鼠的鍵數,記憶體大小、CPU 型別,Windows 的版本號、產品標識、註冊使用者單位名和使用者名稱、當前操作使用者名稱等( 見執行圖示),當然還有更多的資訊,這樣會使你的程式更友好。其實,有很多應用程式就是這樣做的。
通過呼叫Windows 的API 函式和訪問Windows 登錄檔,可以獲取大量的系統資訊。Delphi 為絕大多數Windows API 函式提供了呼叫介面( 可參見DELPHI3\SOURCE\RTL\WIN\windows.pas 檔案),並提供了一個功能全面的TRegistry 類,使我們可以方便的呼叫Windows API 函式和訪問登錄檔,例如:
1、function GetDriveType(lpRootPathName: PChar): UINT; 返回指定驅動器的型別。
2、function GetDiskFreeSpace(lpRootPathName: PChar; var lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; 返回指定驅動器的總簇數、剩餘簇數及每簇扇區數、每扇區位元組數,從而可以計算出總容量和剩
餘空間。
3、function GetSystemMetrics(SM_CXSCREEN或 SM_CYSCREEN): Integer; 返回顯示器解析度。
4、function GetSystemMetrics(SM_CMOUSEBUTTONS): Integer; 返回滑鼠的按鍵數目。
5、在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;
以上僅舉幾例,獲取其他一些資訊的方法與此類似,詳見源程式。
本程式在Pwin95、Delphi3 下除錯通過。
【附】: 源程式清單。
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.
2003-11-20 13:44:20 登錄檔配置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裡的,當然同樣可以寫到當前使用者裡!
2003-11-20 13:50:20 通過登錄檔讀取設定字型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.
2003-11-20 13:56:06 系統登錄檔讀寫操作的例子程式碼 操作登錄檔需要認識到登錄檔的六個根鍵。看看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.
2003-11-20 14:02:11 用登錄檔對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;
2003-11-20 14:06:55 使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一覽無佘的看到,所以千萬不能將一些重要的資訊(如密碼)不經加密而直接寫入登錄檔,這樣做是非常危險的!!
2003-11-20 14:22:10 在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