Программирование на Visual Basic

visual basic реестр

    В ранних версиях 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 LongPrivate 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 = &H80000003End 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 ThenGetString = Left$(sData, lDlen - 1)ElseGetString = vbNullStringEnd 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"~~~~~~.DeleteKeyPublic Sub DeleteKey( _   ByVal HomeKey As HKEY_CONSTANTS, _   ByVal KeyName As String)"результат APi функцииDim lres As Long"Удаляем раздел из корневогоlres = RegDeleteKey(HomeKey, KeyName)End Sub

Как Вы наверное заметили, я сохранял результат работы API функций во всех процедурахи функциях, а проверял только в некоторых. Вообще рекомендуется проверять результат всегда, если дело касается каких-то изменений в системе, но я пытался создать код минимального размера, и сэкономил на проверке, особой беды нет - класс работает и неплохо. Но на всякийслучай возьмите на заметку. А здесь находится исходник класса для работы с реестром.

Hosted by uCoz