![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Мне необходимо отследить переименование проекта, для чего... [D6, Win2k]
Другой Дмитрий © (2005-06-23 10:59:00)Мне необходимо отследить переименование проекта, для чего пишу эксперт. Воспользовался примером ModuleNotifiers ( http://www.devrace.com/files/tools_api_examples.zip) из статьи Андрея Семака ( http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=899).
После установки примера, открываю проект через "File->Open". Не закрывая этот, открываю другой (проекты демонстрационные состоят из одной формы).
Повторяю несколько раз и жму "File->Close All" и получаю "AV in module coreide60.bpl", иногда в rtl60.bpl и периодически появляется сообщение "Invalid Index".
После этого при попытке доступа к любому пункту меню Delphi появляется "AV in module coreide60.bpl".
Может кто нибудь подскажет, что там не доделано или это только у меня такой глюк?
Другой Дмитрий (2005-06-27 08:59:00) [1]После переустановки Delphi6 Update Pack 2, проблема разрешилась.
Другой Дмитрий (2005-06-23 14:35:00) [2]Привожу код:
unit FirstExpClass;
interface
uses
ToolsApi, Dialogs, SysUtils;
type
TFirstModuleExpert = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
private
FNotifierIndex: integer;
public
constructor Create;
destructor Destroy; override;
function GetIDString: string;
function GetName: string;
function GetState: TWizardState;
procedure Execute;
function GetMenuText: string;
end;
TIDENotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier)
{From IOTANotifier}
procedure AfterSave;
procedure BeforeSave;
procedure Destroyed;
procedure Modified;
{From IOTAIDENotifier}
procedure FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: Boolean);
procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
overload;
procedure AfterCompile(Succeeded: Boolean); overload;
end;
TModuleNotifier = class(TNotifierObject, IOTANotifier, IOTAModuleNotifier)
private
FFileName: string;
protected
{From IOTANotifier}
procedure AfterSave;
procedure BeforeSave;
procedure Destroyed;
procedure Modified;
{From IOTAModuleNotifier}
function CheckOverwrite: Boolean;
procedure ModuleRenamed(const NewName: string);
public
constructor Create(FileName: string);
destructor Destroy; override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterPackageWizard(TFirstModuleExpert.Create);
end;
function OTAServices: IOTAServices;
begin
Result := (BorlandIDEServices as IOTAServices);
end;
function OTAMessageServices: IOTAMessageServices;
begin
Result := (BorlandIDEServices as IOTAMessageServices);
end;
function OTAModuleServices: IOTAModuleServices;
begin
Result := (BorlandIDEServices as IOTAModuleServices);
end;
{ TFirstExpert }
constructor TFirstModuleExpert.Create;
begin
FNotifierIndex := OTAServices.AddNotifier(TIDENotifier.Create);
end;
destructor TFirstModuleExpert.Destroy;
begin
if FNotifierIndex <> -1 then
OTAServices.RemoveNotifier(FNotifierIndex);
inherited;
end;
procedure TFirstModuleExpert.Execute;
begin
OTAMessageServices.AddTitleMessage(Format('%s запущен', [GetName]));
end;
function TFirstModuleExpert.GetIDString: string;
begin
Result := 'MY.FIRST.MODULE.EXPERT';
end;
function TFirstModuleExpert.GetMenuText: string;
begin
Result := 'Execute MyFirstModuleExpert';
end;
function TFirstModuleExpert.GetName: string;
begin
Result := 'MyFirstModuleExpert';
end;
function TFirstModuleExpert.GetState: TWizardState;
begin
Result := [wsEnabled];
end;
{ TIDENotifier }
procedure TIDENotifier.AfterCompile(Succeeded: Boolean);
begin
end;
procedure TIDENotifier.AfterSave;
begin
end;
procedure TIDENotifier.BeforeCompile(const Project: IOTAProject;
var Cancel: Boolean);
begin
end;
procedure TIDENotifier.BeforeSave;
begin
end;
procedure TIDENotifier.Destroyed;
begin
end;
procedure TIDENotifier.FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: Boolean);
var
Module: IOTAModule;
begin
{файл открыт в редакторе IDE?}
if NotifyCode = ofnFileOpened then
begin
{ищем модуль по имени}
Module := OTAModuleServices.FindModule(FileName);
{если модуль найден - присоединить нотификатор}
if assigned(Module) then
Module.AddNotifier(TModuleNotifier.Create(Filename));
end;
end;
procedure TIDENotifier.Modified;
begin
end;
{ TModuleNotifier }
procedure TModuleNotifier.AfterSave;
begin
OTAMessageServices.AddTitleMessage('AfterSave ' + FFileName);
end;
procedure TModuleNotifier.BeforeSave;
begin
OTAMessageServices.AddTitleMessage('BeforeSave ' + FFileName);
end;
function TModuleNotifier.CheckOverwrite: Boolean;
begin
Result := True;
end;
constructor TModuleNotifier.Create(FileName: string);
begin
inherited Create;
FFileName := Filename;
end;
destructor TModuleNotifier.Destroy;
begin
OTAMessageServices.AddTitleMessage('Closed ' + FFileName);
inherited;
end;
procedure TModuleNotifier.Destroyed;
begin
end;
procedure TModuleNotifier.Modified;
begin
OTAMessageServices.AddTitleMessage('Modified ' + FFileName);
end;
procedure TModuleNotifier.ModuleRenamed(const NewName: string);
begin
OTAMessageServices.AddTitleMessage('File ' + FFileName + ' renamed to ' +
NewName);
FFileName := NewName;
end;
end.
Юрий Зотов (2005-06-23 12:41:00) [3]> Другой Дмитрий (23.06.05 10:59)
Предположение такое - где-то перечисляются проекты группы (или модули проекта, или еще что-то в этом духе) - причем перечисление идет в цикле for и в возрастающем порядке (от 0 до Count-1). В цикле for верхний предел вычисляется один раз, при его инициализации - поэтому, если во время выполнения цикла количество элементов по каким-то причинам уменьшилось, то произойдет обращение к несуществующему элементу и получим сообщение об ошибке индексации. И, поскольку исключение происходит фактически в самой IDE (это же эксперт, как-никак), то далее возможны нарушения ее работы.
Если приведете код, можно будет попытаться сказать точнее. Либо походите отладчиком. Для этого деинсталлируете пакет эксперта, назначаете ему host application в виде Delphi32.exe и "запускаете" из IDE - получаем 2 экземпляра IDE, причем первый будет отлаживать второй. В этом втором экземпляре инсталлируете пакет и производите все манипуляции - а в первом ведете обычную отладку, с брейкпойнтами и пр.