注冊表是Windows操作系統(tǒng)中保存系統(tǒng)的硬件信息、應用程序信息和用戶信息的一個數(shù)據庫,它為應用程序提供了保存參數(shù)設置的場所。
在Windows操作系統(tǒng)中,當我們運行“RegEdit.exe”文件,從打開的注冊表編輯窗口中可以看出,注冊表由左右兩個部分組成: 左側各項目的第一層稱為注冊表的主鍵,雙擊各主鍵時延伸出的各鍵稱之為子鍵;窗口的右側是各子鍵的鍵值,每一個子鍵都有其相應的默認值和用不同的鍵值名表示的鍵值(其中默認值的鍵值名為一空串)。
在VFP應用程序中讀寫注冊表數(shù)據需借助WIN32API(即Windows 32位應用程序接口)函數(shù),為了像使用其它VFP函數(shù)一樣調用WIN32API函數(shù),必須先用DECLARE命令對每一個被調用函數(shù)進行注冊(聲明),其格式為DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName] ;
[cParamType1 [@] ParamName1,cParamType2 [@] ParamName2, ...]
其中各參數(shù)的意義為:①cFunctionType為函數(shù)的返回值類型,可是SHORT、INTEGER或LONG、SINGLE、DOUBLE、STRING之一,如果函數(shù)沒有返回值,則省略cFunctionType;②FunctionName指出被調用WIN32API函數(shù)名,請注意大小寫,否則VFP將在.DLL庫(LibraryName)中搜索不到該函數(shù)而出錯, 如果該函數(shù)名與VFP的函數(shù)同名,可用AS子句另取一個合法的VFP函數(shù)名;③LibraryName指定外部Windows .DLL的名稱,如取WIN32API,則VFP就在KERNEL32.DLL, GDI32.DLL, USER32.DLL, MPR.DLL和ADVAPI32.DLL中搜索FunctionName;④cParamType指定各參數(shù)的類型,可為INTEGER或LONG、SINGLE、DOUBLE、STRING之一,在VFP中向函數(shù)傳遞參數(shù)的方式有兩種:按值傳遞和按名(引用)傳遞,前者只把變量(也可為常數(shù))的值傳給函數(shù),因而在函數(shù)內部不能修改該變量的值;后者是把變量(不能用常數(shù))的地址傳給函數(shù),因而在函數(shù)內部可修改該變量的值,適用于需要在函數(shù)內部修改該變量的值或在變量中放置返回值的情況。VFP中如在變量名前加“@”表示按引用傳遞參數(shù),不加“@”表示按值傳遞參數(shù)。至于本示例程序中各參數(shù)是按引用傳遞還是按值傳遞,從DECLARE命令和函數(shù)調用語句中一看便知。
下面的示例程序每運行一次,就將注冊表中HKEY_CURRENT_USER\SOFTWARE\LYTAPP子鍵的TimesForUse名下的值加1,直到運行12次為止:
* 各主鍵與一個整數(shù)(INTEGER)值相對應,即:
#DEFINE HKEY_CLASSES_ROOT bitset(0,31) &&-2147483648
#DEFINE HKEY_CURRENT_USER bitset(0,31)+1 &&-2147483647
#DEFINE HKEY_LOCAL_MACHINE bitset(0,31)+2 &&-2147483646
#DEFINE HKEY_USER bitset(0,31)+3 &&-2147483645
#DEFINE HKEY_CURRENT_CONFIG bitset(0,31)+5 &&-2147483643
#DEFINE HKEY_DYN_DATA bitset(0,31)+6 &&-2147483642
* 鍵值的數(shù)據類型:1-字符串,3-二進制,4-整數(shù)
#DEFINE REG_SZ 1
#DEFINE REG_BINARY 3
#DEFINE REG_DWORD 4
* 當以下API函數(shù)返回0時,操作成功。
DECLARE Integer RegOpenKey IN Win32API ;
Integer nHKey, String @cSubKey, Integer @nResult
DECLARE Integer RegCreateKey IN Win32API ;
Integer nHKey, String @cSubKey, Integer @nResult
DECLARE Integer RegSetValueEx IN Win32API ;
Integer hKey, String lpszValueName, Integer dwReserved,;
Integer fdwType, String lpbData, Integer cbData
DECLARE Integer RegQueryValueEx IN Win32API ;
Integer nHKey, String lpszValueName, Integer dwReserved,;
Integer @lpdwType,string @lpbData, Integer @lpcbData
* DECLARE Integer RegDeleteKey IN Win32API ;
* Integer nHKey, String @cSubKey
* DECLARE Integer RegDeleteValue IN Win32API ;
* Integer nHKey, String cSubKey
* DECLARE Integer RegCloseKey IN Win32API ;
* Integer nHKey
csubkey='Software\lytapp'
nresult=0
if regopenkey(HKEY_CURRENT_USER,@csubkey,@nresult)#0
RegCreateKey(HKEY_CURRENT_USER,csubkey,@nresult)
endif
* 在nresult中存放了指向子鍵“HKEY_CURRENT_USER\Software\lytapp”的長整數(shù)值
lpdwtype=0
lpbdata=space(256)
lpcbdata=len(lpbdata)
if RegQueryValueEx(nresult,'TimesForUse',0,@lpdwtype,@lpbdata,@lpcbdata)=0
do case
case lpdwtype=REG_SZ
lpbdata=left(lpbdata,lpcbdata-1)
if val(lpbdata)<12
lpbdata=alltrim(str(val(lpbdata)+1))
messagebox('本程序在未注冊之前只能使用12次!'+CHR(13)+' 您現(xiàn)在是第'+ ;
lpbdata+'次使用本程序。')
lpbdata=lpbdata+chr(0)
cbdata=len(lpbdata)
RegSetValueEx(nresult,'TimesForUse',0,REG_SZ,lpbdata,cbdata)
else
messagebox(" 程序已過期作廢!"+CHR(13)+" 請與作者聯(lián)系注冊事宜。")
endif
case lpdwtype=REG_BINARY
messagebox('該鍵值為二進制數(shù)據。')
case lpdwtype=REG_DWORD
messagebox('該鍵值為長整數(shù)數(shù)據,請用 NN=0'+CHR(13)+'for i=1 to 4'+CHR(13)+ ;
'NN=NN+VAL(SUBSTR(lpbdata,i,1)*16^(2*i-2)'+CHR(13)+ ;
'endfor 讀取此數(shù)值。')
otherwise
messagebox('未知數(shù)據!')
endcase
else
lpbdata='1'
messagebox('本程序在未注冊之前只能使用12次!'+CHR(13)+' 您現(xiàn)在是第'+lpbdata+'次使用本程序。')
lpbdata=lpbdata+chr(0)
RegSetValueEx(nresult,'TimesForUse',0,REG_SZ,lpbdata,2)
endif
* 警告:當用戶不熟悉注冊表時不要修改其中的內容,否則,可能造成系統(tǒng)的崩潰。若用戶想對注冊表修改,建議修改前將注冊表備份。
在Windows操作系統(tǒng)中,當我們運行“RegEdit.exe”文件,從打開的注冊表編輯窗口中可以看出,注冊表由左右兩個部分組成: 左側各項目的第一層稱為注冊表的主鍵,雙擊各主鍵時延伸出的各鍵稱之為子鍵;窗口的右側是各子鍵的鍵值,每一個子鍵都有其相應的默認值和用不同的鍵值名表示的鍵值(其中默認值的鍵值名為一空串)。
在VFP應用程序中讀寫注冊表數(shù)據需借助WIN32API(即Windows 32位應用程序接口)函數(shù),為了像使用其它VFP函數(shù)一樣調用WIN32API函數(shù),必須先用DECLARE命令對每一個被調用函數(shù)進行注冊(聲明),其格式為DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName] ;
[cParamType1 [@] ParamName1,cParamType2 [@] ParamName2, ...]
其中各參數(shù)的意義為:①cFunctionType為函數(shù)的返回值類型,可是SHORT、INTEGER或LONG、SINGLE、DOUBLE、STRING之一,如果函數(shù)沒有返回值,則省略cFunctionType;②FunctionName指出被調用WIN32API函數(shù)名,請注意大小寫,否則VFP將在.DLL庫(LibraryName)中搜索不到該函數(shù)而出錯, 如果該函數(shù)名與VFP的函數(shù)同名,可用AS子句另取一個合法的VFP函數(shù)名;③LibraryName指定外部Windows .DLL的名稱,如取WIN32API,則VFP就在KERNEL32.DLL, GDI32.DLL, USER32.DLL, MPR.DLL和ADVAPI32.DLL中搜索FunctionName;④cParamType指定各參數(shù)的類型,可為INTEGER或LONG、SINGLE、DOUBLE、STRING之一,在VFP中向函數(shù)傳遞參數(shù)的方式有兩種:按值傳遞和按名(引用)傳遞,前者只把變量(也可為常數(shù))的值傳給函數(shù),因而在函數(shù)內部不能修改該變量的值;后者是把變量(不能用常數(shù))的地址傳給函數(shù),因而在函數(shù)內部可修改該變量的值,適用于需要在函數(shù)內部修改該變量的值或在變量中放置返回值的情況。VFP中如在變量名前加“@”表示按引用傳遞參數(shù),不加“@”表示按值傳遞參數(shù)。至于本示例程序中各參數(shù)是按引用傳遞還是按值傳遞,從DECLARE命令和函數(shù)調用語句中一看便知。
下面的示例程序每運行一次,就將注冊表中HKEY_CURRENT_USER\SOFTWARE\LYTAPP子鍵的TimesForUse名下的值加1,直到運行12次為止:
* 各主鍵與一個整數(shù)(INTEGER)值相對應,即:
#DEFINE HKEY_CLASSES_ROOT bitset(0,31) &&-2147483648
#DEFINE HKEY_CURRENT_USER bitset(0,31)+1 &&-2147483647
#DEFINE HKEY_LOCAL_MACHINE bitset(0,31)+2 &&-2147483646
#DEFINE HKEY_USER bitset(0,31)+3 &&-2147483645
#DEFINE HKEY_CURRENT_CONFIG bitset(0,31)+5 &&-2147483643
#DEFINE HKEY_DYN_DATA bitset(0,31)+6 &&-2147483642
* 鍵值的數(shù)據類型:1-字符串,3-二進制,4-整數(shù)
#DEFINE REG_SZ 1
#DEFINE REG_BINARY 3
#DEFINE REG_DWORD 4
* 當以下API函數(shù)返回0時,操作成功。
DECLARE Integer RegOpenKey IN Win32API ;
Integer nHKey, String @cSubKey, Integer @nResult
DECLARE Integer RegCreateKey IN Win32API ;
Integer nHKey, String @cSubKey, Integer @nResult
DECLARE Integer RegSetValueEx IN Win32API ;
Integer hKey, String lpszValueName, Integer dwReserved,;
Integer fdwType, String lpbData, Integer cbData
DECLARE Integer RegQueryValueEx IN Win32API ;
Integer nHKey, String lpszValueName, Integer dwReserved,;
Integer @lpdwType,string @lpbData, Integer @lpcbData
* DECLARE Integer RegDeleteKey IN Win32API ;
* Integer nHKey, String @cSubKey
* DECLARE Integer RegDeleteValue IN Win32API ;
* Integer nHKey, String cSubKey
* DECLARE Integer RegCloseKey IN Win32API ;
* Integer nHKey
csubkey='Software\lytapp'
nresult=0
if regopenkey(HKEY_CURRENT_USER,@csubkey,@nresult)#0
RegCreateKey(HKEY_CURRENT_USER,csubkey,@nresult)
endif
* 在nresult中存放了指向子鍵“HKEY_CURRENT_USER\Software\lytapp”的長整數(shù)值
lpdwtype=0
lpbdata=space(256)
lpcbdata=len(lpbdata)
if RegQueryValueEx(nresult,'TimesForUse',0,@lpdwtype,@lpbdata,@lpcbdata)=0
do case
case lpdwtype=REG_SZ
lpbdata=left(lpbdata,lpcbdata-1)
if val(lpbdata)<12
lpbdata=alltrim(str(val(lpbdata)+1))
messagebox('本程序在未注冊之前只能使用12次!'+CHR(13)+' 您現(xiàn)在是第'+ ;
lpbdata+'次使用本程序。')
lpbdata=lpbdata+chr(0)
cbdata=len(lpbdata)
RegSetValueEx(nresult,'TimesForUse',0,REG_SZ,lpbdata,cbdata)
else
messagebox(" 程序已過期作廢!"+CHR(13)+" 請與作者聯(lián)系注冊事宜。")
endif
case lpdwtype=REG_BINARY
messagebox('該鍵值為二進制數(shù)據。')
case lpdwtype=REG_DWORD
messagebox('該鍵值為長整數(shù)數(shù)據,請用 NN=0'+CHR(13)+'for i=1 to 4'+CHR(13)+ ;
'NN=NN+VAL(SUBSTR(lpbdata,i,1)*16^(2*i-2)'+CHR(13)+ ;
'endfor 讀取此數(shù)值。')
otherwise
messagebox('未知數(shù)據!')
endcase
else
lpbdata='1'
messagebox('本程序在未注冊之前只能使用12次!'+CHR(13)+' 您現(xiàn)在是第'+lpbdata+'次使用本程序。')
lpbdata=lpbdata+chr(0)
RegSetValueEx(nresult,'TimesForUse',0,REG_SZ,lpbdata,2)
endif
* 警告:當用戶不熟悉注冊表時不要修改其中的內容,否則,可能造成系統(tǒng)的崩潰。若用戶想對注冊表修改,建議修改前將注冊表備份。

