home *** CD-ROM | disk | FTP | other *** search
/ Total C++ 2 / TOTALCTWO.iso / vfp5.0 / vfp / samples / classes / registry.prg < prev    next >
Text File  |  1996-08-21  |  23KB  |  862 lines

  1. * Copyright (c) 1995,1996 Sierra Systems, Microsoft Corporation
  2. *
  3. * Written by Randy Brown
  4. * Contributions from Matt Oshry, Calvin Hsia
  5. *
  6. * The Registry class provides a complete library of API
  7. * calls to access the Windows Registry. Support is provided
  8. * for Windows 32S, Windows NT amd Windows 95. Included for
  9. * backward compatibility with older applications which still
  10. * use INI files are several routines which access INI sections
  11. * and details. Finally, several valuable routines are included
  12. * for accessing ODBC drivers and data sources.
  13. *
  14.  
  15.  
  16. * Operating System codes
  17. #DEFINE    OS_W32S                1
  18. #DEFINE    OS_NT                2
  19. #DEFINE    OS_WIN95            3
  20. #DEFINE    OS_MAC                4
  21. #DEFINE    OS_DOS                5
  22. #DEFINE    OS_UNIX                6
  23.  
  24. * DLL Paths for various operating systems
  25. #DEFINE DLLPATH_32S            "\SYSTEM\"        &&used for ODBC only
  26. #DEFINE DLLPATH_NT            "\SYSTEM32\"
  27. #DEFINE DLLPATH_WIN95        "\SYSTEM\"
  28.  
  29. * DLL files used to read INI files
  30. #DEFINE    DLL_KERNEL_W32S        "W32SCOMB.DLL"
  31. #DEFINE    DLL_KERNEL_NT        "KERNEL32.DLL"
  32. #DEFINE    DLL_KERNEL_WIN95    "KERNEL32.DLL"
  33.  
  34. * DLL files used to read registry
  35. #DEFINE    DLL_ADVAPI_W32S        "W32SCOMB.DLL"
  36. #DEFINE    DLL_ADVAPI_NT        "ADVAPI32.DLL"
  37. #DEFINE    DLL_ADVAPI_WIN95    "ADVAPI32.DLL"
  38.  
  39. * DLL files used to read ODBC info
  40. #DEFINE DLL_ODBC_W32S        "ODBC32.DLL"
  41. #DEFINE DLL_ODBC_NT            "ODBC32.DLL"
  42. #DEFINE DLL_ODBC_WIN95        "ODBC32.DLL"
  43.  
  44. * Registry roots
  45. #DEFINE HKEY_CLASSES_ROOT           -2147483648  && BITSET(0,31)
  46. #DEFINE HKEY_CURRENT_USER           -2147483647  && BITSET(0,31)+1
  47. #DEFINE HKEY_LOCAL_MACHINE          -2147483646  && BITSET(0,31)+2
  48. #DEFINE HKEY_USERS                  -2147483645  && BITSET(0,31)+3
  49.  
  50. * Misc
  51. #DEFINE APP_PATH_KEY        "\Shell\Open\Command"
  52. #DEFINE OLE_PATH_KEY        "\Protocol\StdFileEditing\Server"
  53. #DEFINE VFP_OPTIONS_KEY        "Software\Microsoft\VisualFoxPro\5.0\Options"
  54. #DEFINE VFP_OPT32S_KEY        "VisualFoxPro\5.0\Options"
  55. #DEFINE CURVER_KEY            "\CurVer"
  56. #DEFINE ODBC_DATA_KEY        "Software\ODBC\ODBC.INI\"
  57. #DEFINE ODBC_DRVRS_KEY        "Software\ODBC\ODBCINST.INI\"
  58. #DEFINE SQL_FETCH_NEXT        1
  59. #DEFINE SQL_NO_DATA            100
  60.  
  61. * Error Codes
  62. #DEFINE ERROR_SUCCESS        0    && OK
  63. #DEFINE ERROR_EOF             259 && no more entries in key
  64.  
  65. * Note these next error codes are specific to this Class, not DLL
  66. #DEFINE ERROR_NOAPIFILE        -101    && DLL file to check registry not found
  67. #DEFINE ERROR_KEYNOREG        -102    && key not registered
  68. #DEFINE ERROR_BADPARM        -103    && bad parameter passed
  69. #DEFINE ERROR_NOENTRY        -104    && entry not found
  70. #DEFINE    ERROR_BADKEY        -105    && bad key passed
  71. #DEFINE    ERROR_NONSTR_DATA    -106    && data type for value is not a data string
  72. #DEFINE ERROR_BADPLAT        -107    && platform not supported
  73. #DEFINE ERROR_NOINIFILE        -108    && DLL file to check INI not found
  74. #DEFINE ERROR_NOINIENTRY    -109    && No entry in INI file
  75. #DEFINE ERROR_FAILINI        -110    && failed to get INI entry
  76. #DEFINE ERROR_NOPLAT        -111    && call not supported on this platform
  77. #DEFINE ERROR_NOODBCFILE    -112    && DLL file to check ODBC not found
  78. #DEFINE ERROR_ODBCFAIL        -113    && failed to get ODBC environment
  79.  
  80. * Data types for keys
  81. #DEFINE REG_SZ                 1    && Data string
  82. #DEFINE REG_BINARY             3    && Binary data in any form.
  83. #DEFINE REG_DWORD             4    && A 32-bit number.
  84.  
  85. * Data types labels
  86. #DEFINE REG_BINARY_LOC        "*Binary*"            && Binary data in any form.
  87. #DEFINE REG_DWORD_LOC         "*Dword*"            && A 32-bit number.
  88. #DEFINE REG_UNKNOWN_LOC        "*Unknown type*"    && unknown type
  89.  
  90. * FoxPro ODBC drivers
  91. #DEFINE FOXODBC_25            "FoxPro Files (*.dbf)"
  92. #DEFINE FOXODBC_26            "Microsoft FoxPro Driver (*.dbf)"
  93. #DEFINE FOXODBC_30            "Microsoft Visual FoxPro Driver"
  94.  
  95.  
  96. DEFINE CLASS registry AS custom
  97.  
  98.     nUserKey = HKEY_CURRENT_USER
  99.     cVFPOptPath = VFP_OPTIONS_KEY
  100.     cRegDLLFile = ""
  101.     cINIDLLFile = ""
  102.     cODBCDLLFile = ""
  103.     nCurrentOS = 0
  104.     nCurrentKey = 0
  105.     lLoadedDLLs = .F. 
  106.     lLoadedINIs = .F.
  107.     lLoadedODBCs = .F.
  108.     cAppPathKey = ""
  109.     lCreateKey = .F.
  110.     lhaderror = .f.
  111.     
  112.     PROCEDURE Init
  113.         DO CASE
  114.         CASE _DOS OR _UNIX OR _MAC
  115.             RETURN .F.
  116.         CASE ATC("Windows 3",OS(1)) # 0
  117.             THIS.nCurrentOS = OS_W32S
  118.             THIS.cRegDLLFile = DLL_ADVAPI_W32S
  119.             THIS.cINIDLLFile = DLL_KERNEL_W32S
  120.             THIS.cODBCDLLFile = DLL_ODBC_W32S
  121.             THIS.cVFPOptPath = VFP_OPT32S_KEY
  122.             THIS.nUserKey = HKEY_CLASSES_ROOT    
  123.         CASE ATC("Windows NT",OS(1)) # 0
  124.             THIS.nCurrentOS = OS_NT
  125.             THIS.cRegDLLFile = DLL_ADVAPI_NT
  126.             THIS.cINIDLLFile = DLL_KERNEL_NT    
  127.             THIS.cODBCDLLFile = DLL_ODBC_NT
  128.         OTHERWISE
  129.             * Windows 95
  130.             THIS.nCurrentOS = OS_WIN95
  131.             THIS.cRegDLLFile = DLL_ADVAPI_WIN95
  132.             THIS.cINIDLLFile = DLL_KERNEL_WIN95
  133.             THIS.cODBCDLLFile = DLL_ODBC_WIN95
  134.         ENDCASE
  135.     ENDPROC
  136.     
  137.     PROCEDURE Error
  138.         LPARAMETERS nError, cMethod, nLine
  139.         THIS.lhaderror = .T.
  140.         =MESSAGEBOX(MESSAGE())
  141.     ENDPROC
  142.  
  143.     PROCEDURE LoadRegFuncs
  144.         * Loads funtions needed for Registry
  145.         LOCAL nHKey,cSubKey,nResult
  146.         LOCAL hKey,iValue,lpszValue,lpcchValue,lpdwType,lpbData,lpcbData
  147.         LOCAL lpcStr,lpszVal,nLen,lpdwReserved
  148.         LOCAL lpszValueName,dwReserved,fdwType
  149.         LOCAL iSubKey,lpszName,cchName
  150.  
  151.         IF THIS.lLoadedDLLs
  152.             RETURN ERROR_SUCCESS
  153.         ENDIF
  154.         
  155.         DECLARE Integer RegOpenKey IN Win32API ;
  156.             Integer nHKey, String @cSubKey, Integer @nResult
  157.  
  158.         IF THIS.lhaderror && error loading library
  159.             RETURN -1
  160.         ENDIF
  161.  
  162.         DECLARE Integer RegCreateKey IN Win32API ;
  163.             Integer nHKey, String @cSubKey, Integer @nResult
  164.  
  165.         DECLARE Integer RegDeleteKey IN Win32API ;
  166.             Integer nHKey, String @cSubKey
  167.  
  168.         DECLARE Integer RegDeleteValue IN Win32API ;
  169.             Integer nHKey, String cSubKey
  170.  
  171.         DECLARE Integer RegCloseKey IN Win32API ;
  172.             Integer nHKey
  173.  
  174.         DECLARE Integer RegSetValueEx IN Win32API ;
  175.             Integer hKey, String lpszValueName, Integer dwReserved,;
  176.             Integer fdwType, String lpbData, Integer cbData
  177.  
  178.         DECLARE Integer RegQueryValueEx IN Win32API ;
  179.             Integer nHKey, String lpszValueName, Integer dwReserved,;
  180.             Integer @lpdwType, String @lpbData, Integer @lpcbData
  181.  
  182.         DECLARE Integer RegEnumKey IN Win32API ;
  183.             Integer nHKey,Integer iSubKey, String @lpszName, Integer @cchName
  184.  
  185.         DECLARE Integer RegEnumKeyEx IN Win32API ;
  186.             Integer nHKey,Integer iSubKey, String @lpszName, Integer @cchName,;
  187.             Integer dwReserved,String @lpszName, Integer @cchName,String @cchName
  188.  
  189.         DECLARE Integer RegEnumValue IN Win32API ;
  190.             Integer hKey, Integer iValue, String @lpszValue, ;
  191.             Integer @lpcchValue, Integer lpdwReserved, Integer @lpdwType, ;
  192.             String @lpbData, Integer @lpcbData
  193.                     
  194.         THIS.lLoadedDLLs = .T.
  195.         
  196.         * Need error check here
  197.         RETURN ERROR_SUCCESS
  198.     ENDPROC
  199.     
  200.     PROCEDURE OpenKey
  201.         * Opens a registry key
  202.         LPARAMETER cLookUpKey,nRegKey,lCreateKey
  203.         
  204.         LOCAL nSubKey,nErrCode,nPCount,lSaveCreateKey
  205.         nSubKey = 0
  206.         nPCount = PARAMETERS()
  207.         
  208.         IF TYPE("m.nRegKey") # "N" OR EMPTY(m.nRegKey)
  209.             m.nRegKey = HKEY_CLASSES_ROOT
  210.         ENDIF
  211.         
  212.         * Load API functions
  213.         nErrCode = THIS.LoadRegFuncs()
  214.         IF m.nErrCode # ERROR_SUCCESS
  215.             RETURN m.nErrCode
  216.         ENDIF
  217.  
  218.         lSaveCreateKey = THIS.lCreateKey
  219.         IF m.nPCount>2 AND TYPE("m.lCreateKey") = "L"
  220.             THIS.lCreateKey = m.lCreateKey
  221.         ENDIF
  222.  
  223.         IF THIS.lCreateKey
  224.             * Try to open or create registry key
  225.             nErrCode = RegCreateKey(m.nRegKey,m.cLookUpKey,@nSubKey)
  226.         ELSE
  227.             * Try to open registry key
  228.             nErrCode = RegOpenKey(m.nRegKey,m.cLookUpKey,@nSubKey)
  229.         ENDIF
  230.  
  231.         THIS.lCreateKey = m.lSaveCreateKey
  232.         
  233.         IF nErrCode # ERROR_SUCCESS
  234.             RETURN m.nErrCode
  235.         ENDIF
  236.  
  237.         THIS.nCurrentKey = m.nSubKey
  238.         RETURN ERROR_SUCCESS
  239.     ENDPROC
  240.     
  241.     PROCEDURE CloseKey
  242.         * Closes a registry key
  243.         =RegCloseKey(THIS.nCurrentKey)
  244.         THIS.nCurrentKey =0 
  245.     ENDPROC
  246.  
  247.     PROCEDURE SetRegKey
  248.         * This routine sets a registry key setting
  249.         * ex. THIS.SetRegKey("ResWidth","640",;
  250.         *        "Software\Microsoft\VisualFoxPro\4.0\Options",;
  251.         *        HKEY_CURRENT_USER)
  252.         LPARAMETER cOptName,cOptVal,cKeyPath,nUserKey
  253.         LOCAL iPos,cOptKey,cOption,nErrNum
  254.         iPos = 0
  255.         cOption = ""
  256.         nErrNum = ERROR_SUCCESS
  257.  
  258.         * Open registry key
  259.         m.nErrNum = THIS.OpenKey(m.cKeyPath,m.nUserKey)
  260.         IF m.nErrNum # ERROR_SUCCESS
  261.             RETURN m.nErrNum
  262.         ENDIF
  263.         
  264.         * Set Key value
  265.         nErrNum = THIS.SetKeyValue(m.cOptName,m.cOptVal)
  266.  
  267.         * Close registry key 
  268.         THIS.CloseKey()        &&close key
  269.         RETURN m.nErrNum
  270.     ENDPROC
  271.     
  272.     PROCEDURE GetRegKey
  273.         * This routine gets a registry key setting
  274.         * ex. THIS.GetRegKey("ResWidth",@cValue,;
  275.         *        "Software\Microsoft\VisualFoxPro\4.0\Options",;
  276.         *        HKEY_CURRENT_USER)
  277.         LPARAMETER cOptName,cOptVal,cKeyPath,nUserKey
  278.         LOCAL iPos,cOptKey,cOption,nErrNum
  279.         iPos = 0
  280.         cOption = ""
  281.         nErrNum = ERROR_SUCCESS
  282.         
  283.         * Open registry key
  284.         m.nErrNum = THIS.OpenKey(m.cKeyPath,m.nUserKey)
  285.         IF m.nErrNum # ERROR_SUCCESS
  286.             RETURN m.nErrNum
  287.         ENDIF
  288.  
  289.         * Get the key value
  290.         nErrNum = THIS.GetKeyValue(cOptName,@cOptVal)
  291.         
  292.         * Close registry key 
  293.         THIS.CloseKey()        &&close key
  294.         RETURN m.nErrNum
  295.     ENDPROC
  296.  
  297.     PROCEDURE GetKeyValue
  298.         * Obtains a value from a registry key
  299.         * Note: this routine only handles Data strings (REG_SZ)
  300.         LPARAMETER cValueName,cKeyValue
  301.  
  302.         LOCAL lpdwReserved,lpdwType,lpbData,lpcbData,nErrCode
  303.         STORE 0 TO lpdwReserved,lpdwType
  304.         STORE SPACE(256) TO lpbData
  305.         STORE LEN(m.lpbData) TO m.lpcbData
  306.  
  307.         DO CASE
  308.         CASE TYPE("THIS.nCurrentKey")#'N' OR THIS.nCurrentKey = 0
  309.             RETURN ERROR_BADKEY
  310.         CASE TYPE("m.cValueName") #"C"
  311.             RETURN ERROR_BADPARM
  312.         ENDCASE
  313.  
  314.         m.nErrCode=RegQueryValueEx(THIS.nCurrentKey,m.cValueName,;
  315.                 m.lpdwReserved,@lpdwType,@lpbData,@lpcbData)
  316.  
  317.         * Check for error 
  318.         IF m.nErrCode # ERROR_SUCCESS
  319.             RETURN m.nErrCode
  320.         ENDIF
  321.  
  322.         * Make sure we have a data string data type
  323.         IF lpdwType # REG_SZ
  324.             RETURN ERROR_NONSTR_DATA        
  325.         ENDIF
  326.  
  327.         m.cKeyValue = LEFT(m.lpbData,m.lpcbData-1)
  328.         RETURN ERROR_SUCCESS
  329.     ENDPROC
  330.  
  331.     PROCEDURE SetKeyValue
  332.         * This routine sets a key value
  333.         * Note: this routine only handles data strings (REG_SZ)
  334.         LPARAMETER cValueName,cValue
  335.         LOCAL nValueSize,nErrCode 
  336.         
  337.         DO CASE
  338.         CASE TYPE("THIS.nCurrentKey")#'N' OR THIS.nCurrentKey = 0
  339.             RETURN ERROR_BADKEY
  340.         CASE TYPE("m.cValueName") #"C" OR TYPE("m.cValue")#"C"
  341.             RETURN ERROR_BADPARM
  342.         CASE EMPTY(m.cValueName) OR EMPTY(m.cValue)
  343.             RETURN ERROR_BADPARM
  344.         ENDCASE
  345.         
  346.         * Make sure we null terminate this guy
  347.         cValue = m.cValue+CHR(0)
  348.         nValueSize = LEN(m.cValue)
  349.  
  350.         * Set the key value here
  351.         m.nErrCode = RegSetValueEx(THIS.nCurrentKey,m.cValueName,0,;
  352.             REG_SZ,m.cValue,m.nValueSize)
  353.  
  354.         * Check for error
  355.         IF m.nErrCode # ERROR_SUCCESS
  356.             RETURN m.nErrCode
  357.         ENDIF
  358.  
  359.         RETURN ERROR_SUCCESS
  360.     ENDPROC
  361.  
  362.     PROCEDURE DeleteKey
  363.         * This routine deletes a Registry Key
  364.         LPARAMETER nUserKey,cKeyPath
  365.         LOCAL nErrNum
  366.         nErrNum = ERROR_SUCCESS
  367.         
  368.         * Delete key
  369.         m.nErrNum = RegDeleteKey(m.nUserKey,m.cKeyPath)
  370.         RETURN m.nErrNum
  371.     ENDPROC
  372.     
  373.     PROCEDURE EnumOptions
  374.         * Enumerates through all entries for a key and populates array
  375.         LPARAMETER aRegOpts,cOptPath,nUserKey,lEnumKeys
  376.         LOCAL iPos,cOptKey,cOption,nErrNum
  377.         iPos = 0
  378.         cOption = ""
  379.         nErrNum = ERROR_SUCCESS
  380.         
  381.         IF PARAMETERS()<4 OR TYPE("m.lEnumKeys") # "L"
  382.             lEnumKeys = .F.
  383.         ENDIF
  384.         
  385.         * Open key
  386.         m.nErrNum = THIS.OpenKey(m.cOptPath,m.nUserKey)
  387.         IF m.nErrNum # ERROR_SUCCESS
  388.             RETURN m.nErrNum
  389.         ENDIF
  390.         
  391.         * Enumerate through keys
  392.         IF m.lEnumKeys
  393.             * Enumerate and get key names
  394.             nErrNum = THIS.EnumKeys(@aRegOpts)
  395.         ELSE
  396.             * Enumerate and get all key values
  397.             nErrNum = THIS.EnumKeyValues(@aRegOpts)
  398.         ENDIF
  399.         
  400.         * Close key
  401.         THIS.CloseKey()        &&close key
  402.         RETURN m.nErrNum
  403.     ENDPROC
  404.     
  405.     FUNCTION IsKey
  406.         * Checks to see if a key exists
  407.         LPARAMETER cKeyName,nRegKey
  408.  
  409.         * Open extension key        
  410.         nErrNum = THIS.OpenKey(m.cKeyName,m.nRegKey)
  411.         IF m.nErrNum  = ERROR_SUCCESS
  412.             * Close extension key
  413.             THIS.CloseKey()
  414.         ENDIF
  415.  
  416.         RETURN m.nErrNum = ERROR_SUCCESS
  417.     ENDFUNC
  418.  
  419.     PROCEDURE EnumKeys
  420.         PARAMETER aKeyNames
  421.         LOCAL nKeyEntry,cNewKey,cNewSize,cbuf,nbuflen,cRetTime
  422.         nKeyEntry = 0
  423.         DIMENSION aKeyNames[1]
  424.         DO WHILE .T.
  425.             nKeySize = 0
  426.             cNewKey = SPACE(100)
  427.             nKeySize = LEN(m.cNewKey)
  428.             cbuf=space(100)
  429.             nbuflen=len(m.cbuf)
  430.             cRetTime=space(100)
  431.  
  432.             m.nErrCode = RegEnumKeyEx(THIS.nCurrentKey,m.nKeyEntry,@cNewKey,@nKeySize,0,@cbuf,@nbuflen,@cRetTime)
  433.             
  434.             DO CASE
  435.             CASE m.nErrCode = ERROR_EOF
  436.                 EXIT
  437.             CASE m.nErrCode # ERROR_SUCCESS
  438.                 EXIT
  439.             ENDCASE
  440.  
  441.             cNewKey = ALLTRIM(m.cNewKey)
  442.             cNewKey = LEFT(m.cNewKey,LEN(m.cNewKey)-1)
  443.             IF !EMPTY(aKeyNames[1])
  444.                 DIMENSION aKeyNames[ALEN(aKeyNames)+1]
  445.             ENDIF
  446.             aKeyNames[ALEN(aKeyNames)] = m.cNewKey 
  447.             nKeyEntry = m.nKeyEntry + 1
  448.         ENDDO
  449.  
  450.         IF m.nErrCode = ERROR_EOF AND m.nKeyEntry # 0
  451.             m.nErrCode = ERROR_SUCCESS
  452.         ENDIF
  453.         RETURN m.nErrCode
  454.     ENDPROC
  455.  
  456.     PROCEDURE EnumKeyValues
  457.         * Enumerates through values of a registry key
  458.         LPARAMETER aKeyValues
  459.         
  460.         LOCAL lpszValue,lpcchValue,lpdwReserved
  461.         LOCAL lpdwType,lpbData,lpcbData
  462.         LOCAL nErrCode,nKeyEntry,lArrayPassed
  463.  
  464.         STORE 0 TO nKeyEntry
  465.         
  466.         IF TYPE("THIS.nCurrentKey")#'N' OR THIS.nCurrentKey = 0
  467.             RETURN ERROR_BADKEY
  468.         ENDIF
  469.         
  470.         * Sorry, Win32s does not support this one!
  471.         IF THIS.nCurrentOS = OS_W32S
  472.             RETURN ERROR_BADPLAT
  473.         ENDIF
  474.         
  475.         DO WHILE .T.
  476.  
  477.             STORE 0 TO lpdwReserved,lpdwType,nErrCode
  478.             STORE SPACE(256) TO lpbData, lpszValue
  479.             STORE LEN(lpbData) TO m.lpcchValue
  480.             STORE LEN(lpszValue) TO m.lpcbData
  481.  
  482.             nErrCode=RegEnumValue(THIS.nCurrentKey,m.nKeyEntry,@lpszValue,;
  483.                 @lpcchValue,m.lpdwReserved,@lpdwType,@lpbData,@lpcbData)
  484.             
  485.             DO CASE
  486.             CASE m.nErrCode = ERROR_EOF
  487.                 EXIT
  488.             CASE m.nErrCode # ERROR_SUCCESS
  489.                 EXIT
  490.             ENDCASE
  491.  
  492.             nKeyEntry = m.nKeyEntry + 1
  493.  
  494.             * Set array values
  495.             DIMENSION aKeyValues[m.nKeyEntry,2]
  496.             aKeyValues[m.nKeyEntry,1] = LEFT(m.lpszValue,m.lpcchValue)
  497.             DO CASE
  498.             CASE lpdwType = REG_SZ
  499.                 aKeyValues[m.nKeyEntry,2] = LEFT(m.lpbData,m.lpcbData-1)
  500.             CASE lpdwType = REG_BINARY
  501.                 * Don't support binary
  502.                 aKeyValues[m.nKeyEntry,2] = REG_BINARY_LOC
  503.             CASE lpdwType = REG_DWORD
  504.                 * You will need to use ASC() to check values here.
  505.                 aKeyValues[m.nKeyEntry,2] = LEFT(m.lpbData,m.lpcbData-1)
  506.             OTHERWISE
  507.                 aKeyValues[m.nKeyEntry,2] = REG_UNKNOWN_LOC
  508.             ENDCASE
  509.         ENDDO
  510.          
  511.         IF m.nErrCode = ERROR_EOF AND m.nKeyEntry # 0
  512.             m.nErrCode = ERROR_SUCCESS
  513.         ENDIF
  514.         RETURN m.nErrCode
  515.     ENDPROC
  516.  
  517. ENDDEFINE
  518.  
  519.  
  520. DEFINE CLASS oldinireg AS registry
  521.  
  522.     PROCEDURE GetINISection
  523.         PARAMETERS aSections,cSection,cINIFile
  524.         LOCAL cINIValue, nTotEntries, i, nLastPos
  525.         cINIValue = ""
  526.         IF TYPE("m.cINIFile") # "C"
  527.             cINIFile = ""
  528.         ENDIF
  529.     
  530.         IF THIS.GetINIEntry(@cINIValue,cSection,0,m.cINIFile) # ERROR_SUCCESS
  531.             RETURN ERROR_FAILINI
  532.         ENDIF
  533.  
  534.         nTotEntries=OCCURS(CHR(0),m.cINIValue)
  535.         DIMENSION aSections[m.nTotEntries]
  536.         nLastPos = 1
  537.         FOR i = 1 TO m.nTotEntries
  538.             nTmpPos = AT(CHR(0),m.cINIValue,m.i)
  539.             aSections[m.i] = SUBSTR(m.cINIValue,m.nLastPos,m.nTmpPos-m.nLastPos)
  540.             nLastPos = m.nTmpPos+1
  541.         ENDFOR
  542.  
  543.         RETURN ERROR_SUCCESS
  544.     ENDPROC
  545.         
  546.     PROCEDURE GetINIEntry
  547.         LPARAMETER cValue,cSection,cEntry,cINIFile
  548.         
  549.         * Get entry from INI file 
  550.         LOCAL cBuffer,nBufSize,nErrNum,nTotParms
  551.         nTotParms = PARAMETERS()
  552.         
  553.         * Load API functions
  554.         nErrNum= THIS.LoadINIFuncs()
  555.         IF m.nErrNum # ERROR_SUCCESS
  556.             RETURN m.nErrNum
  557.         ENDIF
  558.         
  559.         * Parameter checks here
  560.         IF m.nTotParms < 3
  561.             m.cEntry = 0
  562.         ENDIF
  563.  
  564.         m.cBuffer=space(2000)
  565.         
  566.         IF EMPTY(m.cINIFile)
  567.             * WIN.INI file
  568.             m.nBufSize = GetWinINI(m.cSection,m.cEntry,"",@cBuffer,LEN(m.cBuffer))
  569.         ELSE
  570.             * Private INI file
  571.             m.nBufSize = GetPrivateINI(m.cSection,m.cEntry,"",@cBuffer,LEN(m.cBuffer),m.cINIFile)
  572.         ENDIF
  573.         
  574.         IF m.nBufSize = 0 &&could not find entry in INI file
  575.             RETURN ERROR_NOINIENTRY
  576.         ENDIF
  577.         
  578.         m.cValue=LEFT(m.cBuffer,m.nBufSize)
  579.         
  580.         ** All is well
  581.         RETURN ERROR_SUCCESS
  582.     ENDPROC
  583.     
  584.     PROCEDURE WriteINIEntry
  585.         LPARAMETER cValue,cSection,cEntry,cINIFile
  586.         
  587.         * Get entry from INI file 
  588.         LOCAL nErrNum
  589.         
  590.         * Load API functions
  591.         nErrNum = THIS.LoadINIFuncs()
  592.         IF m.nErrNum # ERROR_SUCCESS
  593.             RETURN m.nErrNum
  594.         ENDIF
  595.         
  596.         IF EMPTY(m.cINIFile)
  597.             * WIN.INI file
  598.             nErrNum = WriteWinINI(m.cSection,m.cEntry,m.cValue)
  599.         ELSE
  600.             * Private INI file
  601.             nErrNum = WritePrivateINI(m.cSection,m.cEntry,m.cValue,m.cINIFile)
  602.         ENDIF
  603.                 
  604.         ** All is well
  605.         RETURN IIF(m.nErrNum=1,ERROR_SUCCESS,m.nErrNum)
  606.     ENDPROC
  607.  
  608.     PROCEDURE LoadINIFuncs
  609.         * Loads funtions needed for reading INI files
  610.         IF THIS.lLoadedINIs
  611.             RETURN ERROR_SUCCESS
  612.         ENDIF
  613.         
  614.         DECLARE integer GetPrivateProfileString IN Win32API ;
  615.             AS GetPrivateINI string,string,string,string,integer,string
  616.  
  617.         IF THIS.lhaderror && error loading library
  618.             RETURN -1
  619.         ENDIF
  620.  
  621.         DECLARE integer GetProfileString IN Win32API ;
  622.             AS GetWinINI string,string,string,string,integer
  623.  
  624.         DECLARE integer WriteProfileString IN Win32API ;
  625.             AS WriteWinINI string,string,string
  626.  
  627.         DECLARE integer WritePrivateProfileString IN Win32API ;
  628.             AS WritePrivateINI string,string,string,string
  629.  
  630.         THIS.lLoadedINIs = .T.
  631.         
  632.         * Need error check here
  633.         RETURN ERROR_SUCCESS
  634.     ENDPROC
  635.  
  636. ENDDEFINE
  637.  
  638. DEFINE CLASS foxreg AS registry
  639.  
  640.     PROCEDURE SetFoxOption
  641.         LPARAMETER cOptName,cOptVal
  642.         RETURN THIS.SetRegKey(cOptName,cOptVal,THIS.cVFPOptPath,THIS.nUserKey)
  643.     ENDPROC
  644.  
  645.     PROCEDURE GetFoxOption
  646.         LPARAMETER cOptName,cOptVal
  647.         RETURN THIS.GetRegKey(cOptName,@cOptVal,THIS.cVFPOptPath,THIS.nUserKey)
  648.     ENDPROC
  649.  
  650.     PROCEDURE EnumFoxOptions
  651.         LPARAMETER aFoxOpts
  652.         RETURN THIS.EnumOptions(@aFoxOpts,THIS.cVFPOptPath,THIS.nUserKey,.F.)
  653.     ENDPROC
  654.  
  655. ENDDEFINE
  656.  
  657. DEFINE CLASS odbcreg AS registry
  658.  
  659.     PROCEDURE LoadODBCFuncs
  660.         IF THIS.lLoadedODBCs
  661.             RETURN ERROR_SUCCESS
  662.         ENDIF
  663.         
  664.         * Check API file containing functions
  665.  
  666.         IF EMPTY(THIS.cODBCDLLFile)
  667.             RETURN ERROR_NOODBCFILE
  668.         ENDIF
  669.  
  670.         LOCAL henv,fDirection,szDriverDesc,cbDriverDescMax
  671.         LOCAL pcbDriverDesc,szDriverAttributes,cbDrvrAttrMax,pcbDrvrAttr
  672.         LOCAL szDSN,cbDSNMax,pcbDSN,szDescription,cbDescriptionMax,pcbDescription
  673.  
  674.         DECLARE Short SQLDrivers IN (THIS.cODBCDLLFile) ;
  675.             Integer henv, Integer fDirection, ;
  676.             String @ szDriverDesc, Integer cbDriverDescMax, Integer pcbDriverDesc, ;
  677.             String @ szDriverAttributes, Integer cbDrvrAttrMax, Integer pcbDrvrAttr
  678.  
  679.         IF THIS.lhaderror && error loading library
  680.             RETURN -1
  681.         ENDIF
  682.  
  683.         DECLARE Short SQLDataSources IN (THIS.cODBCDLLFile) ;
  684.             Integer henv, Integer fDirection, ;
  685.             String @ szDSN, Integer cbDSNMax, Integer @ pcbDSN, ;
  686.             String @ szDescription, Integer cbDescriptionMax,Integer pcbDescription
  687.  
  688.         THIS.lLoadedODBCs = .T.
  689.         
  690.         RETURN ERROR_SUCCESS
  691.     ENDPROC
  692.     
  693.     PROCEDURE GetODBCDrvrs
  694.         PARAMETER aDrvrs,lDataSources
  695.         LOCAL nODBCEnv,nRetVal,dsn,dsndesc,mdsn,mdesc
  696.  
  697.         lDataSources = IIF(TYPE("m.lDataSources")="L",m.lDataSources,.F.)
  698.  
  699.         * Load API functions
  700.         nRetVal = THIS.LoadODBCFuncs()
  701.         IF m.nRetVal # ERROR_SUCCESS
  702.             RETURN m.nRetVal
  703.         ENDIF
  704.  
  705.         * Get ODBC environment handle
  706.         nODBCEnv=VAL(SYS(3053))
  707.  
  708.         * -- Possible error messages
  709.         * 527 "cannot load odbc library"
  710.         * 528 "odbc entry point missing"
  711.         * 182 "not enough memory"
  712.  
  713.         IF INLIST(nODBCEnv,527,528,182)
  714.             * Failed
  715.             RETURN ERROR_ODBCFAIL
  716.         ENDIF
  717.  
  718.         DIMENSION aDrvrs[1,IIF(m.lDataSources,2,1)]
  719.         aDrvrs[1] = ""
  720.     
  721.         DO WHILE .T.
  722.             dsn=space(100)
  723.             dsndesc=space(100)
  724.             mdsn=0
  725.             mdesc=0
  726.  
  727.             * Return drivers or data sources
  728.             IF m.lDataSources
  729.                 nRetVal = SQLDataSources(m.nODBCEnv,SQL_FETCH_NEXT,@dsn,100,@mdsn,@dsndesc,255,@mdesc)
  730.             ELSE
  731.                 nRetVal = SQLDrivers(m.nODBCEnv,SQL_FETCH_NEXT,@dsn,100,@mdsn,@dsndesc,100,@mdesc)
  732.             ENDIF
  733.                 
  734.             DO CASE
  735.             CASE m.nRetVal = SQL_NO_DATA
  736.                 nRetVal = ERROR_SUCCESS
  737.                 EXIT
  738.             CASE m.nRetVal # ERROR_SUCCESS AND m.nRetVal # 1 
  739.                 EXIT
  740.             OTHERWISE
  741.                 IF !EMPTY(aDrvrs[1])
  742.                     IF m.lDataSources
  743.                         DIMENSION aDrvrs[ALEN(aDrvrs,1)+1,2]
  744.                     ELSE
  745.                         DIMENSION aDrvrs[ALEN(aDrvrs,1)+1,1]
  746.                     ENDIF
  747.                 ENDIF
  748.                 dsn = ALLTRIM(m.dsn)
  749.                 aDrvrs[ALEN(aDrvrs,1),1] = LEFT(m.dsn,LEN(m.dsn)-1)
  750.                 IF m.lDataSources
  751.                     dsndesc = ALLTRIM(m.dsndesc)                
  752.                     aDrvrs[ALEN(aDrvrs,1),2] = LEFT(m.dsndesc,LEN(m.dsndesc)-1)            
  753.                 ENDIF
  754.             ENDCASE
  755.         ENDDO
  756.         RETURN nRetVal
  757.     ENDPROC
  758.  
  759.     PROCEDURE EnumODBCDrvrs
  760.         LPARAMETER aDrvrOpts,cODBCDriver
  761.         LOCAL cSourceKey
  762.         cSourceKey = ODBC_DRVRS_KEY+m.cODBCDriver
  763.         RETURN THIS.EnumOptions(@aDrvrOpts,m.cSourceKey,HKEY_LOCAL_MACHINE,.F.)
  764.     ENDPROC
  765.  
  766.     PROCEDURE EnumODBCData
  767.         LPARAMETER aDrvrOpts,cDataSource
  768.         LOCAL cSourceKey
  769.         cSourceKey = ODBC_DATA_KEY+cDataSource
  770.         RETURN THIS.EnumOptions(@aDrvrOpts,m.cSourceKey,HKEY_CURRENT_USER,.F.)
  771.     ENDPROC
  772.  
  773. ENDDEFINE
  774.  
  775. DEFINE CLASS filereg AS registry
  776.  
  777.     PROCEDURE GetAppPath
  778.         * Checks and returns path of application
  779.         * associated with a particular extension (e.g., XLS, DOC). 
  780.         LPARAMETER cExtension,cExtnKey,cAppKey,lServer
  781.         LOCAL nErrNum,cOptName
  782.         cOptName = ""
  783.  
  784.         * Check Extension parameter
  785.         IF TYPE("m.cExtension") # "C" OR LEN(m.cExtension) > 3
  786.             RETURN ERROR_BADPARM
  787.         ENDIF
  788.         m.cExtension = "."+m.cExtension
  789.  
  790.         * Open extension key
  791.         nErrNum = THIS.OpenKey(m.cExtension)
  792.         IF m.nErrNum  # ERROR_SUCCESS
  793.             RETURN m.nErrNum
  794.         ENDIF
  795.  
  796.         * Get key value for file extension
  797.         nErrNum = THIS.GetKeyValue(cOptName,@cExtnKey)
  798.  
  799.         * Close extension key
  800.         THIS.CloseKey()
  801.  
  802.         IF m.nErrNum  # ERROR_SUCCESS
  803.             RETURN m.nErrNum
  804.         ENDIF
  805.         RETURN THIS.GetApplication(cExtnKey,@cAppKey,lServer)
  806.     ENDPROC
  807.  
  808.     PROCEDURE GetLatestVersion
  809.         * Checks and returns path of application
  810.         * associated with a particular extension (e.g., XLS, DOC). 
  811.         LPARAMETER cClass,cExtnKey,cAppKey,lServer
  812.         
  813.         LOCAL nErrNum,cOptName
  814.         cOptName = ""
  815.  
  816.         * Open class key (e.g., Excel.Sheet)
  817.         nErrNum = THIS.OpenKey(m.cClass+CURVER_KEY)
  818.         IF m.nErrNum  # ERROR_SUCCESS
  819.             RETURN m.nErrNum
  820.         ENDIF
  821.  
  822.         * Get key value for file extension
  823.         nErrNum = THIS.GetKeyValue(cOptName,@cExtnKey)
  824.  
  825.         * Close extension key
  826.         THIS.CloseKey()
  827.  
  828.         IF m.nErrNum  # ERROR_SUCCESS
  829.             RETURN m.nErrNum
  830.         ENDIF
  831.         RETURN THIS.GetApplication(cExtnKey,@cAppKey,lServer)
  832.     ENDPROC
  833.  
  834.     PROCEDURE GetApplication
  835.         PARAMETER cExtnKey,cAppKey,lServer
  836.  
  837.         LOCAL nErrNum,cOptName
  838.         cOptName = ""
  839.         
  840.         * lServer - checking for OLE server.
  841.         IF TYPE("m.lServer") = "L" AND m.lServer
  842.             THIS.cAppPathKey = OLE_PATH_KEY
  843.         ELSE    
  844.             THIS.cAppPathKey = APP_PATH_KEY
  845.         ENDIF
  846.  
  847.         * Open extension app key
  848.         m.nErrNum = THIS.OpenKey(m.cExtnKey+THIS.cAppPathKey)
  849.         IF m.nErrNum  # ERROR_SUCCESS
  850.             RETURN m.nErrNum
  851.         ENDIF
  852.  
  853.         * Get application path
  854.         nErrNum = THIS.GetKeyValue(cOptName,@cAppKey)
  855.  
  856.         * Close application path key
  857.         THIS.CloseKey()
  858.         
  859.         RETURN m.nErrNum
  860.     ENDPROC
  861.  
  862. ENDDEFINE