Реестр и Windows API
В ранних версиях Windows, все её приложения хранили необходимую для запуска и работы информацию в файлах инициализации. С развитием ОС информации, необходимой для сохранения стало так много, что возникла необходимость в новом способе её хранения — реестре. Реестр, — это своеобразная база данных для приложений Windows. Его структура напоминает файловую систему. (не верите посмотрите через regedit.exe только ничего не меняйте). Вообще реестр считают несомненной альтернативой INI-файлам, но я думаю, что эти две технологии имеют наибольшую мощность только при их совмещении.
В Visual Basic есть функции для работы с реестром( GetSetting,SaveSetting) но их возможности ограничены. Они могут работать с реестром только в разделе HKEY_CURRENT_USER\Software\VB and VBA Programms, и способны только читать и записывать. Для начинающего программиста это неплохо, даже хорошо — меньше возможностей навредить.На самом деле Windows может намного больше. Расширить возможности VB, позволяет Windows API.
Windows обладает большим набором функций для работы с реестром, сами по себе GetSetting и SaveSetting тоже вызывают их. С помощью этих функций, вы можете создавать разделы, в любой части реестра, а затем удалять их :), подключать реестр через сеть, сохранять разделы в файле и т.д.
В качестве примера, мы создадим класс, для работы с реестром через Windows API (насколько я знаю в Borland Delphi, нечто подобное уже есть, и один знакомый программист очень этим гордится 🙂 ). Этот класс может работать только со строковыми данными. Я посчитал, что если Вам понадобится больше, Вы сможете сделать это сами. Кроме того класс даёт возможность удалять лишние разделы, и параметры. Работу с реестром через сеть, и остальные возможности я исключил, так как этот класс задуман как расширение Basic’овских функций для работы с реестром. Остальные операции будут заключены в другой класс, который должен будет реализовать все возможности Windows API в работе с реестром.
Итак, хватит лирики, приступим к работе. Создадим новый модуль класса и назовём его RegistryExClass(совсем как в API, RegSetValue,RegSetValueEx). После этого приступим к объявлению необходимых функций.Я рассмотрю только особенные, остальные найдёте в API Text Viewer. (RegOpenKey, RegDeleteValue, RegDeleteKey, RegCloseKey, RegCreateKey)
Private Declare Function RegQueryValueExS Lib «advapi32.dll» _
Alias «RegQueryValueExA» ( _
ByVal hkey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
ByVal lpData As String, _
lpcbData As Long) As Long
Private Declare Function RegSetValueExS Lib «advapi32.dll» _
Alias «RegSetValueExA» ( _
ByVal hkey As Long, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
ByVal lpData As String, _
ByVal cbData As Long) As Long
Что здесь особенного, спросите Вы. Объясняю: Как я уже сказал мой класс работает только со строками. Приведённые выше функции, в оригинальном объявлении не имеют чётко определённого типа данных(lpData As Any). При попытке использовать такое объявление, я получал ошибку «Out Of Memory». Как видно в листинге, я объявил lpData как строку, хотя имею возможность присвоить любой тип. Беда в том, что VB не поймёт Вас при попытке объявить две функции. Чтобы обойти это, я и объявил функции с оконаниями «-S». И теперь в класс можно будет добавить ещё функции для работы с различными типами.
Ещё по той же теме. Некоторые функции для работы с реестром имеют параметры типа SECURITY_ATTRIBUTES. Если эти параметры Вам не нужны, то объявите их как Long, и передавайте ноль.
Теперь объявим константы.
‘Объявив эти константы таким способом, Вы дадите
‘пользователю класса возможность выбирать из списка
‘значение параметра
Public Enum HKEY_CONSTANTS
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_CONFIG = &H80000005
HKEY_CURRENT_USER = &H80000001
HKEY_DYN_DATA = &H80000006
HKEY_LOCAL_MACHINE = &H80000002
HKEY_PERFORMANCE_DATA = &H80000004
HKEY_USERS = &H80000003
End Enum
‘Ну ещё константа, для строкового типа
Private Const REG_SZ = 1
Теперь создадим методы для чтения/записи параметров
.GetString Функция
Public Function GetString( _
ByVal HomeKey As HKEY_CONSTANTS, _
ByVal KeyName As String, _
ByVal ValueName As String) As String
‘Handle раздела реестра
Dim hkey As Long
‘переменная для хранения значения
Dim sData As String
‘Результат работы API функций
Dim lres As Long
‘Тип возвращаемого значения
Dim lDataType As Long
‘переменная для хранения длины строки
Dim lDlen As Long
‘Открываем Раздел
lres = RegOpenKey(HomeKey, KeyName, hkey)
‘Если вернулся не ноль — ошибка, выходим
If lres <> 0 Then GetRegString = vbNullString: Exit Function
‘Продолжаем, заполняем строку пробелами.
sData = String$(64, 32) & Chr$(0)
lDlen = Len(sData)
‘Читаем значение
lres = RegQueryValueExS(hkey, ValueName, 0, lDataType, sData, lDlen)
‘опять проверка на ошибку
If lres <> 0 Then GetRegString = vbNullString: Exit Function
‘проверяем тип полученных данных
If lDataType = REG_SZ Then
GetString = Left$(sData, lDlen — 1)
Else
GetString = vbNullString
End If
‘и закрываем раздел
lres = RegCloseKey(hkey)
End Function
.SaveString Метод
Public Sub SaveString( _
ByVal HomeKey As HKEY_CONSTANTS, _
ByVal KeyName As String, _
ByVal ValueName As String, _
ByVal Data As String)
‘Handle для корневого раздела
Dim hkey As Long
‘Handle для изменяемого раздела
Dim hSubKey As Long
‘Результат работы функции
Dim lres As Long
‘Открываем корневой раздел
lres = RegOpenKey(HomeKey, vbNullString, hkey)
‘Создаём(если есть открываем) нужный раздел
lres = RegCreateKey(HomeKey, KeyName, hSubKey)
‘Пишем данные
lres = RegSetValueExS(hSubKey, ValueName, 0, _
REG_SZ, Data + Chr$(0), Len(Data) + 1)
‘и закрываем всё открытое
lres = RegCloseKey(hSubKey)
lres = RegCloseKey(hkey)
End Sub
Метод GetString всего лишь читает параметр из реестра. SaveString — имеет больше возможностей. С его помощью Вы можете создать пустой раздел. Для этого вызовите его, установив значение ValueName и Data равное пустой строке. Если хотите установить для раздела значение по умолчанию присвойте Data нужное значение, при нулевом(vbNullString) ValueName.
Теперь поработаем с удалением.
.DeleteValue Метод
Public Sub DeleteValue( _
ByVal HomeKey As HKEY_CONSTANTS, _
ByVal KeyName As String, _
ByVal ValueName As String)
‘Handle для изменяемого раздела
Dim hkey As Long
‘Результат API функции
Dim lres As Long
‘открываем нужные раздел
lres = RegOpenKey(HomeKey, KeyName, hkey)
‘проверяем на ошибку
If lres <> 0 Then Exit Sub
‘удаляем параметр
lres = RegDeleteValue(hkey, ValueName)
‘закрываем
lres = RegCloseKey(hkey)
End Sub
.DeleteKey
Public Sub DeleteKey( _
ByVal HomeKey As HKEY_CONSTANTS, _
ByVal KeyName As String)
‘результат APi функции
Dim lres As Long
‘Удаляем раздел из корневого
lres = RegDeleteKey(HomeKey, KeyName)
End Sub
Как Вы наверное заметили, я сохранял результат работы API функций во всех процедурах и функциях, а проверял только в некоторых. Вообще рекомендуется проверять результат всегда, если дело касается каких-то изменений в системе, но я пытался создать код минимального размера, и сэкономил на проверке, особой беды нет — класс работает и неплохо. Но на всякий случай возьмите на заметку. Вот в общем-то и всё, что я хотел сообщить Вам о работе с реестром. Весь код я скопировал в прямо из VB-редактора, так что он должен работать, если что удалите лишние подчёркивания.
Registry Functions
The following are the registry functions.
Function | Description |
---|---|
GetSystemRegistryQuota | Retrieves the current size of the registry and the maximum size that the registry is allowed to attain on the system. |
RegCloseKey | Closes a handle to the specified registry key. |
RegConnectRegistry | Establishes a connection to a predefined registry handle on another computer. |
RegCopyTree | Copies the specified registry key, along with its values and subkeys, to the specified destination key. |
RegCreateKeyEx | Creates the specified registry key. |
RegCreateKeyTransacted | Creates the specified registry key and associates it with a transaction. |
RegDeleteKey | Deletes a subkey and its values. |
RegDeleteKeyEx | Deletes a subkey and its values from the specified platform-specific view of the registry. |
RegDeleteKeyTransacted | Deletes a subkey and its values from the specified platform-specific view of the registry as a transacted operation. |
RegDeleteKeyValue | Removes the specified value from the specified registry key and subkey. |
RegDeleteTree | Deletes the subkeys and values of the specified key recursively. |
RegDeleteValue | Removes a named value from the specified registry key. |
RegDisablePredefinedCache | Disables handle caching for the predefined registry handle for HKEY_CURRENT_USER for the current process. |
RegDisablePredefinedCacheEx | Disables handle caching for all predefined registry handles for the current process. |
RegDisableReflectionKey | Disables registry reflection for the specified key. |
RegEnableReflectionKey | Enables registry reflection for the specified disabled key. |
RegEnumKeyEx | Enumerates the subkeys of the specified open registry key. |
RegEnumValue | Enumerates the values for the specified open registry key. |
RegFlushKey | Writes all attributes of the specified open registry key into the registry. |
RegGetKeySecurity | Retrieves a copy of the security descriptor protecting the specified open registry key. |
RegGetValue | Retrieves the type and data for the specified registry value. |
RegLoadKey | Creates a subkey under HKEY_USERS or HKEY_LOCAL_MACHINE and stores registration information from a specified file into that subkey. |
RegLoadMUIString | Loads the specified string from the specified key and subkey. |
RegNotifyChangeKeyValue | Notifies the caller about changes to the attributes or contents of a specified registry key. |
RegOpenCurrentUser | Retrieves a handle to the HKEY_CURRENT_USER key for the user the current thread is impersonating. |
RegOpenKeyEx | Opens the specified registry key. |
RegOpenKeyTransacted | Opens the specified registry key and associates it with a transaction. |
RegOpenUserClassesRoot | Retrieves a handle to the HKEY_CLASSES_ROOT key for the specified user. |
RegOverridePredefKey | Maps a predefined registry key to a specified registry key. |
RegQueryInfoKey | Retrieves information about the specified registry key. |
RegQueryMultipleValues | Retrieves the type and data for a list of value names associated with an open registry key. |
RegQueryReflectionKey | Determines whether reflection has been disabled or enabled for the specified key. |
RegQueryValueEx | Retrieves the type and data for a specified value name associated with an open registry key. |
RegReplaceKey | Replaces the file backing a registry key and all its subkeys with another file. |
RegRestoreKey | Reads the registry information in a specified file and copies it over the specified key. |
RegSaveKey | Saves the specified key and all of its subkeys and values to a new file. |
RegSaveKeyEx | Saves the specified key and all of its subkeys and values to a new file. You can specify the format for the saved key or hive. |
RegSetKeyValue | Sets the data for the specified value in the specified registry key and subkey. |
RegSetKeySecurity | Sets the security of an open registry key. |
RegSetValueEx | Sets the data and type of a specified value under a registry key. |
RegUnLoadKey | Unloads the specified registry key and its subkeys from the registry. |
The following shell functions can be used with the registry:
The following are the initialization-file functions. They retrieve information from and copy information to a system- or application-defined initialization file. These functions are provided only for compatibility with 16-bit versions of Windows. New applications should use the registry.
Function | Description |
---|---|
GetPrivateProfileInt | Retrieves an integer associated with a key in the specified section of an initialization file. |
GetPrivateProfileSection | Retrieves all the keys and values for the specified section of an initialization file. |
GetPrivateProfileSectionNames | Retrieves the names of all sections in an initialization file. |
GetPrivateProfileString | Retrieves a string from the specified section in an initialization file. |
GetPrivateProfileStruct | Retrieves the data associated with a key in the specified section of an initialization file. |
GetProfileInt | Retrieves an integer from a key in the specified section of the Win.ini file. |
GetProfileSection | Retrieves all the keys and values for the specified section of the Win.ini file. |
GetProfileString | Retrieves the string associated with a key in the specified section of the Win.ini file. |
WritePrivateProfileSection | Replaces the keys and values for the specified section in an initialization file. |
WritePrivateProfileString | Copies a string into the specified section of an initialization file. |
WritePrivateProfileStruct | Copies data into a key in the specified section of an initialization file. |
WriteProfileSection | Replaces the contents of the specified section in the Win.ini file with specified keys and values. |
WriteProfileString | Copies a string into the specified section of the Win.ini file. |
Obsolete Functions
These functions are provided only for compatibility with 16-bit versions of Windows: