Форум: "KOL";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
ВнизВызов метода, чтоб его... Найти похожие ветки
← →
Dima (2007-12-15 22:08) [0]Привет всем. Хотел написать небольшой компонент, основанный на объектах (надо для практики), но есть трабла. Помогите пожалуйста. Если я чего не понял, прошу не ругать :) Я начинающий. В целом компонент такого вида:
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, как прога вылетает. Почему?
← →
Vladimir Kladov © (2007-12-15 22:14) [1]Код присваивания обработчика событию, и код вызова - не приведены. (Наверняка опять различие ординарной процедуры и метода объекта, но не на 100% - здесь-то оно зачем. А может вы просто Sender и Self перепутали. Без кода непонятно).
← →
Dima (2007-12-15 22:51) [2]Ну вот как-то так:
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;
← →
Dima (2007-12-15 22:54) [3]Это только пример, я специально наваял, но принцип того, что хочу сделать, видно.
← →
Дмитрий К © (2007-12-15 23:24) [4]У меня вот так заработало. А почему, сами разбирайтесь, либо пусть кто другой объяснит. Я в теории - не очень.
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.
← →
Vladimir Kladov © (2007-12-16 08:31) [5]Это именно то, что я и подозревал как №1.
procedure OnUpdate(Dummy, Sender: PMyObj);
Как я в описании Соль заметил, выросло поколение (хороших, но неграмотных) программеров, которых инфиксная запись и отсутствия явной передачи параметра-объекта сбивает с толку. Не пишут параметр, значит его как бы и нет.
← →
Dima (2007-12-16 09:17) [6]Спасибо всем, я понял в чём дело :)
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.063 c