![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вызов метода, чтоб его...
Dima © (2007-12-15 22:08:00)Привет всем. Хотел написать небольшой компонент, основанный на объектах (надо для практики), но есть трабла. Помогите пожалуйста. Если я чего не понял, прошу не ругать :) Я начинающий. В целом компонент такого вида:
PMyObj = ^TPMyObj;
TOnMyObjEvent = procedure(Sender: PMyObj) of object;
TMyObj = object( TObj )
... (тут всякие свойства...)
destructor Destroy; virtual;
end;
PMainComp = ^TMainComp;
TMainComp = object(TObj)
private
FOnUpdate: TOnMyObjEvent;
...
public
property OnUpdate: TOnMyObjEvent read FOnUpdate write FOnUpdate;
end;
Есть некоторая процедура внутри TMainComp, которая создаёт и формирует экземпляр TMyObj (при помощи New(MyObj, Create), MyObj - PMyObj), а затем вызывает метод OnUpdate(MyObj), внутри которого идёт обращение к свойствам объекта. Как вы уже, наверное, догадались, я успешно получаю обухом по голове :) а почему, понять не в состоянии. Может, от того, что целый день парюсь, но дела не меняются - внутри метода стоит только обратиться к любому свойству MyObj, как прога вылетает. Почему?
Dima (2007-12-16 09:17:00) [1]Спасибо всем, я понял в чём дело :)
Vladimir Kladov (2007-12-16 08:31:00) [2]Это именно то, что я и подозревал как №1.
procedure OnUpdate(Dummy, Sender: PMyObj);
Как я в описании Соль заметил, выросло поколение (хороших, но неграмотных) программеров, которых инфиксная запись и отсутствия явной передачи параметра-объекта сбивает с толку. Не пишут параметр, значит его как бы и нет.
Дмитрий К (2007-12-15 23:24:00) [3]У меня вот так заработало. А почему, сами разбирайтесь, либо пусть кто другой объяснит. Я в теории - не очень.
program project1;
uses KOL;
type
PMyObj = ^TMyObj;
TOnMyEvent = procedure(Sender: PMyObj) of object;
TMyObj = object( TObj )
Name: string;
private
FOnUpdate: TOnMyEvent;
procedure SetOnUpdate(const Value: TOnMyEvent);
public
// destructor Destroy; virtual;
property OnUpdate: TOnMyEvent read FOnUpdate write SetOnUpdate;
end;
PMyComp = ^TMyComp;
TMyComp = object(TObj)
protected
private
FOnUpdate: TOnMyEvent;
procedure SetOnUpdate(const Value: TOnMyEvent);
public
FMyObj: PMyObj;
// destructor Destroy; virtual;
property OnUpdate: TOnMyEvent read FOnUpdate write SetOnUpdate;
procedure Go;
end;
function NewMyComp: PMyComp;
begin
New(Result, Create);
New(Result.FMyObj, Create);
Result.Add2AutoFree(Result.FMyObj);
Result.FMyObj.Name := 'MyComp Name';
end;
procedure TMyObj.SetOnUpdate(const Value: TOnMyEvent);
begin
FOnUpdate := Value;
end;
procedure TMyComp.Go;
begin
Self.FMyObj.OnUpdate := Self.FOnUpdate;
if Assigned(Self.FMyObj.OnUpdate) then
Self.FMyObj.OnUpdate(Self.FMyObj);
end;
procedure TMyComp.SetOnUpdate(const Value: TOnMyEvent);
begin
FOnUpdate := Value;
end;
procedure OnUpdate(Dummy, Sender: PMyObj);
begin
ShowMessage(Sender.Name);
end;
procedure Button1Click(Dummy, Sender: PObj);
var
MyComp: PMyComp;
begin
MyComp := NewMyComp;
MyComp.OnUpdate := TOnMyEvent(MakeMethod(nil, @OnUpdate) );
MyComp.Go;
MyComp.Free;
end;
var form, btn: PControl;
begin
form := newform(nil, 'test');
btn := newbutton(form,'click').ResizeParent;
btn.OnClick := TOnEvent(MakeMethod(nil, @Button1Click));
run(Form);
end.
Dima (2007-12-15 22:54:00) [4]Это только пример, я специально наваял, но принцип того, что хочу сделать, видно.
Dima (2007-12-15 22:51:00) [5]Ну вот как-то так:
type
PMyObj = ^TMyObj;
TOnMyEvent = procedure(Sender: PMyObj) of object;
TMyObj = object( TObj )
Name: string;
private
FOnUpdate: TOnMyEvent;
procedure SetOnUpdate(const Value: TOnMyEvent);
public
destructor Destroy; virtual;
property OnUpdate: TOnMyEvent read FOnUpdate write SetOnUpdate;
end;
PMyComp = ^TMyComp;
TMyComp = object(TObj)
protected
private
FOnUpdate: TOnMyEvent;
procedure SetOnUpdate(const Value: TOnMyEvent);
public
FMyObj: PMyObj;
destructor Destroy; virtual;
property OnUpdate: TOnMyEvent read FOnUpdate write SetOnUpdate;
procedure Go;
end;
function NewMyComp: PMyComp;
implementation
function NewMyComp: PMyComp;
begin
New(Result, Create);
New(Result.FMyObj, Create);
Result.FMyObj.Name := 'MyComp Name';
end;
procedure TMyObj.SetOnUpdate(const Value: TOnMyEvent);
begin
FOnUpdate := Value;
end;
procedure TMyComp.Go;
begin
Self.FMyObj.OnUpdate := Self.FOnUpdate;
if Assigned(Self.FMyObj.OnUpdate) then
Self.FMyObj.OnUpdate(@Self.FMyObj);
end;
procedure TMyComp.SetOnUpdate(const Value: TOnMyEvent);
begin
FOnUpdate := Value;
end;
end.
Далее в программе:
procedure OnUpdate(Sender: PMyObj);
begin
ShowMessage(Sender.Name);
end;
procedure TForm1.Button1Click(Sender: PObj);
var
MyComp: PMyComp;
begin
MyComp := NewMyComp;
MyComp.OnUpdate := TOnMyEvent(MakeMethod(nil, @OnUpdate) );
MyComp.Go;
MyComp.Free;
end;
Vladimir Kladov (2007-12-15 22:14:00) [6]Код присваивания обработчика событию, и код вызова - не приведены. (Наверняка опять различие ординарной процедуры и метода объекта, но не на 100% - здесь-то оно зачем. А может вы просто Sender и Self перепутали. Без кода непонятно).