особенности метода AddComponent
У меня MDI приложение с одинаковыми классами форм TMyMDIForm. Каждая форма приложения содержит экземпляр TfsScript (TMyMDIForm.Sctipt). На каждой форме так же есть Панель TPanel на которой лежит кнопка TButton (TMyMDIForm.Panel.Button) причем Button.Owner = Panel. При нажатии на кнопку запускается процедура скрипта BtClick Script.CallFunction...
Чтобы каждый раз не регистрировать в каждом из этих экземпляров TfsScript необходимые для выполнения классы предусмотрет модуль данных TdmMyLibScript который содержит экземпляр класса TfsScript (TdmMyLibScript .LibScript) с уже зарегистрированными классами, доступными в каждой форме.
procedure TdmMyLibScript.Init;
begin
Script.AddClass(TPanel,'TComponent');
Script.AddClass(TButton,'TComponent');
end;
У каждой формы есть процедура инициализации TMyMDIForm.Init:
procedure TMyMDIForm.Init;
begin
Script.Parent := dmMyLibScript.LibScript;
Script.AddComponent(MyMDIForm.Panel);
Script.Lines.Add('procedure BtClick;');
Script.Lines.Add('begin');
Script.Lines.Add(' ShowMessage(Panel.Button.Caption);');
Script.Lines.Add('end;');
Script.Lines.Add(' ');
Script.Lines.Add('begin');
Script.Lines.Add('end.');
Script.Execute;
end;
В итоге если выполнить следующий код:
MyMDIForm := TMyMDIForm.Create(Application);
MyMDIForm.Name := 'Form1';
MyMDIForm.Button.Caption := 'Привет!';
MyMDIForm.Init;
MyMDIForm := TMyMDIForm.Create(Application);
MyMDIForm.Name := 'Form2';
MyMDIForm.Button.Caption := 'Пока!';
MyMDIForm.Init;
То при нажатии на кнопку Button на любой из форм выдастся сообщение 'Привет!'. Причем после уничтожения первой формы (Form1) попытки нажатия на кнопку на второй форме приведут к Access vialation
Проблема кроется в методе AddComponent. Просто субкомпоненты добавляются методом AddObject не к самому компоненту, а к его классу.
procedure TfsScript.AddComponent(Form: TComponent);
var
i: Integer;
v: TfsClassVariable;
begin
{$IFNDEF NOFORMS}
v := FindClass(Form.ClassName);
if v = nil then
begin
if Form.InheritsFrom(TForm) then
AddClass(Form.ClassType, 'TForm')
else if Form.InheritsFrom(TDataModule) then
AddClass(Form.ClassType, 'TDataModule')
else
Exit;
v := FindClass(Form.ClassName);
end;
for i := 0 to Form.ComponentCount - 1 do
v.AddComponent(Form.Components); {Комонент добавлен к классу (в нашем случае класс зарегистрирован в dmMyLibScript и как следствие он общий у скриптов всех форм}
AddObject(Form.Name, Form);
{$ENDIF}
end;
Это затрудняет широкое использование TfsScript.Parent. Как я могу сделать свое приложение (см. выше) функционирующим корректно?
Чтобы каждый раз не регистрировать в каждом из этих экземпляров TfsScript необходимые для выполнения классы предусмотрет модуль данных TdmMyLibScript который содержит экземпляр класса TfsScript (TdmMyLibScript .LibScript) с уже зарегистрированными классами, доступными в каждой форме.
procedure TdmMyLibScript.Init;
begin
Script.AddClass(TPanel,'TComponent');
Script.AddClass(TButton,'TComponent');
end;
У каждой формы есть процедура инициализации TMyMDIForm.Init:
procedure TMyMDIForm.Init;
begin
Script.Parent := dmMyLibScript.LibScript;
Script.AddComponent(MyMDIForm.Panel);
Script.Lines.Add('procedure BtClick;');
Script.Lines.Add('begin');
Script.Lines.Add(' ShowMessage(Panel.Button.Caption);');
Script.Lines.Add('end;');
Script.Lines.Add(' ');
Script.Lines.Add('begin');
Script.Lines.Add('end.');
Script.Execute;
end;
В итоге если выполнить следующий код:
MyMDIForm := TMyMDIForm.Create(Application);
MyMDIForm.Name := 'Form1';
MyMDIForm.Button.Caption := 'Привет!';
MyMDIForm.Init;
MyMDIForm := TMyMDIForm.Create(Application);
MyMDIForm.Name := 'Form2';
MyMDIForm.Button.Caption := 'Пока!';
MyMDIForm.Init;
То при нажатии на кнопку Button на любой из форм выдастся сообщение 'Привет!'. Причем после уничтожения первой формы (Form1) попытки нажатия на кнопку на второй форме приведут к Access vialation
Проблема кроется в методе AddComponent. Просто субкомпоненты добавляются методом AddObject не к самому компоненту, а к его классу.
procedure TfsScript.AddComponent(Form: TComponent);
var
i: Integer;
v: TfsClassVariable;
begin
{$IFNDEF NOFORMS}
v := FindClass(Form.ClassName);
if v = nil then
begin
if Form.InheritsFrom(TForm) then
AddClass(Form.ClassType, 'TForm')
else if Form.InheritsFrom(TDataModule) then
AddClass(Form.ClassType, 'TDataModule')
else
Exit;
v := FindClass(Form.ClassName);
end;
for i := 0 to Form.ComponentCount - 1 do
v.AddComponent(Form.Components); {Комонент добавлен к классу (в нашем случае класс зарегистрирован в dmMyLibScript и как следствие он общий у скриптов всех форм}
AddObject(Form.Name, Form);
{$ENDIF}
end;
Это затрудняет широкое использование TfsScript.Parent. Как я могу сделать свое приложение (см. выше) функционирующим корректно?
Комментарии
Script.AddComponent(MyMDIForm.Panel);
напиши хотя бы та
Script.AddComponent(self.Panel);