 |
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
上一篇主題 :: 下一篇主題 |
發表人 |
內容 |
garfield Site Admin

註冊時間: 2003-01-30 文章: 2160
第 1 樓
|
發表於: 星期五 八月 30, 2013 11:53 am 文章主題: 找出安裝於電腦裡 MySQL ODBC 最新版本 |
|
|
1.VFP是32位元軟體, 所以MyODBC 要安裝32bit 才能使用.
2.連接字串 :
mstring = [DRIVER={]+GetLastODBCName( MySQL ODBC')+[};SERVER=localhost;UID=root;PWD=密碼;Stmt=set names utf8;database=後端資料庫名;charset=utf8]
代碼: |
? 'MySQL ODBC 最新版本:',GetLastODBCName('MySQL ODBC')
RETURN
PROCEDURE GetLastODBCName
LPARAMETERS modbc
IF EMPTY(modbc)
modbc = 'MySQL ODBC'
ENDIF
LOCAL mreg
mreg = Createobject( 'Registry' )
*? mreg.ReadRegistryString( HKEY_LOCAL_MACHINE ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\","MySQL ODBC 5.2 Unicode Driver" )
LOCAL mret ,i
mret = ''
local mlist[1,1]
*mreg.GetEnumValues(@mlist , HKEY_LOCAL_MACHINE ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\" )
mreg.GetEnumValues(@mlist , 0x80000002 ,"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\" )
FOR i=1 TO ALen(mlist,1)
*? i,mlist[i,1] &&-,mlist[i,2]
IF modbc $ mlist[i,1]
&&--取最後一個
mret = mlist[i,1]
endif
next
RETURN mret
*************************************************************
*** The following should be placed into a .H file and included
*** in any program that uses the Registry class (registry.vcx)
#Define MAX_INI_BUFFERSIZE 256
#Define MAX_INI_ENUM_BUFFERSIZE 16000
*** Registry roots - You'll likely need these values in your programs
*** so add them to FOXPRO.H or to each program that
*** uses them.
#Define HKEY_CLASSES_ROOT -2147483648 && (( HKEY ) 0x80000000 )
#Define HKEY_CURRENT_USER -2147483647 && (( HKEY ) 0x80000001 )
#Define HKEY_LOCAL_MACHINE -2147483646 && (( HKEY ) 0x80000002 )
#Define HKEY_USERS -2147483645 && (( HKEY ) 0x80000003 )
*** Success Flag
#Define ERROR_SUCCESS 0
*** Registry Value types
#Define REG_NONE 0 && Undefined Type (default)
#Define REG_SZ 1 && Regular Null Terminated String
#Define REG_BINARY 3 && ??? (unimplemented)
#Define REG_DWORD 4 && Long Integer value
#Define MULTI_SZ 7 && Multiple Null Term Strings (not implemented)
Define Class Registry As Custom
*************************************************************
*** Author: Rick Strahl
*** modify some error by Garfield
*** (c) West Wind Technologies, 1995
*** Contact: (503) 386-2087 / 76427,2363@compuserve.com
*** Modified: 02/24/95
***
*** Function: Provides read and write access to the
*** System Registry under Windows 95 and
*** NT. The functionality provided is
*** greatly abstracted resulting in using
*** a single method call to set and
*** retrieve values from the registry.
*** The functionality closely matches
*** the way GetPrivateProfileString
*** works, including the ability to
*** automatically delete key nodes.
***
*** Wish List: Key Enumeration and enumerated deletion
*** Allow Binary Registry values
*************************************************************
*** Custom Properties
*** Stock Properties
************************************************************************
* Registry :: Init
*********************************
*** Function: Loads required DLLs. Note Read and Write DLLs are
*** not loaded here since they need to be reloaded each
*** time depending on whether String or Integer values
*** are required
************************************************************************
Function Init
*** Open Registry Key
Declare Integer RegOpenKey ;
IN Win32API ;
INTEGER nHKey,;
STRING cSubKey,;
INTEGER @nHandle
*** Create a new Key
Declare Integer RegCreateKey ;
IN Win32API ;
INTEGER nHKey,;
STRING cSubKey,;
INTEGER @nHandle
*** Close an open Key
Declare Integer RegCloseKey ;
IN Win32API ;
INTEGER nHKey
*** Delete a key (path)
Declare Integer RegDeleteKey ;
IN Win32API ;
INTEGER nHKEY,;
STRING cSubkey
*** Delete a value from a key
Declare Integer RegDeleteValue ;
IN Win32API ;
INTEGER nHKEY,;
STRING cEntry
Endproc
* LoadRegistryDLLs
************************************************************************
* Registry :: ReadRegistryString
*********************************
*** Function: Reads a string value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to retrieve
*** Return: Registry String or .NULL. on error
************************************************************************
Function ReadRegistryString
Lparameters tnHKey, tcSubkey, tcEntry
Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
lnRegHandle=0
*** Open the registry key
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here it's STRING.
Declare Integer RegQueryValueEx ;
IN Win32API As RegQueryString;
INTEGER nHKey,;
STRING lpszValueName,;
INTEGER dwReserved,;
INTEGER @lpdwType,;
STRING @lpbData,;
INTEGER @lpcbData
*** Return buffer to receive value
lcDataBuffer=Space(MAX_INI_BUFFERSIZE)
lnSize=Len(lcDataBuffer)
lnType=0
lnResult=RegQueryString(lnRegHandle,tcEntry,0,@lnType,;
@lcDataBuffer,@lnSize)
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
If lnSize<2
Return ""
Endif
*** Return string based on length returned
Return Substr(lcDataBuffer,1,lnSize-1)
Endproc
* ReadRegistryString
************************************************************************
* Registry :: ReadRegistryInt
*********************************
*** Function: Reads an integer (DWORD) or short (4 byte or less) binary
*** value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to retrieve
*** Return: Registry String or .NULL. on error
************************************************************************
Function ReadRegistryInt
Lparameters tnHKey, tcSubkey, tcEntry
Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
lnRegHandle=0
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here's it's an INTEGER
Declare Integer RegQueryValueEx ;
IN Win32API As RegQueryInt;
INTEGER nHKey,;
STRING lpszValueName,;
INTEGER dwReserved,;
Integer @lpdwType,;
INTEGER @lpbData,;
INTEGER @lpcbData
lnDataBuffer=0
lnSize=4
lnResult=RegQueryInt(lnRegHandle,tcEntry,0,@tnType,;
@lnDataBuffer,@lnSize)
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Return lnDataBuffer
* EOP RegQueryInt
************************************************************************
* Registry :: WriteRegistryString
*********************************
*** Function: Reads a string value from the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
Function WriteRegistryString
Lparameters tnHKey, tcSubkey, tcEntry, tcValue, tlCreate
Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
lnRegHandle=0
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
If !tlCreate
Return .Null.
Else
lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Endif
Endif
*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
Declare Integer RegSetValueEx ;
IN Win32API ;
INTEGER nHKey,;
STRING lpszEntry,;
INTEGER dwReserved,;
INTEGER fdwType,;
STRING lpbData,;
INTEGER cbData
*** Check for .NULL. which means delete key
If !Isnull(tcValue)
*** Nope - write new value
lnSize=Len(tcValue)
lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_SZ,;
tcValue,lnSize)
Else
*** DELETE THE KEY
lnResult=RegDeleteValue(lnRegHandle,tcEntry)
Endif
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Return .T.
Endproc
* WriteRegistryString
************************************************************************
* Registry :: WriteRegistryInt
*********************************
*** Function: Writes a numeric value to the registry.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
Function WriteRegistryInt
Lparameters tnHKey, tcSubkey, tcEntry, tnValue,tlCreate
Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
lnRegHandle=0
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
If !tlCreate
Return .Null.
Else
lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Endif
Endif
*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
Declare Integer RegSetValueEx ;
IN Win32API ;
INTEGER nHKey,;
STRING lpszEntry,;
INTEGER dwReserved,;
INTEGER fdwType,;
INTEGER @lpbData,;
INTEGER cbData
*** Check for .NULL. which means delete key
If !Isnull(tnValue)
*** Nope - write new value
lnSize=4
lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_DWORD,;
@tnValue,lnSize)
Else
*** DELETE THE KEY
lnResult=RegDeleteValue(lnRegHandle,tcEntry)
Endif
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Return .T.
Endproc
* WriteRegistryInt
************************************************************************
* Registry :: WriteRegistryBinary
*********************************
*** Function: Writes a binary value to the registry.
*** Binary must be written as character values:
*** chr(80)+chr(13) will result in "50 1D"
*** for example.
*** Pass: tnHKEY - HKEY value (in CGIServ.h)
*** tcSubkey - The Registry subkey value
*** tcEntry - The actual Key to write to
*** tcValue - Value to write or .NULL. to delete key
*** tnLength - you have to supply the length
*** tlCreate - Create if it doesn't exist
*** Assume: Use with extreme caution!!! Blowing your registry can
*** hose your system!
*** Return: .T. or .NULL. on error
************************************************************************
Function WriteRegistryBinary
Lparameters tnHKey, tcSubkey, tcEntry, tcValue,tnLength,tlCreate
Local lnRegHandle, lnResult, lnSize, lcDataBuffer, tnType
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
tnLength=Iif(Type("tnLength")="N",tnLength,Len(tcValue))
lnRegHandle=0
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
If !tlCreate
Return .Null.
Else
lnResult=RegCreateKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Endif
Endif
*** Need to define here specifically for Return Type!
*** Here lpbData is STRING.
Declare Integer RegSetValueEx ;
IN Win32API ;
INTEGER nHKey,;
STRING lpszEntry,;
INTEGER dwReserved,;
INTEGER fdwType,;
STRING @lpbData,;
INTEGER cbData
*** Check for .NULL. which means delete key
If !Isnull(tcValue)
*** Nope - write new value
lnResult=RegSetValueEx(lnRegHandle,tcEntry,0,REG_BINARY,;
@tcValue,tnLength)
Else
*** DELETE THE KEY
lnResult=RegDeleteValue(lnRegHandle,tcEntry)
Endif
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Return .T.
Endproc
* WriteRegistryBinary
************************************************************************
* Registry :: DeleteRegistryKey
*********************************
*** Function: Deletes a registry key. Note this does not delete
*** an entry but the key (ie. a path node).
*** Use WriteRegistryString/Int with a .NULL. to
*** Delete an entry.
*** Pass: tnHKey - Registry Root node key
*** tcSubkey - Path to clip
*** Return: .T. or .NULL.
************************************************************************
Function DeleteRegistryKey
Lparameters tnHKey,tcSubkey
Local lnResult, lnRegHandle
tnHKey=Iif(Type("tnHKey")="N",tnHKey,HKEY_LOCAL_MACHINE)
lnRegHandle=0
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
*** Key doesn't exist or can't be opened
Return .Null.
Endif
lnResult=RegDeleteKey(tnHKey,tcSubkey)
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
Return .Null.
Endif
Return .T.
Endproc
* DeleteRegistryKey
************************************************************************
* wwAPI :: EnumRegistryKey
*********************************
*** Function: Returns a registry key name based on an index
*** Allows enumeration of keys in a FOR loop. If key
*** is empty end of list is reached or the key doesn't
*** exist or is empty.
*** Pass: tnHKey - HKEY_ root key
*** tcSubkey - Subkey string
*** tnIndex - Index of key name to get (0 based)
*** Return: "" on error - Key name otherwise
************************************************************************
Protected Procedure EnumKey
Lparameters tnHKey, tcSubkey, tnIndex
Local lcSubKey, lcReturn, lnResult, lcDataBuffer
lnRegHandle=0
*** Open the registry key
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
*** Not Found
Return .Null.
Endif
Declare Integer RegEnumKey ;
IN WIN32API ;
INTEGER nHKey, ;
INTEGER nIndex, ;
STRING @cSubkey, ;
INTEGER nSize
lcDataBuffer=Space(MAX_INI_BUFFERSIZE)
lnSize=MAX_INI_BUFFERSIZE
lnReturn=RegEnumKey(lnRegHandle, tnIndex, @lcDataBuffer, lnSize)
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
*** Not Found
Return .Null.
Endif
Return Trim(Chrtran(lcDataBuffer,Chr(0),""))
Endfunc
* EnumRegistryKey
************************************************************************
* Registry :: EnumValue
*********************************
*** Function: Returns the name of a registry Value key. Note the actual
*** Value is not returned but just the key. This is done
*** so you can check the type first and use the appropriate
*** ReadRegistryX method. The type is returned by ref in the
*** last parameter.
*** Assume:
*** Pass: tnHKey - HKEY value
*** tcSubkey - The key to enumerate valuekeys for
*** tnIndex - Index of key to work on
*** @tnType - Used to pass back the type of the value
*** Return: String of ValueKey or .NULL.
************************************************************************
Protected Function EnumValue
Lparameters tnHKey, tcSubkey, tnIndex, tnType
Local lcSubKey, lcReturn, lnResult, lcDataBuffer
tnType=Iif(Type("tnType")="N",tnType,0)
lnRegHandle=0
*** Open the registry key
lnResult=RegOpenKey(tnHKey,tcSubkey,@lnRegHandle)
If lnResult#ERROR_SUCCESS
*** Not Found
Return .Null.
Endif
*** Need to define here specifically for Return Type
*** for lpdData parameter or VFP will choke.
*** Here it's STRING.
Declare Integer RegEnumValue ;
IN Win32API ;
INTEGER nHKey,;
INTEGER nIndex,;
STRING @lpszValueName,;
INTEGER @lpdwSize,;
INTEGER dwReserved,;
INTEGER @lpdwType,;
STRING @lpbData,;
INTEGER @lpcbData
tcSubkey=Space(MAX_INI_BUFFERSIZE)
tcValue=Space(MAX_INI_BUFFERSIZE)
lnSize=MAX_INI_BUFFERSIZE
lnValSize=MAX_INI_BUFFERSIZE
lnReturn=RegEnumValue(lnRegHandle, tnIndex, @tcSubkey,@lnValSize, 0, @tnType, @tcValue, @lnSize)
=RegCloseKey(lnRegHandle)
If lnResult#ERROR_SUCCESS
*** Not Found
Return .Null.
Endif
tcValue = Alltrim(Chrtran(tcValue , Chr(0), "")) && memc 06/30/1999
tcSubkey = Alltrim(Chrtran(tcSubkey, Chr(0), ""))
If !Empty(tcValue) And Empty(tcSubkey) && memc 06/30/1999
tcSubkey = "0"
Endif
Return tcSubkey
Endfunc
* EnumRegValue
************************************************************************
* Registry :: GetEnumValues
*********************************
*** Function: Retrieves all Values off a key into an array. The
*** array is 2D and consists of: Key Name, Value
*** Assume: Not tested with non-string values
*** Pass: @taValues - Result Array: Pass by Reference
*** tnHKEY - ROOT KEY value
*** tcSubKey - SubKey to work on
*** Return: Count of Values retrieved
************************************************************************
Function GetEnumValues
Lparameters taValues, tnHKey, tcSubkey
Local x, lcKey
lcKey="x"
x=0
Do While !Empty(lcKey) Or Isnull(lcKey)
lnType=0
lcKey=This.EnumValue(tnHKey,tcSubkey,x,@lnType)
If Isnull(lcKey) Or Empty(lcKey)
Exit
Endif
If lcKey = "0" && memc 06/30/1999
lcKey = 0
Endif
x=x+1
Dimension taValues[x,2]
Do Case
Case lnType=REG_SZ Or lnType=REG_BINARY Or lnType=REG_NONE
lcValue=this.ReadRegistryString(tnHKey,tcSubkey,lcKey)
If Type("lcKey") = "N" && memc 06/30/1999
lcKey = "0"
Endif
taValues[x,1]=lcKey
taValues[x,2]=lcValue
Case lnType=REG_DWORD
lnValue=this.ReadRegistryInt(tnHKey,tcSubkey,lcKey)
If Type("lcKey") = "N" && memc 06/30/1999
lcKey = "0"
Endif
taValues[x,1]=lcKey
taValues[x,2]=lnValue
Otherwise
taValues[x,1]=lcKey
taValues[x,2]=""
Endcase
Enddo
Return x
Endfunc
* GetEnumValues
************************************************************************
* Registry :: GetEnumKeys
*********************************
*** Function: Returns an array of all subkeys for a given key
*** NOTE: This function does not return Value Keys only
*** Tree Keys!!!!
*** Pass: @taKeys - An array that gets filled with key names
*** tnHKEY - Root Key
*** tcSubkey - Subkey to enumerate for
*** Return: Number of keys or 0
************************************************************************
Function GetEnumKeys
Lparameters taKeys, tnHKey, tcSubkey
Local x, lcKey
lcKey="x"
x=0
Do While !Empty(lcKey) Or Isnull(lcKey)
lnType=0
lcKey=This.EnumKey(tnHKey,tcSubkey,x)
If Isnull(lcKey) Or Empty(lcKey)
Exit
Endif
x=x+1
Dimension taKeys[x]
taKeys[x]=lcKey
Enddo
Return x
Endfunc
* GetEnumKeys
Function Release
Release This
Endfunc
Enddefine
*EOC Registry
|
_________________ 利用>>搜尋<<的功能會比問的還要快得到答案. |
|
回頂端 |
|
 |
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|