unit exmpl_04;
{ ИСПОЛЬЗОВАНИЕ МОДУЛЬНЫХ НОТИФИКАТОРОВ }
interface
uses
Dialogs, Toollntf, Exptlntf, Editlntf, Menus;
type
{ класс модульного нотификатора порождаем от TIModuleNotifier }
TModuleNotifier = class(TIModuleNotifier)
private
FileName: string;
public
constructor Create(const aFileName: string);
procedure Notify(NotifyCode: TNotifyCode); override;
procedure ComponentRenamed(ComponentHandle: Pointer;
const OldName, NewName: string); override;
end;
TEMyExpert = class;
{ класс add - in нотификатора порождаем от TIAddlnNotifier }
TAddlnNotifier = class(TIAddlnNotifier)
private
Expert: TEMyExpert;
public
constructor Create(anExpert: TEMyExpert);
procedure FileNotification(NotifyCode: TFileNotification;
const FileName: string; var Cancel: Boolean); override;
end;
{ класс эксперта является потомком базового класса TlExpert }
TEMyExpert = class (TIExpert)
private
AddlnNotifier: TAddlnNotifier;
Modulelnterface: TIModulelnterface;
ModuleNotifier: TModuleNotifier;
public
constructor Create;
destructor Destroy; override;
function GetName: string; override;
function GetStyle: TExpertStyle; override;
function GetlDString: string; override;
procedure AddModuleNotifier(const FileName: string);
procedure RemoveModuleNotifier;
end;
procedure Register;
implementation
constructor TModuleNotifier.Create;
begin
inherited Create;
FileName := aFileName;
end;
procedure TModuleNotifier.Notify;
begin
{ если произошло сохранение соответствующего нотификатору файла, то
выдаем сообщение об этом }
if NotifyCode = ncAfterSave then
MessageDlg( FileName + ' saved' , mtlnformation, [mb0k], 0);
end;
procedure ТModule Notifier.СomponentRenamed;
begin
{ ничего здесь не делаем, но метод необходимо перекрыть }
end;
procedure TAddlnNotifier.FileNotification
(NotifyCode: TFileNotification; const FileName: string;
var Cancel: Boolean);
begin
with Expert do
case NotifyCode of
fnProjectOpened: { открытие проекта }
{ добавляем модульный нотификатор }
AddModuleNotifier(FileName);
fnProjectClosing: { закрытие проекта }
{ освобождаем модульный нотификатор }
RemoveModuleNotifier;
end;
end;
constructor TEMyExpert.Create;
begin
inherited Create;
try
{ создаем add-in нотификатор }
AddlnNotifier := TAddlnNotifier.Create(Self);
{ регистрируем add-in нотификатор }
ToolServices.AddNotifier(AddlnNotifier);
except
AddlnNotifier := nil;
end;
{ добавляем модульный нотификатор }
AddModuleNotifier (ToolServices . GetProjectName ) ;
end;
destructor TEMyExpert.Destroy;
begin
if As signed(AddlnNotifier) then
begin
{ снимаем регистрацию add-in нотификатора }
ToolServices.RemoveNotifier(AddlnNotifier);
{ уничтожаем add-in нотификатор }
AddlnNotifier.Free;
end;
{ освобождаем модульный нотификатор }
RemoveModuleNotifier;
inherited Destroy;
end;
procedure ТЕMyExpert.AddModuleNotifier;
begin
{ если модульный нотификатор для проектного файла уже зарегистрирован
то никаких действий не выполняем во избежание появления дубликатов
нотификаторов ; в противном случае дубликаты могли бы появиться,
например, при открытии Delphi: один нотификатор добавился бы при
создании эксперта (в конструкторе класса эксперта), а второй -
при открытии проекта (в TAddNotifier.FileNotification) }
if Assigned(Modulelnterface) and Assigned(ModuleNotifier) then
Exit;
try
{ получаем интерфейс модуля }
Modulelnterface := ToolServices.GetModulelnterface(FileName);
try
{ создаем модульный нотификатор }
ModuleNotifier := TModuleNotifier.Create(FileName);
{ регистрируем модульный нотификатор }
Modulelnterface.AddNotifier(ModuleNotifier)
except
ModuleNotifier := nil;
end;
except
Modulelnterface := nil;
end;
end;
procedure TEMyExpert.RemoveModuleNotifier;
begin
if Assigned(ModuleNotifier) then
begin
if Assigned(Modulelnterface) then
{ снимаем регистрацию модульного нотификатора }
Modulelnterface.RemoveNotifier(ModuleNotifier);
{ уничтожаем модульный нотификатор }
ModuleNotifier.Free;
ModuleNotifier := nil;
end;
if Assigned(Modulelnterface) then
begin
{ освобождаем модульный интерфейс }
Modulelnterface.Free;
Modulelnterface := nil;
end;
end;
end.