Шаг 9 - Наш реестр данных

Со временем, у каждого разработчика возникает вопрос, куда записывать служебную информацию ? Всевозможные настройки интерфейса, индивидуальные данные для пользователей и т.п. Одни пишут это в текстовые файлы, другие сохраняют переменные памяти в файлах и т.д.

Мы уже увидели, что VFP хранит очень много служебной информации в таблицах. Даже библиотеки классов - таблицы.

Пора и нам создать свою собственную базу данных для системной информации нашего приложения. Создаем папку System(если она еще не создана) в папке нашего проекта. В окне проекта на закладке Data создаем базу данных D_SYSTEM. Добавляем в нее таблицу T_Registry следующей структуры:

T_REGISTRY
НаименованиеТипШиринаДесятичные знаки 
FldStrKeyChar100 Ключ поиска
FldStrTypeChar1 Тип данных
FldStrChar250 Строка данных
FldIntInt  Целое число
FldLogLog  Логическое
FldDateTimeDateTime  Дата и время
FldNumNum206Цифровое
FldIntIdentityInt  Уникальный код

По полю FldStrKey необходимо создать индекс с именем TAG_KEY типа Primary, чтобы обеспечить уникальность записей. Об индексах расскажу далее.

Чем наше приложение хуже Windows !!! У нас теперь есть свой реестр. Для работы с ним создадим несколько функций.

Прежде, чем что-то получить, его надо записать. Пишем функцию SetRegistry():

*
* function SetRegistry
* передаем в функцию ключ, тип и значение
  lparameters strLocPrmKey, strLocPrmType, voidLocPrmValue
*
  local logLocReturn, strLocKey
  logLocReturn = .F.
* преобразовываем строку ключа в верхний регистр
* и дополняем пробелами до длины поля FldStrKey,
* предварительно, функцией alltrim() убираем возможные
* пробелы (ошибки при написании кода)
  strLocKey = padr(upper(alltrim(strLocPrmKey)),100)
* открываем таблицу или проверяем, что она открыта (см. ниже)
  if (OpenTable(".\System\T_Registry.DBF", "AliasSystemRegistry") > 0)
* проверяем наличие ключа в таблице самым быстрым способом
* для файл-серверного варианта нашего приложения
* если нет такой записи - добавляем ее
    if .not. seek(strLocKey,"AliasSystemRegistry","TAG_KEY")
      insert into AliasSystemRegistry (FldStrKey, FldStrType) ;
           values (strLocPrmKey, strLocPrmType)
    endif
* проверяем ключ
    if (AliasSystemRegistry.FldStrKey = strLocKey)
* записываем наши данные в реестр
       do case
           case strLocPrmType = "C"
               replace FldStr with voidLocPrmValue
           case strLocPrmType = "I"
               replace FldInt with voidLocPrmValue
           case strLocPrmType = "L"
               replace FldLog with voidLocPrmValue
           case strLocPrmType = "N"
               replace FldNum with voidLocPrmValue
           case strLocPrmType = "D"
               replace FldDateTime with voidLocPrmValue
       endcase
* возвращаем TRUE
       logLocReturn = .T.
     endif
   endif
return logLocReturn
*

К системному реестру нашего приложения мы будем обращаться постоянно. Поэтому, псевдоним задаем постоянный, а не получаем функцией GetNewAlias(). Функцию OpenTable() необходимо дополнить кодом проверки открытого псевдонима с возвратом рабочей области :

*
#INCLUDE .\Include \Define.H
*
* function OpenTable
* передаем имя таблицы или путь к ней и псевдоним
  lparameters strLocPrmTable, strLocPrmAlias
  local intLocReturnWorkArea, intLocCount, objLocWorkArea
* инициализируем код возврата
  intLocReturnWorkArea = 0
* проверка псевдонима
  if used(strLocPrmAlias)
* инициализируем код возврата номером рабочей области
    intLocReturnWorkArea = select(strLocPrmAlias)
  else
* весь предыдущий код
::::::
:::..
   endif
return intLocReturnWorkArea
*

Теперь пишем функцию чтения из реестра GetRegistry():

*
* function GetRegistry
  lparameters strLocPrmKey, strLocPrmType, voidLocPrmValue
  local voidLocReturn, strLocKey
  strLocKey = padr(upper(alltrim(strLocPrmKey)),100)
  if (OpenTable(".\System\T_Registry.DBF", "AliasSystemRegistry") > 0)
    if .not. seek(strLocKey,"AliasSystemRegistry","TAG_KEY")
* если нет записи - используем функцию SetRegistry() !!!
      SetRegistry(strLocPrmKey, strLocPrmType, voidLocPrmValue)
    endif
    if (AliasSystemRegistry.FldStrKey = strLocKey)
* читаем наши данные из реестра и записываем в переменную возврата
      do case
        case strLocPrmType = "C"
           voidLocReturn = AliasSystemRegistry .FldStr
        case strLocPrmType = "I"
           voidLocReturn = AliasSystemRegistry .FldInt
        case strLocPrmType = "L"
           voidLocReturn = AliasSystemRegistry .FldLog
        case strLocPrmType = "N"
           voidLocReturn = AliasSystemRegistry .FldNum
        case strLocPrmType = "D"
           voidLocReturn = AliasSystemRegistry .FldDateTime
     endcase
   endif
endif
return voidLocReturn
*

Теперь мы имеем возможность сохранять любые наши данные. Функциональность таблицы T_REGISTRY можно расширить добавлением соответствующих полей. Примеры использования:

* при входе пользователя в программу
GetRegistry("User001.MainWindow.Top","I",0)
GetRegistry("User001.MainWindow.Left","I",0)
GetRegistry("User001.MainWindow.Height","I",400)
GetRegistry("User001.MainWindow.Width","I",400)
GetRegistry("User001.LastDate","D",datetime())
* при выходе пользователя из программы
SetRegistry("User001.MainWindow.Top","I",_SCREEN.Top)
SetRegistry("User001.MainWindow.Left","I",_SCREEN.Left)
SetRegistry("User001.MainWindow.Height","I",_SCREEN.Height)
SetRegistry("User001.MainWindow.Width","I",_SCREEN.Width)
SetRegistry("User001.LastDate","D",datetime())
*

Обратите внимание, что наш реестр самозаполняемый !!! Вы можете использовать функцию GetRegistry() без предварительной записи ключей, а значение (третий параметр) будет значением по умолчанию !!!


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Сергей Платонов.