Хранение пользовательских типов данных. Часть 3.3. Реестр.
На данный момент уже рассмотрены варианты хранения данных в файлах: и dat, и ini. Такой метод хранения оправдан, например, для каталогов (как пример можно рассмотреть программу "Прокат" В.Кондрата, которую достаточно долго и успешно модифицировали участники dwg.ru); или для небольших порций достаточно редко меняющихся данных.
А как быть, если данные, к примеру, должны еще и относиться к определенному профилю AutoCAD? Не, можно, конечно, организовать отдельный каталог с именем профиля, где и хранить соответствующие настройки, или еще как-то извернуться. В некоторых случаях подобное решение оправдано, но за ради интересу сходим иным путем и рассмотрим хранение данных в реестре.
На самом деле все не просто, а очень просто. В реестре существует несколько базовых понятий: ветка, ключ, переменная и значение. Посмотреть на реестр машины тоже несложно: Пуск - Выполнить - regedit.
Вот пример реестра Windows (картинка кликабельна). Видны ветки HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS и HKEY_CURRENT_CONFIG. О назначении каждой из этих веток можно прочитать в соответствующей литературе, а нам достаточно знать о некоторых тонкостях HKEY_CURRENT_USER (далее HKCU) и HKEY_LOCAL_MACHINE (HKLM).
Поскольку мы будем хранить там данные, интересует возможность прежде всего записи в эти ветки. Так вот, в HKLM записывать может только администратор компьютера или программы, запущенные от его имени. Сходу отметать эту ветку не стоит, там может храниться информация, например, о каталогах установки собственного комплекса приложений (естественно, что записывается туда она не сама собой, а соответствующим инсталлятором, который и запускает администратор. Но это тема абсолютно отдельного разговора). Для наших задач практически идеально подходит вариант хранения данных в HKCU. Точнее, в одной из его подветок.
Прежде всего, надо подумать: хранимые данные могут различаться для разных профилей AutoCAD или нет? Если нет, то проще всего выделить в HKCU/Software собственную подветку и писать туда. Если же это не так, то придется выделять собственную подветку в HKCU/Software/Autodesk/AutoCAD-и-так-далее/Profiles/Имя-профиля.
Где хранить - вроде бы разобрались. Теперь поговорим о том, что хранить. Точнее, о том, что хранить можно, а что не получится ни в какую.
Хранить можно несколько типов данных, но нас будут интересовать следующие:
- Строковый параметр (REG_SZ). Возможен вариант использования REG_EXPAND_SZ (строка с переменной длиной), но VisualLISP позволяет записывать только REG_SZ.
- Целочисленный тип (REG_DWORD). Не поддерживает отрицательные значения
К сожалению, типов ни для отрицательных чисел, ни для нецелых чисел, ни для списков или массивов не предусмотрено. Придется "извращаться".
Для работы с реестром в VisualLISP предусмотрено несколько функций: vl-registry-delete, vl-registry-descendents, vl-registry-read и vl-registry-write. Предназначение каждой из них в общем-то понятно - удаление, получение списка подчиненных веток (узлов) и ключей, чтение и запись.
Имя функции | Предназначение | Параметры вызова | Возвращаемое значение |
vl-registry-read | Чтение данных из указанного ключа реестра. | Узел реестра и наименование ключа. Регистр значения не имеет | В случае успеха возвращает прочитанное значение; в случае ошибки - nil |
vl-registry-descendents | Чтение имен подветок или ключей указанного "родителя" | Имя "родителя"; возможно наличие второго параметра - читать названия подветок или нет. Если второй параметр указан и не nil, выполняется чтение только ключей. Если же второй параметр не указан, читаются имена подветок. | Список из имен подветок или ключей |
vl-registry-write | Записывает в указанную ветку значение ключа | Полный адрес ветки, название ключа и записываемое значение | В случае успеха возвращает записываемое значение; в случае ошибки - nil |
Проведем небольшой эксперимент. Выполним код
1 2 | _$ (vl-registry-write "HKEY_CURRENT_USER\\Software\\LispRu\\Test\\Key" "Value" 1) 1 |
Если сейчас зайти в редактор реестра, мы увидим, что был создана ветка, в ней - ключ и ключу присвоено значение типа REG_DWORD, равное 1.
Соответствующим образом можно сохранять и строки, если интересно - сделайте самостоятельно
Что самое интересное и удобное по сравнению с файловым хранилищем - не надо мучаться с тем, чтобы создавать весь путь ключа, он создается автоматически.
Подобным образом можно создать сколь угодно сложную структуру ключей и значений, каждый из которых будет отвечать за свою часть программы. Так, например, именно в реестре наиболее удобно хранить "значения по умолчанию для диалоговых окон".
Конечно, не обошлось и без ложки дегтя в этой бочке меда. Ну, насчет типов данных уже было сказано. Конечно, можно для отрицательных чисел и списков на самом деле использовать строковые значения, к которым потом применять read, но... Но в некоторых случаях (по-моему, на Windows 2000 такое еще встречалось, в более поздних версиях уже не помню) длина строкового параметра не может превышать 255 символов. То есть записаться-то оно запишется, но вот как прочитается - еще вопрос.
Так что для длинных строк лично я стараюсь реестр не использовать.
P.S. У меня ощущение, что еще и для AutoCAD 32bit, запущенном на 64-разрядной ОС, тоже не все будет гладко, но пока "в лоб" не сталкивался. Если у кого будет информация - прошу поделиться.