[fpc-pascal]Passing Methods as Callback Procedures?

Jon David Sawyer badquanta6384 at comcast.net
Tue Dec 17 19:20:36 CET 2002


On Tue, 2002-12-17 at 12:23, Karagiannidis Savvas wrote:
> On  Monday, December 16, 2002 10:27 PM     Jon David Sawyer  wrote :
> 
> 
> > On Mon, 2002-12-16 at 13:57, memsom at interalpha.co.uk wrote:
> > > > Ok,  I've got some code that looks like this:
> > > >
> > > > fCollection.ForEach(@Self.DoEach);
> > > >
> > > > Now when DoEach() is called its Self and the Self above
> > > > are not the same...
> > > >
> > > > Is this supposed to happen?
> > >
> > > Yes. 'Self' refers to the Instance you currently reside within. So:
> > >
> > > procedure TMyClass.dosomething(..);
> > > begin
> > >   //Self is the instance of TMyClass
> > > end;
> > >
> > > procedure TCollection.ForEach(..);
> > > begin
> > >   //Self is the instance of TCollection
> > > end;
> > >
> > > Therefore, as 'Self' refers to the Instance the code belongs to, Self
> will
> > > differ in every unique class instance.
> > >
> > > What is the parameter for the 'TCollection.ForEach' method? I assume
> it's a
> > > typed method pointer? You should be able to just use the following:
> > >
> > > fCollection.ForEach(DoEach); //assign this within the class that owns
> 'DoEach'.
> > >
> > > You don't *need* to use Self, unless your class is out of scope, for
> example
> > > accessed within a 'with' statement and clashes with a class
> method/property for
> > > the with'd class.
> > >
> > > e.g.
> > >
> > >   procedure TForm1.Button1Clicked(sender: TObject);
> > >   begin
> > >     Caption := 'wabble'; // the form
> > >
> > >     with sender as TButton do begin
> > >
> > >       Caption := 'wibble'; //the button not the form
> > >
> > >       Self.Caption := 'wobble'; //the form
> > >
> > >     end;
> > >   end;
> > >
> > >
> > > Matt
> > >
> > >
> > I belive you missunderstood what I was trying to do:
> > I had My object which used another object.  That otehr object was
> > a tCollection.  tCOllection has a method in which you can pass
> > a procedure to process each individual item in the collection.
> >
> > I was trying to pass My object's item handler , MyObject.DoEach, as
> > the callback procedure for ForEach();  ie:
> > fCOllection.ForEach(@Self.DoEach);
> >
> > The compiler doesn't complain about this code.  However the correct
> > instance of the object is not called when DoEach() is called.
> >
> > My problem is that prior to going into ForEach() self equals something
> > diffrent than when ForEach() calls DoEach().
> > >
> 
> In ForEach you must pass two parameters.
> The first must be a pointer to the object whose method you want to call
>    and the second must be the pointer to the object's method.
> 
> 
> Note that fCollection must accept the second parameter as a pointer to a
> procedure,
> but the type of the procedure is different than the object's method. The
> difference between them is that
> the procedure has an extra parameter, which must be the first parameter you
> pass to the procedure,
> and must be the pointer that points to the object whose method you wish to
> call...
> 
> for example :
> 
> 
> TDoEachProc = procedure (objptr : pointer;  ...... (actual method
> parameters)  );
> 
> fCollection = class
>    procedure ForEach( callbackobj : pointer; callbackproc : TDoEachProc );
> end;
> 
> procedure fCollection.ForEach ( callbackobj : pointer; callbackproc :
> TDoEachProc );
> begin
>   callbackproc( callbackobj ,  ... parameters for the method... );
> end;
> 
> 
> Now, in the other object, you can use
> 
> procedure AnObject.DoEach(...)
> begin
> ...
> end;
> 
> procedure AnObject.SetCallBack;
> var p : pointer;
> begin
>   ...
>   p := @DoEach;
>   fCollection.ForEach(Self,TDoEachProc(p));
> end;
> 
> This should work for you, BUT I don't think you should do something like
> that!
> I'm sure that there is a better way of doing what you want...
> 
> 
If there is a better way of doing this I'd be most intrested in hearing?
I *was* able to get the code worknig the way  wanted by overrideing
tCollection.ForEach with one that took a Procedure Of Object; callback. 
But *IF* there is an even better way then I'm all for it! ^_^

[to the message board]
Sorry about the multipul replys.  for some reason my Email client puked
on me yesterday. (Evolution)
> 
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal






More information about the fpc-pascal mailing list