Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.03.15;
Скачать: CL | DM;

Вниз

Вызов метода, чтоб его...   Найти похожие ветки 

 
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 вся ветка

Текущий архив: 2009.03.15;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.022 c
2-1232518754
charoey_mag
2009-01-21 09:19
2009.03.15
Потоки и Indy


2-1233054476
Merry
2009-01-27 14:07
2009.03.15
операции с датами


3-1216183175
Rav
2008-07-16 08:39
2009.03.15
Как заставить работать ADO в сервисе NT


2-1232578253
RustB
2009-01-22 01:50
2009.03.15
Ошибка при добавлении записи в access


6-1200748956
VoV_I_K
2008-01-19 16:22
2009.03.15
Как передать(получить) данные извыполняемог jscript в приложение?