Работа с регистъра в Delphi

0
289

По времето на Windows 3.1 програмите записваха своите настройки във файлове с разширение .ini. С появата на Windows 95 и по-късните версии обаче, все повече програми започнаха да използват за запис на настройките си регистъра на Windows. Регистъра на Windows се превърна в обща база данни с настройките на всички инсталирани програми. Но освен че е удобно място за съхранение на информацията, необходима на дадена програма, регистъра съдържа и настройките на самия Windows и затова работата с него е задължителна, ако искате приложението ви да се интегрира с операционната система. Най-простия пример за това е факта, че в регистъра се записва с кои файлове с коя програма се отваря и ако искате при двукратно щракване с мишката върху дукомент, създаден от вашата програма, той да се отваря, трябва да добавите съответния запис в регистъра. Обикновено това се прави при инсталацията на програмата, но ако сте създали програма за работа с често използван формат файлове (например .html), тогава е добре да предоставите на потребителите възможността да ги асоциират с програмата си от самата програма – в противен случай инсталацията на друг HTML редактор например може да замени програмата по подразбиране за отваряне на HTML документи и да принуди потребителя да преинсталира вашия продукт за да върне настройките както трябва да са. Още по-важен е регистъра, ако пишете системен софтуер. За щастие, Borland да се постарали да улеснят максимално работата с регистъра, като са предоставили класа TRegistry. В тази статия ще разгледаме свойствата и методите на този клас.

Преди да започнем обаче, искам да отбележа факата, че TRegistry не е единствения клас, предоставящ достъп до регистъра. В Delphi съществува и класа TRegistryIniFile, който скрива работата с регистъра и ви позволява да записвате настройките на програмата си по същия начин, по който и ако го правите в INI файл. Освен това този клас ви позволява преминаването от използването на INI файлове към използването на регистъра на Windows с минимална промяна на кода – достатъчно е само да смените името на класа TIniFile с TRegistryIniFile. Няма да разглеждам подробно този клас – целта тук е пълноценната работа с регистъра, а не симулацията на работа с INI файлове, която е предназначена просто за улеснение на разработчиците.

Нека се запознаем с регистъра – вероятно всеки от вас го е виждал и знае какво представлява, но все пак ще кажа няколко думи за него. Информацията е подредена в йерархична структура, като има няколко начални ключа – HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG. Ако сте пускали RegEdit знаете, че в ляво имате списък на „директориите“, а в дясно – списък на всички стойности в текущата „директория“. Всъщност тези „директории“ се наричат ключове (keys). Всеки ключ може да има неограничено количество подключове (subkeys), които от своя страна също могат да имат подключове и т.н. Всеки ключ може да съдържа и неограничено количество променливи. Съществъват няколко типа данни. Това за вас не е съществено, тъй като Delphi (и по-точно класа TRegistry) предоставя методи за прочитане и записване на данни в познатите ви типове – Integer, String и т.н.

За да използате класа TRegistry, вие трябва да добавите Registry в клаузата uses на приложението.

Когато създавате обект TRegistry, вие му определяте начален ключ, който е един от началните ключове, които изброихме по-рано – по подразбиране това е HKEY_CURRENT_USER. По-късно вие можете да смените началния ключ. От там нататък вие работите с подключовете на този начален ключ и със записаните в тях променливи. Разбира се, първото нещо, което трябва да направите, е да създадете обект TRegistry. В зависимост от нуждите на вашата програма, този обект може да се създава при създаването на формата или при някакво определено събитие. Ние ще използваме създаването на формата. TRegistry има два предефинирани конструктора – можете да извикате конструктор без параметри или с един единствен параметър, инициализиращ свойството Access с подадената стойност. Access определя правата на програмата, когато отваря ключове – дали може да създава подлючове, да променя стойностите на променливите и т.н. По подразбиране (ако извикате конструктора без параметър) програмата има пълен достъп до регистъра. Можете по-късно да промените това, като използвате свойството Access. Ето как ще изглежда кода на нашето приложение:

Код:


unit Unit1; 

interface 

uses 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Registry; 

type 
TForm1 = class(TForm) 
procedure FormCreate(Sender: TObject); 
private 
{ Private declarations } 
public 
{ Public declarations } 
end; 

var 
Form1: TForm1; 
RegEdit: TRegistry; 
implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
RegEdit:=TRegistry.Create; 
end; 

end. 

Свойства:

Класа TRegistry има едва 5 свойства. Първото от тях вече го споменахме – Access. То може да има следните стойности:
KEY_ALL_ACCESS е комбинация от KEY_READ, KEY_WRITE и KEY_CREATE_LINK.
KEY_READ е комбинация от KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, и KEY_NOTIFY.
KEY_WRITE е комбинация от KEY_SET_VALUE и KEY_CREATE_SUB_KEY.
KEY_QUERY_VALUE разрешава на приложението да прочете стойностите на променливите на даден ключ.
KEY_ENUMERATE_SUB_KEYS дава право на приложението да прочете имената на подключовете.
KEY_NOTIFY позволява на приложението да бъде уведомявано при промяна в регистъра..
KEY_SET_VALUE разрешава на приложението да променя променливите в даден ключ.
KEY_CREATE_SUB_KEY дава право на приложението да създава подключове.
KEY_CREATE_LINK дава право на приложението да създава връзки.
KEY_EXECUTE ограничава достъпа единствено до четене на стойностите.

Стойността на свойството Access се използва при отваряне на ключове, но не и при създаването им. Можете да комбинирате няколко стойности с оператора OR. Имайте предвид, че това са правата, които приложението ще иска от Windows, а не тези които реално ще има. Затова ако приложението ви изисква повече права върху регистъра, от колкото Windows му дава, то може да не работи коректно (или изобщо да не работи). Така че никога не изисквайте повече права от необходимите ви.

Друго свойство на TRegistry е CurrentKey. То съдържа ключа, който приложението е отворило в момента. Всички операции, които извършвате, се изпълняват в текущия ключ. Можете да отворите друг ключ с някой от методите на TRegistry, които ще разгледаме по-нататък.
CurrentPath е низ, който съдържа пълния път от началния до текущия ключ включително.
LazyWrite е булево свойсвто, отнасящо се до начина, по който се записват промените в регистъра. При създаването на обекта TRegistry, това свойство се инициализира на true. Ако стойността му е true, промените се записват при затваряне на ключа, но метода CloseKey може да върне управлението на приложението преди те да са записани. Ако е false то CloseKey връща контрола на приложението едва след записване на промените, така че промените трябва да бъдат записани преди приложението да е способно да извърши каквато и да е друга операция. Този метод гарантира записване на промените но е значително по-бавен, отколкото ако се използва стойност true за свойството LazyWrite.
RootKey съдържа началния ключ. По подразбиране той е HKEY_CURRENT_USER, но вие можете да го промените, като промените стойността на свойството RootKey.

За сметка на малкото свойства, TRegistry предоставя голямо количество методи. Голямо количество от тях се отнасят до прочитането и записването на стойности, тъй като класът предоставя отделни методи за прочитане и записване на различни типове данни.
OpenKey отваря избран ключ. Приема два аргумента – първия низ, съдържащ искания ключ, а втория, който може да е true или false, определя дали да бъде създаден ключ ако избрания не съществува. При извикване на метода свойството CurrentKey получава за стойност отворения или създаден ключ. Ако за ключ бъде определено nil то текущ става началния ключ, определен от свойството RootKey. Имайте предвид, че за стойност трябва да дадете пълния път на ключа (изключвайки началния ключ), така че низа трябва да започва със символа “.
OpenKeyReadOnly също отваря ключа, само че заедно с това определя стойност KEY_READ на свойството Access. Друга съществена разлика с предишния метод е, че OpenKeyReadOnly не приема втори аргумент – той никога не създава ключ, ако определения в първия (и единствен) аргумент на метода не съществува
CloseKey затваря текущия ключ. Промените, направени в регистъра се записват при затваряне на ключа, затова не бива да държите ключовете отворени по-дълго от необходиморо. Този метод не приема аргументи.
CreateKey създава ключа. Приема един аргумент – низ, който указва името на ключа, който да бъде създаден. CreateKey винаги използва стойност KEY_ALL_ACCESS на свойството Access.
DeleteKey изтрива ключа, определен от подадения му аргумент.
KeyExist е булева функция, която приема аргумент низ и връща дали има ключ с това име.
HasSubKeys връща true ако текущия ключ съдържа подключове.
GetKeyNames приема като единствен аргумент променлива от типа TStrings и връща в нея имената на всички подключове на текущия ключ,
GetValueNames също приема като аргумент променлива от типа TStrings, но връща в нея иманата на всички променливи в трекущия ключ.

Следващите методи, които ще разгледаме, вече се отнасят до работата със самата информация в регистъра. Те работят с информацията в текущо отворения ключ. Ключа съдържа определени стойности, като за всяке една от тях има асоциирано име. Поради това ние ще наричаме тези имена променливи.

Съществуват три метода които дават информация за типа данни, съдържащ се в дадена променлива. И трите приемат за първи аргумент името на променливата, но връщат различна информация за нея:
GetDataSize връща размера на информацията (в байтове), съдържащ се в променливата.
GetDataType връща типа на данните в променливата. Върната стойност може да бъде:
rdUnknown Стойността е от недефиниран тип.
rdString Стойността е символен низ
rdExpandString Стойността е символен низ, който съдържа връзки към т.нар. environment променливи (environment в превод от английски означава „околна среда“. environment променливите са системни променливи. Например променливата %WINDIR% съдържа директорията, в която е инсталиран Windows).
rdInteger Стойността е число
rdBinary Бинарна стойност
GetDataInfo приема и втори аргумент – променлива от типа TRegDataInfo, в която връща и информацията за исканата променлива. TRegDataInfo е запис с две полета. Първото от тях, RegData, съдържа типа на данните – същия, като при GetDataType. Второто – DataSize, съдържа размера в байтове на информацията. На практира този метод комбинира предишните два.

Следват няколко Read* и съответстващитя им Write* методи, които четат и записват стойностите в регистъра, като единствената разлика между тях е типа данни, които използват.

ReadBool, ReadCurrency, ReadDate, ReadDateTime, ReadFloat, ReadInteger, ReadString и ReadTime приемат като аргумент име на променлива и връщат стойността й като съответния тип данни. Съответните Write* методи (WriteBool, WriteCurrency, WriteDate, WriteDateTime, WriteFloat, WriteInteger, WriteString и WriteTime) приемат като първи аргумент име на променлива и като втори – нейната стойност като съответния тип данни и ги записва в регистъра.

Това е всичко, което ви трябва, за да работите с регистъра. Разбира се, информацията тук е само за достъпа до регистъра. Можете да го използвате, за да записвате настройките на приложенията си и да ги възстановявате при следващо стартиране. Е, бихте могли и във файл, но така е малко по-скрито от обикновения потребител…

По-важното е, че Windows, Internet Explorer и много други приложения могат да бъдат контролирани от регистъра. Ако познавате структурата му, ако знаете къде какво е записано и къде какво трябва да промените, можете да добавяте и махате елементи от контекстното меню, да променяте настройки на Windows – включително такива, които не са достъпни извън самия регистър, да добавяте бутони в Internet Explorer, да модифицирате MS Office… Изобщо, да интегрирате своите приложения с продуктите на Microsoft

Автор: Максим Крижановски

0 0 глас
Оценете статията
Абонирай се
Извести ме за
guest
0 Коментара
Отзиви
Всички коментари