Хранение пользовательских типов данных. Часть 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/Имя-профиля.

Где хранить - вроде бы разобрались. Теперь поговорим о том, что хранить. Точнее, о том, что хранить можно, а что не получится ни в какую.

Хранить можно несколько типов данных, но нас будут интересовать следующие:

  1. Строковый параметр (REG_SZ). Возможен вариант использования REG_EXPAND_SZ (строка с переменной длиной), но VisualLISP позволяет записывать только REG_SZ.
  2. Целочисленный тип (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-разрядной ОС, тоже не все будет гладко, но пока "в лоб" не сталкивался. Если у кого будет информация - прошу поделиться.

Размещено в Код LISP, Функции LISP · Метки: , ,



Поделитесь своим мнением


Я не робот.