Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 1999-07

Latest source is attached.

8 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author
to Michael A. Hess: Let me throw my hat into this fire. I hope this doesn't confuse the issue. FPC already…
Michael A. Hess wrote 50 lines
Shane Miller wrote: > Let me throw my hat into this fire. I hope this doesn't confuse the issue. FPC already has a messaging system built in. I was having problems getting it working a few weeks ago and due to other commitments that many of us seemed to have at the same time I didn't get much further with it. I had planned on doing some this weekend. Any way here is how I had started trying to do the messaging thing. If you remember I first started with the GUIapi.pp file. This was suppose to be the file that was standard as far as access from the FCL but it would have different version for each type of API (GTK, QT) that you are using. It relys on the messaging built into the FPC. I am using the TForm as an example since that is what I was working with. First you would create the message routines in the class definition like thus: ++++++++++++++++++++++++++++++++++++++++++++++++++++ TCustomForm = class(TWinControl) . . . protected procedure DoDestroy(Self : TCustomForm); message 'destroy'; procedure DoShow(Self : TCustomForm); message 'show'; procedure DoFocus(Self : TCustomForm); message 'focus'; . . . end; procedure TCustomForm.DoDestroy(Self : TCustomForm); begin if Assigned (FOnDestroy) then FOnDestroy(Self); end; { do the same for DoShow and DoFocus } constructor TCustomForm.Create(AOwner : TComponent); begin . . . GUIAPI_Set_Callback('destroy', Self) GUIAPI_Set_Callback('show', Self) GUIAPI_Set_Callback('focus', Self)

This is essentially correct.

Do not forget that the callback must go to dispatchstr() and not to the DoDestroy. The Dispatchstr will call the DoDestroy by itself.

Good work, Michael (H).

Michael (V.C).

Reply by email

Michael A. Hess
to Shane Miller: I'm a bit confused yet on the implementation. Do you have any code that shows this yet?…
Shane Miller wrote
I'm a bit confused yet on the implementation.

I'm not surprise I really didn't go into great detail as to the connection between the gtk callback and how it is set up. All I was trying to do at this point was show you all that would be needed in the FCL if I can get my messaging scheme working.

Do you have any code that shows this yet?

As I mentioned I do have all the code added to TControl and the required GTK stuff in GUIAPI to make this work. It should work but I was having problem with the compiler before. The compiler just finished doing a fresh cycle from CVS as I type this line. I don't think I will get a chance to actually try a compile of my lazarus code tonight but I'll do so tomorrow. When I have it working or at least cleaned up for you to look at I'll sent it to you. (probably post a link to my ftp where the code will be)

I think I understand but if I understood when/how you used Dispatch(str) I think I would understand a bit better.

The GUIAPI_Set_Callback routine actually calls the gtk_connect stuff and it uses a method found in TControl that ALL gtk_connects attach to. This routine calls the DispatchStr with the correct message. This then filters up through the messaging chain.

Does that actually work now?

It should give me a day to run it through the new compiler. :-)

Does it send a "string" message to the "self" component? Are we supposed to do that after we receive a "signal" or does that replace it?

The code I showed in my email is ALL that would be required of ANY component. You would never have to do anything more then you see there. If your component needed to receive a 'resize' message you would simple put the following in your class.

protected
   procedure DoResize(Self : TCustomForm); message 'resize';

then actually write the procedure

procedure TCustomForm.DoResize(Self : TCustomForm);
begin
   if Assigned (FOnResize) then
      FOnResize(Self);
end;

and the following in your create.

GUIAPI_Set_Callback('resize', Self)

You would add this for any message you wanted to receive. Of course the GUIAPI would have to know about this kind message but if it didn't already know about it you would just add it.

If it replaces it, how do we watch for a resize without trapping the signal from the gtk widget?

You are getting the signals from the gtk widgets. It is just that instead of each component needing to call the gtk_connect and write a specific method to handle the callback, all callbacks go to just one method found in the TControl component. Then the built in message dispatcher passes it to the correct location.

As I said give me a day or two at most and I send you code. I won't commit it to CVS until we get a chance to go over it together.

Talk at you later,

==== Programming my first best destiny! ==== Michael A. Hess Miracle Concepts, Inc. http://www.miraclec.com

Reply by email

Shane Miller

I'm a bit confused yet on the implementation. Do you have any code that shows this yet?
I think I understand but if I understood when/how you used Dispatch(str) I think I would understand a bit better. Does that actually work now? Does it send a "string" message to the "self" component? Are we supposed to do that after we receive a "signal" or does that replace it?

If it replaces it, how do we watch for a resize without trapping the signal from the gtk widget?

Shane

Earlier message 116 lines
-----Original Message----- From: Michael A. Hess To: Date: Friday, July 02, 1999 4:34 PM Subject: Re: [lazarus] Latest source is attached. >Shane Miller wrote: >> > >Let me throw my hat into this fire. I hope this doesn't confuse the >issue. FPC already has a messaging system built in. I was having >problems getting it working a few weeks ago and due to other commitments >that many of us seemed to have at the same time I didn't get much >further with it. I had planned on doing some this weekend. Any way here >is how I had started trying to do the messaging thing. > >If you remember I first started with the GUIapi.pp file. This was >suppose to be the file that was standard as far as access from the FCL >but it would have different version for each type of API (GTK, QT) that >you are using. It relys on the messaging built into the FPC. > >I am using the TForm as an example since that is what I was working >with. First you would create the message routines in the class >definition like thus: > >++++++++++++++++++++++++++++++++++++++++++++++++++++ > >TCustomForm = class(TWinControl) >. >. >. >protected > procedure DoDestroy(Self : TCustomForm); message 'destroy'; > procedure DoShow(Self : TCustomForm); message 'show'; > procedure DoFocus(Self : TCustomForm); message 'focus'; >. >. >. >end; > >procedure TCustomForm.DoDestroy(Self : TCustomForm); >begin > if Assigned (FOnDestroy) then > FOnDestroy(Self); >end; > >{ do the same for DoShow and DoFocus } > >constructor TCustomForm.Create(AOwner : TComponent); >begin >. >. >. >GUIAPI_Set_Callback('destroy', Self) >GUIAPI_Set_Callback('show', Self) >GUIAPI_Set_Callback('focus', Self) >. >. >. >end; > > >destructor TCustomForm.Destroy; >begin >. >. >. > GUIAPI_Remove_Callback(Self); > inherited Destroy >end; > >++++++++++++++++++++++++++++++++++++++++++++++++ > > >That is all that is needed in the actual FCL code for any component. If >you write a component that inherits this one it gets these messages plus >any that you add to your new component. When you send a message to a >TControl it will try and find a matching message assigned to the >control. If it can't find one it moves up through the parent chain until >it does find it. > >I haven't shown the code that is required in Tcontrol that gets the >signal from GUIAPI but all call backs from the API in this case GTK is >tied to just one routine which then calls DispatchStr(signal) to send >the message off to the control. > >Does anyone understand what I am attempting here? I have all of this >already coded in a version of Lazarus that I was working with trying to >make this work. However when I was trying this about 5-6 weeks ago the >compiler was still having problems with all that procedure pointer and >ansistring stuff. I think most of that is fixed now and I have hopes >that this will now work. > >What this means is that we can separate all the call backs and all the >gtk calls into an independent file that just has routines that the FCL >know about and calls regardless of the API being used. This would then >start to allow people to easily write their own GUIAPI file for their >favorite API without effecting the core of the FCL. > >I can get back to working on this this weekend and try and get it >working. > >Opinions???? > >-- >==== Programming my first best destiny! ==== > >Michael A. Hess Miracle Concepts, Inc. > http://www.miraclec.com > >_________________________________________________________________ > To unsubscribe: mail with > "unsubscribe" as the Subject > archives at http://www.miraclec.com/list_archives/lazarus >

Reply by email

Shane Miller

Again, I appologize for attaching source. I don't want to update CVS with it quite yet though. This version is a bit further in my Multi-Platform/tools theory.

If you look at this, and look at the resize, createcomponent, and SETTEXT methods. Here you will find examples of my theory on using INTSENDMESSAGE and INTSENDMESSAGE2 which are found in gtkint.pp. The theory is whatever is defines (QT or GTK) interfaces.pp will create a class with procedures like INTSENDMESSAGE that can be used to create the components.

Eventually all the GTK code will be removed from TFORMS, TCONTROLS, etc and the only gtk stuff will be in gtkint.pp.

My current hold up is resizing.  If you specify a Left, Top, Width or Height TControls (in resize) calls InterfaceObject.IntSendMessage2(message,parent,child,record of 4 values);

In gtkint the size is set. If it's a form I want to look through gtkfixed children list and see what controls are attached to that form and send a message to resize them.

I just can't come up with a good way to do that....

Please look at the source and give me your thoughts on the theory..

Shane

-------------- next part --------------
A non-text attachment was scrubbed...
Name: zip00007.zip
Type: application/octet-stream
Size: 50139 bytes
Desc: "PKZIP (compressed) files"
Url : http://localhost/pipermail/lazarus/attachments/19990702/7db78abb/zip00007.obj

Reply by email

Michael A. Hess
to Shane Miller
Shane Miller wrote

Let me throw my hat into this fire. I hope this doesn't confuse the issue. FPC already has a messaging system built in. I was having problems getting it working a few weeks ago and due to other commitments that many of us seemed to have at the same time I didn't get much further with it. I had planned on doing some this weekend. Any way here is how I had started trying to do the messaging thing.

If you remember I first started with the GUIapi.pp file. This was suppose to be the file that was standard as far as access from the FCL but it would have different version for each type of API (GTK, QT) that you are using. It relys on the messaging built into the FPC.

I am using the TForm as an example since that is what I was working with. First you would create the message routines in the class definition like thus:

++++++++++++++++++++++++++++++++++++++++++++++++++++

TCustomForm = class(TWinControl)
.
.
.
protected

   procedure DoDestroy(Self : TCustomForm); message 'destroy';
   procedure DoShow(Self : TCustomForm); message 'show';
   procedure DoFocus(Self : TCustomForm); message 'focus';

.
.
.
end;

procedure TCustomForm.DoDestroy(Self : TCustomForm);
begin
   if Assigned (FOnDestroy) then
      FOnDestroy(Self);
end;

{ do the same for DoShow and DoFocus }

constructor TCustomForm.Create(AOwner : TComponent); begin
.
.
.
GUIAPI_Set_Callback('destroy', Self)
GUIAPI_Set_Callback('show', Self)
GUIAPI_Set_Callback('focus', Self)
.
.
.
end;

destructor TCustomForm.Destroy;
begin
.
.
.
   GUIAPI_Remove_Callback(Self);
   inherited Destroy
end;

++++++++++++++++++++++++++++++++++++++++++++++++

That is all that is needed in the actual FCL code for any component. If you write a component that inherits this one it gets these messages plus any that you add to your new component. When you send a message to a TControl it will try and find a matching message assigned to the control. If it can't find one it moves up through the parent chain until it does find it.

I haven't shown the code that is required in Tcontrol that gets the signal from GUIAPI but all call backs from the API in this case GTK is tied to just one routine which then calls DispatchStr(signal) to send the message off to the control.

Does anyone understand what I am attempting here? I have all of this already coded in a version of Lazarus that I was working with trying to make this work. However when I was trying this about 5-6 weeks ago the compiler was still having problems with all that procedure pointer and ansistring stuff. I think most of that is fixed now and I have hopes that this will now work.

What this means is that we can separate all the call backs and all the gtk calls into an independent file that just has routines that the FCL know about and calls regardless of the API being used. This would then start to allow people to easily write their own GUIAPI file for their favorite API without effecting the core of the FCL.

I can get back to working on this this weekend and try and get it working.

Opinions????

==== Programming my first best destiny! ==== Michael A. Hess Miracle Concepts, Inc. http://www.miraclec.com

Reply by email

Michael A. Hess
to Shane Miller: Now I'm confused. Got any working example code? Shane
Shane Miller wrote
Now I'm confused. Got any working example code?

Let me give you the simple explaination.

In objpas of the RTL which defines TObjects there is a method called DispatchStr. When you setup a procedure in your class using,

procedure something(self : thisClass); message 'show';

the compiler adds this method to a table and cross references it to the string 'show'. When you call DispatchStr for a given component that inherited from TObject (which everything does) and pass it the message such as:

Dispatch('show');

The object goes through the table, finds the matching message, and then calls the method indicated in the table.

So what I am doing is setting up the messages for the various components such as the TForm example in my previous email.

     procedure DoShow(Self : TCustomForm); message 'show';

Then in the Create I call:

      GUIAPI_Callback('show', Self);

Now in the GUIAPI_Callback it determines what kind of message needs to be handled. In this case it is a 'show' message.

For every type of message possible there is a separate routine that is used as the callback from gtk.

   procedure GUIAPI_Callback(signal : string, Sender : TControl);
   var
      gObject : gtk_Object;
      signalFunc : Pointer;
      gSignal : array[0..15] of char;
   begin
   .
   .
   .
      gObject := gtk_Object(Sender.fcomponent);
      if signal = 'show' then
	   signalFunc = @gtkshowCB;
   .
   .
   .
      gtk_signal_connect(gObject, gSignal, gtk_Signal_Func(signalFunc),
Sender);
   end;

When the above function sees the 'show' message it knows to setup the callback to gtkshowCB and it passes Self as the data.

So now you need to write the gtkshowCB. It looks like this

   function gtkshowCB(widget: PGtkWidget; data: gPointer):Boolean;cdecl;
   begin
      TControl(data).GUIAPI_Signals('show', TControl(data));
   end;

Every 'show' message callback from gtk, no matter what component, will go through here. It uses the data value which points to Self which is the actual control that needs to receive the message. Every component is based on TControl so in that class I create the GUIAPI_Signals method.

It then looks like this.

   procedure TControl.GUIAPI_Signals(signal : string, obj : TControl);
   begin
      DispatchStr(signal);
   end;

At this point the message is of to the appropriate control and should be handled as you wish.

Now this is how I have it all setup in code and it wasn't quite working before but that was due to the fact that various aspects of the compiler namely some of the pointer stuff wasn't working right. I believe that it should work now since it has been stated that it has been corrected.

I don't have clean code to send at this point since I was kludging around in the code as it WAS about 6 weeks ago. I have gotten fresh code out of CVS and will add this to the current code and try and compile and see if it works.

Does that make it clearer?

I will send you the code as soon as I have it working.

==== Programming my first best destiny! ==== Michael A. Hess Miracle Concepts, Inc. http://www.miraclec.com

Reply by email

Shane Miller
Show quoted text 10 lines
This is essentially correct. Do not forget that the callback must go to dispatchstr() and not to the DoDestroy. The Dispatchstr will call the DoDestroy by itself. Good work, Michael (H). Michael (V.C).

Now I'm confused. Got any working example code?

Shane

Reply by email