Со временем, у каждого разработчика возникает вопрос, куда записывать служебную информацию ? Всевозможные настройки интерфейса, индивидуальные данные для пользователей и т.п. Одни пишут это в текстовые файлы, другие сохраняют переменные памяти в файлах и т.д.
Мы уже увидели, что VFP хранит очень много служебной информации в таблицах. Даже библиотеки классов - таблицы.
Пора и нам создать свою собственную базу данных для системной информации нашего приложения. Создаем папку System(если она еще не создана) в папке нашего проекта. В окне проекта на закладке Data создаем базу данных D_SYSTEM. Добавляем в нее таблицу T_Registry следующей структуры:
Наименование | Тип | Ширина | Десятичные знаки | |
---|---|---|---|---|
FldStrKey | Char | 100 | Ключ поиска | |
FldStrType | Char | 1 | Тип данных | |
FldStr | Char | 250 | Строка данных | |
FldInt | Int | Целое число | ||
FldLog | Log | Логическое | ||
FldDateTime | DateTime | Дата и время | ||
FldNum | Num | 20 | 6 | Цифровое |
FldIntIdentity | Int | Уникальный код |
По полю 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() без предварительной записи ключей, а значение (третий параметр) будет значением по умолчанию !!!