[lazarus] Has message handler stuff been implemented yet???

Michael Van Canneyt michael.vancanneyt at wisa.be
Mon May 17 04:22:43 EDT 1999




On Sun, 16 May 1999, Michael A. Hess wrote:

> michael at tfdec1.fys.kuleuven.ac.be wrote:
> > 
> > the following should compile:
> > 
> > ------------------------------------------------------
> > 
> > program testit;
> > 
> > Type TMyObject = Class (Tobject)
> >        A : Integer;
> >        Procedure DoClick (Var B : Integer; Self : TMyObject); message 'click';
> >        end;
> > 
> > Procedure TMyObject.DoClick (Var B : Integer; Self : TMyObject);
> > 
> > begin
> >   Writeln ('B : ',B);
> >   Writeln ('A : ',A);
> > end;
> > 
> > Type TCallPRoc = Procedure (Var B: Integer; Obj : TMyObject) of object;
> > 
> > Var MyObject : TMyObject;
> >     MyProc : TCallProc;
> >     P : Pointer;
> > 
> > begin
> >   MyObject:=TMyObject.Create;
> >   MyObject.A:=1;
> >   // MyProc:=@MyObject.DoClick;
> >   // MyProc(2,MyObject);
> >   MyObject.Free;
> > end.
> > 
> > -----------------------------------------------------------------------
> 
> OK this does compile OK, but I don't totally understand it. If you don't
> have the var B: integer then the compiler craps out big time. Messes up
> my terminal and everything. Is that leading variable required?
> 
> Secondly I guess I just don't understand the mechanics of this thing as
> a whole. What is the purpose of the ;message 'click'; statement at the
> end of the line. You seem to set the pointer MyProc equal to the value
> of MyObject.DoClick and then try and call the procedure. Where does the
> message 'click' part come into it? Sorry if this is a stupid question
> but I don't see why the code wouldn't be exactly the same if you didn't
> have the message 'click' added.
> 
> What am I missing? Could you explain this to me?

The point is that under Windows you have message functions.

Procedure DoKey (...) message WM_KEyCLICK;
For such a procedure, special RTTI is generated.

All messages for an object come to 1 central procedure, which then calls
dispatch (a method from TObject) which looks through the RTTI to see if
there is a handler for the message registered. If so it is called. Thus,
a Windows message arrives at the procedure you registered.

Gtk has also messages, but they are strings, hence the possibility
Procedure DoKey ( ) message 'string';
Likewise, there is now a procedure DispatchStr() which takes a string as
and argument (the signal name) and looks in the RTTI to see if there is
a handler registered for the given signal name.

A problem with this is that GTK is not object oriented, but does allow
to pass data to the signal call. This means that you must put a pointer
to 'self' in this data, and that 'self' must be loaded into the object
when the function gets called: hence the above syntax.

So the above syntax is a mixture of 2 things: allowing string-type messages,
and allowing calls from Non-OOP toolkits to OOP objects.

I don't know if GTK supports a 'all-purpose' signal handler; i.e. a signal handler
that is called for any type of signal, but with additionally the signal as an option;

Then you could do

TControl.GTKSignals (Msg : String; Self : TControl);

begin
  // Self loaded automatically !!
  Dispatchstr (Msg); // Calls the function that responds to 'msg'
end,

Any signal should then be connected to TControl.GTKSignals, which would dispatch
automatically to any function with message MSG.
(This is the windows way of doing things)

I hope this is clear :(

Michael.







More information about the Lazarus mailing list