Главная » Delphi » Мастер Wizard

0

Рис. 17.3. Записи о мастерах Delphi в системном  реестре

Интерфейс мастера

Мастер  Wizard  позволяет без  использования редактора реестра добавлять, моди фицировать и удалять из системного реестра записи о мастерах, размещенных в биб лиотеках DLL. Сначала  рассмотрим модуль InitWiz.pas, содержащий класс мастера (листинг 17.2).Листинг 17.2. Модуль InitWiz.pas, содержащий класс мастера DLL

unit InitWiz;

interface

uses Windows, ToolsAPI;

type

TWizardWizard = class(TNotifierObject, IOTAWizard,

IOTAMenuWizard)

// Методы класса IOTAWizard

function GetIDString: string;

function GetName: string;

function GetState: TWizardState;

procedure Execute;

// Методы класса IOTAMenuWizard

function GetMenuText: string;

end;

function InitWizard(const BorlandIDEServices: IBorlandIDEServices; RegisterProc: TWizardRegisterProc;

var Terminate: TWizardTerminateProc): Boolean stdcall;

implementation

uses SysUtils, Forms, Controls, Main;

function TWizardWizard.GetName: string;

{ Возвращает имя мастера }

begin

Result := ‘WizardWizard';

end;

function TWizardWizard.GetState: TWizardState;

{ Этот мастер всегда доступен }

begin

Result := [wsEnabled];

end;

function TWizardWizard.GetIDString: String;

{ "Vendor.AppName" строка идентификатора мастера }

begin

Result := ‘DDG.WizardWizard';

end;

function TWizardWizard.GetMenuText: string;

{ Строка меню мастера }

begin

Result := ‘Wizard Wizard';

end;procedure TWizardWizard.Execute;

{ Вызывается при выборе мастера в главном меню. Эта процедура

создает, отображает и освобождает главную форму мастера. }

begin

MainForm := TMainForm.Create(Application);

try

MainForm.ShowModal;

finally

MainForm.Free;

end;

end;

function InitWizard(const BorlandIDEServices: IBorlandIDEServices; RegisterProc: TWizardRegisterProc;

var Terminate: TWizardTerminateProc): Boolean stdcall;

var

Svcs: IOTAServices;

begin

Result := BorlandIDEServices <> nil;

if Result then begin

Svcs := BorlandIDEServices as IOTAServices;

ToolsAPI.BorlandIDEServices := BorlandIDEServices;

Application.Handle := Svcs.GetParentHandle;

SDelphiKey := Svcs.GetBaseRegistryKey + ‘\Experts';

RegisterProc(TWizardWizard.Create);

end;

end;

end.Между этим  модулем  и  модулем  мастера Dumb  существует  несколько различий. Самым важным  из них является то, что функция инициализации типа TWizardInit- Proc должна  быть  точкой входа подпрограмм интегрированной среды  разработки в библиотеке DLL. В данном  случае такая  функция называется InitWizard(). Она вы полняет следующие задачи инициализации мастера.

•   Получает через параметр BorlandIDEServices указатель на интерфейс IOTA- Services.

•   Сохраняет указатель BorlandIDEServices для дальнейшего использования.

•   Присваивает переменной Application библиотеки DLL дескриптор, возвра щаемый  методом IOTAServices.GetParentHandle(). Этот  метод  возвраща ет дескриптор окна, которое должно  быть родительским по отношению ко всем остальным окнам верхнего уровня,  создаваемым мастером.

•   Передает созданный экземпляр мастера процедуре RegisterProc() для  его регистрации в интегрированной среде  разработки. Процедура Register- Proc() вызывается один  раз  для каждого  экземпляра мастера DLL, регистри руемого в интегрированной среде разработки.

•  Кроме  того,  функция InitWizard() может  назначать параметру Terminate

процедуру  типа  TWizardTerminateProc, используемую  в качестве процедурывыхода.  Эта процедура будет вызвана перед  выгрузкой мастера из среды  разра ботки.  В ней  можно  выполнять освобождение необходимых ресурсов. Перво начально данный параметр равен  nil, и если при выходе  из мастера выполнять какие либо специфические действия не требуется, то такое  значение изменять не нужно.

CОВЕТ

В методе инициализации мастера необходимо использовать соглашение о вызовах

stdcall.CОВЕТ

В разделе uses любого размещаемого в DLL мастера, в котором вызываются функции интерфейса API Open Tools со строковыми параметрами, должен быть указан модуль ShareMem. В противном случае при освобождении экземпляра мастера произойдет ошибка, вызванная отказом в доступе (access violation).

Пользовательский интерфейс мастера

Метод  Execute() немного сложнее методов, рассматривавшихся ранее в настоя щей главе. В нем создается, а затем освобождается экземпляр мастера — форма Main- Form, отображаемая в модальном режиме (рис. 17.4). В листинге 17.3 приведен модуль Main.pas, содержащий исходный код формы MainForm.

Рис. 17.4. Главная форма мастера WizardЛистинг 17.3. Main.pas — главный  модуль  мастера Wizard

unit Main; interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls, Registry, AddModU, ComCtrls, Menus;type

TMainForm = class(TForm)

TopPanel: TPanel;

Label1: TLabel;

BottomPanel: TPanel;

WizList: TListView;

PopupMenu1: TPopupMenu;

Add1: TMenuItem;

Remove1: TMenuItem;

Modify1: TMenuItem;

AddBtn: TButton;

RemoveBtn: TButton;

ModifyBtn: TButton;

CloseBtn: TButton;

procedure RemoveBtnClick(Sender: TObject);

procedure CloseBtnClick(Sender: TObject);

procedure AddBtnClick(Sender: TObject);

procedure ModifyBtnClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

private

procedure DoAddMod(Action: TAddModAction);

procedure RefreshReg;

end;

var

MainForm: TMainForm;

{ Ключ системного реестра, в котором Delphi 6 регистрирует

мастера. Версия EXE использует значение по умолчанию, а

версия DLL получает ключ с помощью

метода ToolServices.GetBaseRegistryKey. }

SDelphiKey: string = ‘\Software\Borland\Delphi\6.0\Experts';

implementation

{$ifndef BUILD_EXE}

uses InitWiz;

{$endif}

{$R *.DFM}

var

DelReg: TRegistry;

procedure TMainForm.RemoveBtnClick(Sender: TObject);

{ Обработчик щелчка на кнопке Remove. Выделенный элемент удаляется

из системного реестра. }

var

Item: TListItem;

begin

Item := WizList.Selected;

if Item <> nil then begin

if MessageDlg(Format(‘Remove item "%s"’, [Item.Caption]),

mtConfirmation, [mbYes, mbNo], 0) = mrYes thenDelReg.DeleteValue(Item.Caption); RefreshReg;

end;

end;

procedure TMainForm.CloseBtnClick(Sender: TObject);

{ Обработчик щелчка на кнопке Close. Завершение приложения. }

begin

Close;

end;

procedure TMainForm.DoAddMod(Action: TAddModAction);

{ Добавление в реестр записи для нового мастера или модификация уже

существующей записи. }

var

OrigName, ExpName, ExpPath: String;

Item: TListItem;

begin

if Action = amaModify then begin // При модификации…

Item := WizList.Selected;

if Item = nil then Exit; // удостовериться, что элемент выбран

ExpName := Item.Caption; // инициализировать переменные

if Item.SubItems.Count > 0 then

ExpPath := Item.SubItems[0];

OrigName := ExpName;           // сохранить исходное имя.

end;

{ Вызов диалога, позволяющего добавить или отредактировать

запись }

if AddModWiz(Action, ExpName, ExpPath) then begin

{ Обработка ситуации, когда выбрано действие Modify и изменено

имя параметра. }

if (Action = amaModify) and (OrigName <> ExpName) then

DelReg.RenameValue(OrigName, ExpName);

DelReg.WriteString(ExpName, ExpPath); // Запись нов. значения

end;

RefreshReg;                                // Обновить список

end;

procedure TMainForm.AddBtnClick(Sender: TObject);

{ Обработчик щелчка на кнопке Add }

begin

DoAddMod(amaAdd);

end;

procedure TMainForm.ModifyBtnClick(Sender: TObject);

{ Обработчик щелчка на кнопке Modify }

begin

DoAddMod(amaModify);

end;

procedure TMainForm.RefreshReg;

{ Обновление списка содержимым системного реестра }

vari: integer;

TempList: TStringList;

Item: TListItem;

begin

WizList.Items.Clear;

TempList := TStringList.Create;

try

{ Получить имена мастеров из системного реестра }

DelReg.GetValueNames(TempList);

{ Получить путь для каждого имени мастера }

for i := 0 to TempList.Count – 1 do begin

Item := WizList.Items.Add;

Item.Caption := TempList[i];

Item.SubItems.Add(DelReg.ReadString(TempList[i]));

end;

finally

TempList.Free;

end;

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

RefreshReg;

end;

initialization

DelReg := TRegistry.Create;              // Создать объект реестра

DelReg.RootKey := HKEY_CURRENT_USER; // Установить корневой ключ

// Открыть/создать ключ мастера Delphi

DelReg.OpenKey(SDelphiKey, True);

finalization

Delreg.Free;                  // Удалить объект системного реестра

end.Этот модуль обеспечивает пользовательский интерфейс мастера, помещенного в библиотеку DLL. Он предназначен для добавления, удаления  и модификации записей в системном реестре. В разделе initialization данного модуля создается объект Del- Reg, имеющий тип TRegistry. Свойству  RootKey объекта DelReg присваивается зна чение ключа  HKEY_CURRENT_USER. Затем   с помощью метода  OpenKey() этот  ключ верхнего уровня  разворачивается в ключ \Software\Borland\Delphi\6.0\Experts, который содержит записи о мастерах Delphi, сохраняемых в библиотеках DLL.

При  первом запуске мастера компонент TListView по имени ExptList заполняет ся параметрами и значениями из рассмотренного выше ключа системного реестра. Сначала  вызов  метода  DelReg.GetValueNames() возвращает имена  параметров и по мещает  их в объект TStringList. Затем  для каждого  элемента списка  TStringList к компоненту ExptList добавляется компонент TListItem. Для  получения значения каждого  параметра объекта TListItem, помещаемого в список  SubItems, использует ся метод DelReg.ReadString().

Работа с реестром осуществляется в методах RemoveBtnClick() и DoAddMod(). Ме

тод RemoveBtnClick() отвечает за удаление из системного реестра записи, соответст вующей текущему выделенному мастеру.  Прежде всего в методе  проверяется наличие не которого выделенного элемента, а затем  отображается диалоговое окно  для подтвержде ния  выполнения операции удаления.  Затем  вызывается метод  DelReg.DeleteValue(), которому в качестве параметра передается значение CurrentItem.

Методу DoAddMod() может передаваться параметр типа TAddModAction. Этот тип

определен следующим образом:

type

TAddModAction = (amaAdd, amaModify);

Как следует из приведенных значений, параметр указывает, будет ли в реестр добав лен новый элемент или модифицирован уже существующий. Сначала  функция проверя ет наличие выделенного в данный момент  элемента. Если его нет, то функция дополни тельно проверяет, имеет  ли переданный ей параметр Action значение amaAdd. Если в параметре Action имеется значение amaModify, то параметр и значение, которые со ответствуют существующему мастеру,  присваиваются локальным переменным ExpName и ExpPath. Затем  эти значения передаются функции AddModExpert(), определенной в модуле AddModU (листинг 17.4). В этой функции создается диалоговое окно,  в котором можно  ввести  новое  либо  изменить существующее  имя  или  путь к мастеру  (рис. 17.5). Функция  AddModExpert() возвращает значение True, если ее диалоговое окно закры то с помощью щелчка на кнопке OK. В таком случае существующий параметр системного реестра модифицируется с помощью метода  DelReg.RenameValue(), а новое  или мо дифицируемое значение записывается функцией DelReg.WriteString().

Рис. 17.5. Форма  AddModForm мастера

Wizard

Листинг 17.4. AddModU.pas — модуль, добавляющий и модифицирующий записи о мастере в системном реестре

unit AddModU;

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls;

type

TAddModAction = (amaAdd, amaModify);

TAddModForm = class(TForm) OkBtn: TButton; CancelBtn: TButton; OpenDialog: TOpenDialog; Panel1: TPanel;Label1: TLabel; Label2: TLabel; PathEd: TEdit; NameEd: TEdit; BrowseBtn: TButton;

procedure BrowseBtnClick(Sender: TObject);

private

{ Закрытые объявления }

public

{ Открытые объявления }

end;

function AddModWiz(AAction: TAddModAction; var WizName, WizPath: String): Boolean;

implementation

{$R *.DFM}

function AddModWiz(AAction: TAddModAction; var WizName, WizPath: String): Boolean;

{ Применяется для вызова диалогового окна, добавления или модификации параметров системного реестра }

const

CaptionArray: array[TAddModAction] of string[31] =

(‘Add newexpert’, ‘Modify expert’);

begin

with TAddModForm.Create(Application) do begin     // Создать диалог

Caption := CaptionArray[AAction];           // Установить заголовок

if AAction = amaModify then begin           // При модификации…

NameEd.Text := WizName;                     // инициализировать имя

PathEd.Text := WizPath;                     // и путь.

end;

Result := ShowModal = mrOk;                 // Показать диалог

if Result then begin                        // Если Ok…

WizName := NameEd.Text;                     // установить имя

WizPath := PathEd.Text;                     // и путь.

end;

Free;

end;

end;

procedure TAddModForm.BrowseBtnClick(Sender: TObject);

begin

if OpenDialog.Execute then

PathEd.Text := OpenDialog.FileName;

end;

end.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии