Microsoft Corporation
July 1996
Microsoft® Windows NT® and Windows® 95 operating systems make use of a set of system configuration files referred to as the registry. The operating system provides a tool called Regedit that is used to manipulate entries in the registry.
When you are developing applications for the Windows environment, it is imperative that you know how to work with the system registry to discover information and to save and manipulate your own specific entries.
The registry is accessed through Microsoft Visual Basic® for Applications by declaring the necessary Windows application programming interface (API) functions and the correct constants:
' *********************************************************
' Registry Module for Visual Basic for Applications under Windows 95
' Declarations and Control Module
' *********************************************************
Option Explicit
' **********************************************
' Declare the specific key path for your
' application's settings in the registry.
' **********************************************
Public Const AppReg = "MyAppName"
Private Const REG_APP_KEYS_PATH = "Software\MYApps\" & AppReg
' **********************************************
' Specify constants to specific branches in the
' registry.
' **********************************************
Global Const HKEY_CLASSES_ROOT = &H80000000
Global Const HKEY_CURRENT_USER = &H80000001
Global Const HKEY_LOCAL_MACHINE = &H80000002
Global Const HKEY_USERS = &H80000003
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_NO_MORE_ITEMS = 259&
' **********************************************
' Specify constants to registry data types.
' These are declared Public for outside module
' usage in the GetAppRegValue() function.
' **********************************************
Public Const REG_NONE = 0
Public Const REG_SZ = 1
Public Const REG_EXPAND_SZ = 2
Public Const REG_BINARY = 3
Public Const REG_DWORD = 4
Public Const REG_DWORD_LITTLE_ENDIAN = 4
Public Const REG_DWORD_BIG_ENDIAN = 5
Public Const REG_LINK = 6
Public Const REG_MULTI_SZ = 7
Public Const REG_RESOURCE_LIST = 8
' **********************************************
' Specify constants to registry action types.
' **********************************************
Private Const REG_OPTION_NON_VOLATILE = 0
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const KEY_CREATE_LINK = &H20
Private Const SYNCHRONIZE = &H100000
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or _
KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
' **********************************************
' Security mask attributes for Windows NT (SAM).
' **********************************************
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Boolean
End Type
Declare Function RegCreateKey Lib "advapi32" Alias "RegCreateKeyA" _
(ByVal hKey As Long, _
ByVal lpszSubKey As String, _
phkResult As Long) _
As Long
Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal Reserved As Long, _
ByVal lpClass As String, _
ByVal dwOptions As Long, _
ByVal samDesired As Long, _
lpSecurityAttributes As Any, _
phkResult As Long, lpdwDisposition As Long) _
As Long
Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String) _
As Long
Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" _
(ByVal hKey As Long, _
ByVal lpValueName As String) _
As Long
Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) _
As Long
Declare Function RegEnumKeyEx Lib "advapi32" Alias "RegEnumKeyA" _
(ByVal hKey As Long, _
ByVal iSubKey As Long, _
ByVal lpszName As String, _
ByVal cchName As Long) _
As Long
Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpszSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) _
As Long
Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" _
(ByVal hKey As Long, _
ByVal lpszValueName As String, _
ByVal dwReserved As Long, _
lpdwType As Long, _
lpbData As Any, _
cbData As Long) _
As Long
Declare Function RegSetValueEx Lib "advapi32" Alias "RegSetValueExA" _
(ByVal hKey As Long, _
ByVal lpszValueName As String, _
ByVal dwReserved As Long, _
ByVal fdwType As Long, _
lpbData As Any, _
ByVal cbData As Long) _
As Long
Declare Function RegSetStringEx Lib "advapi32" Alias "RegSetValueExA" _
(ByVal hKey As Long, _
ByVal lpszValueName As String, _
ByVal dwReserved As Long, _
ByVal fdwType As Long, _
lpbData As String, _
ByVal cbData As Long) _
As Long
Declare Function GetCurrentProcessId Lib "Kernel32" () As Long
The following code will create a new item in the system registry:
Function CreateRegEntry(pDatatype As Long, _
KeyToAdd As Variant, _
ValueToAdd As Variant) As Boolean
On Local Error GoTo CreateRegEntry_Err
' ***********************************************
' Declare local usage variables.
' ***********************************************
Dim lResult As Long, i As Integer, Msg As String
Dim strMyKeyFull As String, MyKeyName As String
Dim MyKeyValueLng As Long, MyKeyValueStr As String
Dim MyDataType As Long, phkResult As Long, IsNewKey As Long
' ***********************************************
' Set path to your application's settings.
' ***********************************************
lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_APP_KEYS_PATH, 0&, _
REG_SZ, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, _
ByVal 0&, phkResult, IsNewKey)
If Not (lResult = ERROR_SUCCESS) Then
CreateRegEntry = False
Msg = "Error Creating Registry Key Entry:" & vbCrLf
Msg = Msg & "Key=" & strMyKeyFull & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, App.Title
GoTo CreateRegEntry_End
End If
' ***********************************************
' Determine data type and use appropriate
' passed value.
' ***********************************************
Select Case pDatatype
Case REG_DWORD
MyKeyValueLng = ValueToAdd
lResult = RegSetValueEx(phkResult, KeyToAdd, _
ByVal 0&, pDatatype, _
MyKeyValueLng, Len(MyKeyValueLng))
Case REG_SZ
MyKeyValueStr = ValueToAdd
lResult = RegSetValueEx(phkResult, KeyToAdd, _
ByVal 0&, pDatatype, _
ByVal MyKeyValueStr, Len(MyKeyValueStr))
End Select
If Not (lResult = ERROR_SUCCESS) Then
CreateRegEntry = False
Msg = "Error Creating Registry Key Entry:" & vbCrLf
Msg = Msg & "Key=" & KeyToAdd & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, App.Title
GoTo CreateRegEntry_End
End If
CreateRegEntry = True
CreateRegEntry_End:
Exit Function
CreateRegEntry_Err:
MsgBox Error.Description, vbOKOnly Or vbExclamation, App.Title
Resume CreateRegEntry_End
End Function
The following code will delete an existing item in the system registry:
Function DeleteAllAppRegEntries() As Boolean
On Local Error GoTo DeleteAllAppRegEntries_Err
' ***********************************************
' Declare local usage variables.
' ***********************************************
Dim lResult As Long, Msg As String
Dim hKey As Long
' ***********************************************
' Open the application's path key.
' ***********************************************
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
REG_APP_KEYS_PATH, _
ByVal 0&, KEY_ALL_ACCESS, hKey)
If Not (lResult = ERROR_SUCCESS) Then
DeleteAllAppRegEntries = False
Msg = "Error Opening Registry Key Entry:" & vbCrLf
Msg = Msg & "Key/Path=" & REG_APP_KEYS_PATH & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
GoTo DeleteAllAppRegEntries_End
End If
' ***********************************************
' Delete the entire application's path key and any
' associated keys and values.
' ***********************************************
lResult = RegDeleteKey(hKey, "")
If Not (lResult = ERROR_SUCCESS) Then
DeleteAllAppRegEntries = False
Msg = "Error Deleting Registry Key Entry:" & vbCrLf
Msg = Msg & "Key=" & REG_APP_KEYS_PATH & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
GoTo DeleteAllAppRegEntries_End
End If
lResult = RegCloseKey(hKey)
DeleteAllAppRegEntries = True
DeleteAllAppRegEntries_End:
Exit Function
DeleteAllAppRegEntries_Err:
MsgBox Error.Description, vbOKOnly Or vbExclamation, "YourAppName"
Resume DeleteAllAppRegEntries_End
End Function
The following code will return a value from an existing item in the system registry:
Function GetAppRegValue(WhatKey As String, _
KeyDataType As Variant, _
KeyValue As Variant, _
IsVerbose As Integer) As Boolean
On Local Error GoTo GetAppRegValue_Err
' ***********************************************
' Declare local usage variables.
' ***********************************************
Dim lResult As Long, dwResult As Long
Dim dwType As Long, cbData As Long
Dim varStrData As String, varLngData As Long
Dim Msg As String
' ***********************************************
' Open the key for application's path.
' ***********************************************
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
REG_APP_KEYS_PATH, _
ByVal 0&, KEY_ALL_ACCESS, dwResult)
If Not (lResult = ERROR_SUCCESS) Then
GetAppRegValue = False
If IsVerbose Then
Msg = "Error Opening Registry Key Entry:" & vbCrLf
Msg = Msg & "Key/Path=" & REG_APP_KEYS_PATH & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
End If
GoTo GetAppRegValue_End
End If
' ***********************************************
' Set up passed variables and retrieve value.
' ***********************************************
Select Case KeyDataType
Case REG_SZ
varStrData = String$(255, 0)
cbData = Len(varStrData)
lResult = RegQueryValueEx(dwResult, WhatKey, ByVal 0&, _
dwType, ByVal varStrData, cbData)
Case REG_DWORD
varLngData = False
cbData = Len(varLngData)
lResult = RegQueryValueEx(dwResult, WhatKey, ByVal 0&, _
dwType, varLngData, cbData)
End Select
If Not (lResult = ERROR_SUCCESS) Then
GetAppRegValue = False
If IsVerbose Then
Msg = "Error Retrieving Registry Key Entry:" & vbCrLf
Msg = Msg & "Key=" & WhatKey & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
End If
lResult = RegCloseKey(dwResult)
GoTo GetAppRegValue_End
End If
' ***********************************************
' Close key.
' ***********************************************
lResult = RegCloseKey(dwResult)
' ***********************************************
' Select data type (for the needed types
' used in the values) and assign value.
' ***********************************************
Select Case dwType
Case REG_NONE
KeyValue = vbNull
Case REG_SZ
KeyValue = Left$(varStrData, cbData)
Case REG_DWORD
KeyValue = varLngData
Case Else
KeyValue = vbNull
End Select
GetAppRegValue = True
Debug.Print KeyValue
GetAppRegValue_End:
Exit Function
GetAppRegValue_Err:
MsgBox Error.Description, vbOKOnly Or vbExclamation, "YourAppName"
Resume GetAppRegValue_End
End Function
The following code will return a value from an existing item in the system registry:
Function SetAppRegValue(WhatKey As String, _
KeyDataType As Variant, _
NewKeyValue As Variant) _
As Boolean
On Local Error GoTo SetAppRegValue_Err
' ***********************************************
' Declare local usage variables.
' ***********************************************
Dim lResult As Long, dwResult As Long
Dim dwType As Long, cbData As Long
Dim varStrData As String, varLngData As Long
Dim Msg As String
' ***********************************************
' Open the key for application's path.
' ***********************************************
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
REG_APP_KEYS_PATH, _
ByVal 0&, KEY_ALL_ACCESS, dwResult)
If Not (lResult = ERROR_SUCCESS) Then
SetAppRegValue = False
Msg = "Error Opening Registry Key Entry:" & vbCrLf
Msg = Msg & "Key/Path=" & REG_APP_KEYS_PATH & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
GoTo SetAppRegValue_End
End If
' ***********************************************
' Set up passed variables and retrieve value.
' ***********************************************
Select Case KeyDataType
Case REG_SZ
varStrData = NewKeyValue
lResult = RegSetValueEx(dwResult, WhatKey, _
ByVal 0&, KeyDataType, _
ByVal varStrData, Len(varStrData))
Case REG_DWORD
varLngData = CLng(NewKeyValue)
lResult = RegSetValueEx(dwResult, WhatKey, _
ByVal 0&, KeyDataType, _
varLngData, Len(varLngData))
End Select
If Not (lResult = ERROR_SUCCESS) Then
SetAppRegValue = False
Msg = "Error Setting Registry Key Entry:" & vbCrLf
Msg = Msg & "Key=" & WhatKey & vbCrLf
Msg = Msg & "DLL Returned=" & Format$(lResult)
MsgBox Msg, vbOKOnly Or vbExclamation, "ODBC Registry"
lResult = RegCloseKey(dwResult)
GoTo SetAppRegValue_End
End If
' ***********************************************
' Close key.
' ***********************************************
lResult = RegCloseKey(dwResult)
SetAppRegValue = True
SetAppRegValue_End:
Exit Function
SetAppRegValue_Err:
MsgBox Error.Description, vbOKOnly Or vbExclamation, "YourAppName"
Resume SetAppRegValue_End
End Function
Once you have implemented these functions in your database or wizard, you can begin to use the capabilities to manipulate the registry. Take, for example, a routine that runs each time you load your database as part of the startup:
Dim KeyValue As String
' *******************************************
' DSN name
' *******************************************
If Not GetAppRegValue("DSN", _
REG_SZ, _
KeyValue, _
False) Then
' Not yet made, create.
If Not CreateRegEntry(REG_SZ, _
"DSN", _
"My SQL Database") Then
' Error
End If
End If
The code above tests whether a registry entry exists and, if not, creates that key with a default value.
The path to store your registry entries should follow the convention of your company name and, specifically, the application name. These values are set as part of the constants in the General Declarations section of the code:
Public Const AppReg = "MyAppName"
Private Const REG_APP_KEYS_PATH = "Software\MYApps\" & AppReg
This makes it easy to troubleshoot the registry. Keep in mind that the registry is a significant database; you need to make it as easy as possible to find your entries.
If you follow the convention, outlined previously, of executing the check for the existence of your registry keys upon application startup, you can be reasonably assured that you will be modifying existing entries in the registry.
The following simple code captures the value entered in a text box and saves it:
' Save DSN.
strSaveVal = Me!txtConfigLookups1
If Not SetODBCRegValue("DSN", _
REG_SZ, _
strSaveVal) Then
' Error.
End If
As a courtesy, you may want to consider a method to clean up the entries you have created in the registry.
The following code deletes existing registry entries:
' Delete your registry key.
If Not DeleteAllAppRegEntries() Then
' error
End If