home *** CD-ROM | disk | FTP | other *** search
- //------------------------------------------------------------------------
- //
- // Registry.prg -- Windows 32 System Registry Class
- //
- // The registry program contains the class definition for the
- // Registry class. Using this class you can read and write
- // values in the Windows 32 registry.
- //
- // Syntax:
- //
- // new Registry(<openKey>, <subKey>);
- //
- // where <openKey> is a numeric value containing the handle to open
- // registry key. This will typically be one of the
- // system keys defined in WINREG.H.
- // <subKey> is a character string containing the name of a
- // subkey of <openKey>.
- //
- // Properties:
- //
- // error - Contains the Windows error number if an error
- // occured during the last registry operation.
- // Contains 0 if no error occured.
- // newlyCreated - Set during instantiation. True if this is a
- // new key, false otherwise.
- //
- // Methods:
- //
- // deleteValue([<name>]) - Delete the named value from the current
- // key. If no name is passed, then the
- // default value for this key is deleted.
- //
- // enumValue() - Returns an array containing the names of each
- // value contained in the current key.
- //
- // queryKeyName() - Returns the name of the current registry key.
- //
- // queryValue(<name>) - Returns the value associated with <name>. The
- // <name> parameter is required, but may be blank.
- // If blank the default value for the key is
- // returned.
- //
- // setValue(<name>,<value>[,<type>])
- // - Sets the value of <name> to <value>. Both
- // parameters are required, but <name> may be
- // blank to set the default value for the key.
- // Returns a logical true or false to indicate
- // success or failure, respectively. If no type
- // is indicated, the value is saved. The types
- // are defined in WINREG.H.
- //
- // Example: Using the Registry class to set the DBASE table
- // creation level to 7
- //
- /*
- #include <winreg.h>
- #define BDE_REG_KEY "SOFTWARE\Borland\Database Engine"
- SET PROCEDURE TO "registry.prg" ADDITIVE
-
- reg = new Registry(HKEY_LOCAL_MACHINE, ;
- BDE_REG_KEY + ;
- "\Settings\DRIVERS\DBASE\TABLE CREATE" )
- dbfLevel = reg.queryValue("LEVEL")
-
- if ( reg.error == 0 )
- if ( dbfLevel <> "7" )
- if (reg.setValue("LEVEL","7"))
- MSGBOX("dBASE table level set to 7.")
- endif
- endif
- else
- MSGBOX("Error reading registry.")
- endif
- */
- //
- //
- // Visual dBASE Samples Group
- // $Revision: 1.6 $
- //
- // Copyright (c) 1997, Borland International, Inc. All rights reserved.
- //
- //------------------------------------------------------------------------
- //
- //
- // These next two lines are used for debugging purposes. To trace the
- // results of the API calls, uncomment the #define DEBUG line. The
- // results are written to the Command window.
- //
- //#define DEBUG
-
- // Define Windows data types for use by the extern command
- #include <windef.h>
- #include <winreg.h>
-
- class Registry(openKey, subKey)
- this.openKey = openKey
- this.subKey = subKey
- this.key = 0
- this.isOpen = false
- this.error = 0
- this.newlyCreated = false
-
- class::prototype()
-
- local nKey, nDisposition, nResult
- nKey = 0
- nDisposition = -1
- nResult = RegCreateKeyEx( this.openKey, this.subKey, 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, nKey, nDisposition )
-
- #ifdef DEBUG
- ? "constructor - " + nResult
- ? "disposition - " + nDisposition
- #endif
-
- // store the handle to this key
- this.key := nKey
- // registry keys should not be held open. If we got a key open
- // close it for now.
- if (nResult == ERROR_SUCCESS)
- if (nDisposition == REG_CREATED_NEW_KEY)
- this.newlyCreated := true
- endif
-
- #ifdef DEBUG
- ? "created - " + this.newlyCreated
- #endif
-
- this.close()
- else
- this.error := nResult
- endif
-
- function close
- this.isOpen := false
- local nResult
- nResult = RegCloseKey( this.key )
-
- #ifdef DEBUG
- ? "close - " + nResult
- #endif
-
- return (nResult)
-
- function deleteValue(keyName)
- local bReturn, nResult
- bReturn = false
- nResult = 0
-
- // reset the error property
- this.error := 0
-
- // open up the key
- this.open()
-
- if (this.isOpen)
- bReturn := true
- // if one parameter is passed, delete that value
- if (deleteValue.arguments.length == 1)
- nResult := RegDeleteValue(this.key, keyName)
- // if no parameter is passed, delete default value
- else
- nResult := RegDeleteValue(this.key, "")
- endif
-
- #ifdef DEBUG
- ? "delete - " + nResult
- #endif
-
- this.close()
- endif
- return (bReturn)
-
- function enumValue
- local aReturn, nResult, nCount, sValue, nLen, string80
-
- aReturn = new Array()
- nResult = ERROR_SUCCESS
- nCount = 0
- sValue = ""
- nLen = 0
- string80 = REPLICATE(" ", 80)
-
- // reset the error property
- this.error := 0
-
- // open up the key
- this.open()
-
- if (this.isOpen)
- do while (nResult == ERROR_SUCCESS)
- sValue := string80
- nLen := sValue.length
- nResult := RegEnumValue(this.key, nCount, sValue, ;
- nLen, 0, 0, 0, 0)
-
- #ifdef DEBUG
- ? "enum - " + nCount + " - " + nResult
- #endif
-
- if ( nResult == ERROR_SUCCESS )
- aReturn.add( SUBSTR( sValue, 0, nLen) )
- else
- if (nResult <> ERROR_NO_MORE_ITEMS )
- this.error := nResult
- endif
- endif
- nCount ++
- enddo
- this.close()
- endif
- return (aReturn)
-
- function open
- local nResult, nReturn
- nReturn = 0 // handle of new key
- nResult = RegOpenKeyEx( this.openKey, this.subKey, 0, ;
- KEY_ALL_ACCESS, nReturn)
-
- #ifdef DEBUG
- ? "open - " + nResult
- #endif
-
- if (nResult == ERROR_SUCCESS)
- this.key = nReturn
- this.isOpen = true
- else
- this.error = (nResult)
- endif
- return (nReturn)
-
- function prototype
- local bAsian
- bAsian = false
- extern CLONG RegCloseKey( HKEY ) ADVAPI32
- extern CLONG RegCreateKeyEx( HKEY, LPCTSTR, DWORD, LPTSTR, DWORD, ;
- REGSAM, LPSTRUCTURE, PHKEY, LPDWORD ) ADVAPI32 ;
- from "RegCreateKeyExA"
- extern CLONG RegDeleteValue( HKEY, LPTSTR ) ADVAPI32 ;
- from "RegDeleteValueA"
- extern CLONG RegEnumValue( HKEY, DWORD, LPTSTR, LPDWORD, DWORD, ;
- LPDWORD, LPBYTE, LPDWORD) ADVAPI32 from "RegEnumValueA"
- extern CLONG RegOpenKeyEx( HKEY, LPCTSTR, DWORD, REGSAM, PHKEY ) ;
- ADVAPI32 from "RegOpenKeyExA"
- extern CLONG RegQueryValueEx( HKEY, LPTSTR, DWORD, LPDWORD, CSTRING, ;
- LPDWORD ) ADVAPI32 from "RegQueryValueExA"
- extern CLONG RegSetValueEx( HKEY, LPCTSTR, DWORD, DWORD, CSTRING, DWORD ) ;
- ADVAPI32 from "RegSetValueExA"
- #ifdef __asian__
- extern CLONG RegQueryValueExChar( HKEY, LPTSTR, DWORD, LPDWORD, CSTRING, ;
- LPDWORD ) ADVAPI32 from "RegQueryValueExA"
- extern CLONG RegSetValueExChar( HKEY, LPCTSTR, DWORD, DWORD, CSTRING, DWORD ) ;
- ADVAPI32 from "RegSetValueExA"
- bAsian := true
- #endif
-
- return (bAsian)
-
- function queryKeyName
- local keyName
- keyName = ""
-
- do case
- case ( this.openKey == HKEY_CLASSES_ROOT )
- keyName := "HKEY_CLASSES_ROOT\\"
- case ( this.openKey == HKEY_CURRENT_USER )
- keyName := "HKEY_CURRENT_USER\\"
- case ( this.openKey == HKEY_LOCAL_MACHINE )
- keyName := "HKEY_LOCAL_MACHINE\\"
- case ( this.openKey == HKEY_USERS )
- keyName := "HKEY_USERS\\"
- case ( this.openKey == HKEY_PERFORMANCE_DATA )
- keyName := "HKEY_PERFORMANCE_DATA\\"
- case ( this.openKey == HKEY_CURRENT_CONFIG )
- keyName := "HKEY_CURRENT_CONFIG\\"
- case ( this.openKey == HKEY_DYN_DATA )
- keyName := "HKEY_DYN_DATA\\"
- otherwise
- keyName := "UNKNOWN_KEY\\"
- endcase
-
- return (keyName + this.subKey)
-
- function queryValue(keyName)
- local nResult, nType, nLen, keyValue
- local strEx, cData
- nResult = 0
- nType = 0
- nLen = 80
- keyValue = false
-
- strEx = ""
- cData = REPLICATE(" ", 80)
-
- // reset the error property
- this.error := 0
-
- // open up the key
- this.open()
-
- if (this.isOpen)
- // query the value
- nResult := RegQueryValueEx(this.key, keyName, 0, ;
- nType, cData, nLen)
-
- #ifdef DEBUG
- ? "query - " + nResult
- #endif
-
- // ERROR_MORE_DATA means we need to pass a larger cData
- if (nResult == ERROR_MORE_DATA)
- cData := REPLICATE(" ", nLen)
- nResult := RegQueryValueEx(this.key, keyName, 0, ;
- nType, cData, nLen)
-
- #ifdef DEBUG
- ? "requery - " + nResult
- #endif
-
- endif
-
- #ifdef __asian__
- // The Asian version uses Unicode strings. Call RegQueryValueExChar, which
- // is prototyped to char*, which converts the string to multi-byte.
- if ( nResult == ERROR_SUCCESS AND nType == REG_SZ )
- cData := REPLICATE(" ", nLen)
- nResult := RegQueryValueExChar(this.key, keyName, 0, nType, cData, nLen);
-
- #ifdef DEBUG
- ? "UNICODE requery - " + nResult
- #endif
-
- endif
- #endif
-
- strEx := cData
- if (nResult == ERROR_SUCCESS)
- if (nType == REG_DWORD)
- keyValue := strEx.asc(strEx.substring(0, 1)) * ( 256 ^ 0 ) + ;
- strEx.asc(strEx.substring(1, 2)) * ( 256 ^ 1 ) + ;
- strEx.asc(strEx.substring(2, 3)) * ( 256 ^ 2 ) + ;
- strEx.asc(strEx.substring(3, 4)) * ( 256 ^ 3 )
- else
- keyValue := SUBSTR(strEx, 1, nLen - 1 )
- endif
- else
- this.error := nResult
- endif
- this.close()
- endif
- return (keyValue)
-
- function setValue( valueName, value, type )
- local bReturn, nType, xValue, nAtNull, nLen, nResult
- private typeVal
- bReturn = false
- nType = IIF( PCOUNT() == 3, type, REG_SZ )
- typeVal = value
- xValue = value
- nAtNull = 0
- nLen = 0
- nResult = 0
-
- // reset the error property
- this.error := 0
-
- // open the key
- this.open()
-
- if (this.isOpen)
- // reformat data if necessary
- if (nType == REG_DWORD)
- if TYPE("typeVal") == "C"
- xValue := VAL(value)
- endif
- xValue := CHR( INT( xValue / ( 256 ^ 0 ) ) % 256) + ;
- CHR( INT( xValue / ( 256 ^ 1 ) ) % 256) + ;
- CHR( INT( xValue / ( 256 ^ 2 ) ) % 256) + ;
- CHR( INT( xValue / ( 256 ^ 3 ) ) % 256)
- else
- xValue := value + "" // force to string type
- nAtNull := AT( CHR(0), xValue )
- if ( nAtNull > 0 )
- xValue := SUBSTR( xValue, 1, nAtNull + 1 )
- else
- xValue := xValue + CHR(0)
- endif
- endif
-
- // Write the data to the registry
- nLen := LEN( xValue )
- #ifdef __asian__
- if (nType == REG_SZ)
- nResult := RegSetValueExChar(this.key, valueName, ;
- 0, nType, xValue, nLen)
- else
- #endif
- nResult := RegSetValueEx(this.key, valueName, ;
- 0, nType, xValue, nLen)
- #ifdef __asian__
- endif
- #endif
-
- #ifdef DEBUG
- ? "setvalue - " + nResult
- #endif
-
- if (nResult == ERROR_SUCCESS)
- bReturn := true
- else
- this.error = (lnResult)
- endif
- this.close()
- endif
- return (bReturn)
- endclass
-