Sign in Join

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

Mailing lists / lazarus / 1999-08

More Native Win32 stuff(Pascal,canyouhelphere?)

22 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

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

Michael A. Hess
to Shane Miller: During the LM_CREATE, you have the SENDER, so you could also create a TLISt (if it's…
Shane Miller wrote 5 lines
During the LM_CREATE, you have the SENDER, so you could also create a TLISt (if it's still nil) then ADD an object (sender) and the handle returned from the CreateWindowEx. However, you may receive the handle AFTER the WM_CREATE is passed.

Correct. The AFTER bit is the problem. From the other email though it has been indicated that you can add the "Self" value to the HWND structure so we should be able to retieve it that way.

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

Reply by email

Michael A. Hess
to Jeffrey A. Wormsley: during and Well, that was where I was having all the trouble, in "create(ing) a callback…
Jeffrey A. Wormsley wrote
I think the method worked out by Marc and Michael (H) will work out very well, though. It seems like an (almost) no brainer, once pointed out.

Cool! Glad you got in the groove of it now. I can't wait to see a Windows API working. Or at least something that will do the Hello World demo. :-)

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

Reply by email

Michael A. Hess
to Shane Miller: Couldn't you inherit CONTROLS.PP or FORMS.PP or whereever the TApplication is stored and…
Shane Miller wrote
Couldn't you inherit CONTROLS.PP or FORMS.PP or whereever the TApplication is stored and run through it's components list and see if the handles match, then use the object in the list to call Dispatch.

This would be one avenue except in the cast of WM_CREATE. This is sent to the callback BEFORE the actual CreateWindow function returns. So you haven't been able to place the HWND in the TControl class yet to do the search.

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

Reply by email

Jeffrey A. Wormsley
Shane Miller wrote 5 lines
No...that's not the way to do it. First, I think each control should have it's own. You keep saying that it's not possible to do because you would need to assign TControl's windowproc, but that makes it easy! All you do is

during

the create (LM_CREATE) in win32int.pp (or whatever) you create a callback procedure that gets passed the Sender. Then in that callback you do a TCOntrtol(Data_Received_In_Call_Back).WindowProc or something like that

and

you'll be calling THAT control's windowproc.

Well, that was where I was having all the trouble, in "create(ing) a callback procedure that gets passed the Sender."

I think the method worked out by Marc and Michael (H) will work out very well, though. It seems like an (almost) no brainer, once pointed out.

Jeff.

Reply by email

Michael A. Hess
to Shane Miller: Here is a basic map of how it's done: We call gtkint.pp and send it a "message" or…
Shane Miller wrote 15 lines
Here is a basic map of how it's done: We call gtkint.pp and send it a "message" or "command" LM_CREATE. gtkint.pp says 'Hey, I received a LM_CREATE so they want me to create something!" (That's the English version of gtkint.pp talking of course) gtkint then checks the SELF parameter (as a tcontrol) and check's it's compstyle and says "Hey, it's a compstyle is csFORM so I'll create a FORM!'. (gtkint.pp is very excitable, that's why it talks that way.) So, now in order to detect when someone clicks on the form, TControl (for TForm) calls SetCAllBack(LM_CLICKED) and that's passed onto gtkint.pp.

All of this is easy to do and he won't have any problems doing what is indicated above. However .....

GtKINT.PP get's it's SetCallBack called with a SELF and a LM_CLICKED so it sets a callback procedure up to be called when a clicked event occurs. In that callback, it uses the SELF to call DISPATCH(LM_CLICKED).

this is the problem. At present I don't see an easy way to get the value Self back to the callback. The other issue is that ALL messages for a given window (which in windows means buttons, scrollbars, just about everything) goes through only ONE callback for that control. So the callback must determine which message it is getting and then tranlate the message to an LM_XXX message and call Dispatch. However since Self isn't readily available something tricky needs to take place to determine which "Self" the passed HWND represents. The only really, really nice thing about this is that ALL and I mean ALL of the messages from ALL of the controls will go through just ONE callback routine. It will make that part of the win32int a whole lot cleaner and smaller than the GTK version.

That is assuming we can figure out a clean and easy way to get the "Self" value to the callback.

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

Reply by email

Shane Miller

Here is a basic map of how it's done:

We call gtkint.pp and send it a "message" or "command" LM_CREATE. gtkint.pp says 'Hey, I received a LM_CREATE so they want me to create something!" (That's the English version of gtkint.pp talking of course)

gtkint then checks the SELF parameter (as a tcontrol) and check's it's compstyle and says "Hey, it's a compstyle is csFORM so I'll create a FORM!'. (gtkint.pp is very excitable, that's why it talks that way.)

So, now in order to detect when someone clicks on the form, TControl (for TForm) calls SetCAllBack(LM_CLICKED) and that's passed onto gtkint.pp.

GtKINT.PP get's it's SetCallBack called with a SELF and a LM_CLICKED so it sets a callback procedure up to be called when a clicked event occurs. In that callback, it uses the SELF to call DISPATCH(LM_CLICKED).

The LM_CLICKED is dispatch to TOBJECT, and it climbs UP the object tree looking for a procedure defined as

Procedure Something(var Message) message LM_CLICKED;

and when it sees that, it calls that procedure....

Basically that's how the messaging works. You should be able to do the exact same thing with WIN32.

I hope this helps.

Shane

Reply by email

Jeff Wormsley
to Shane Miller
Shane Miller wrote 6 lines
Here is a basic map of how it's done: We call gtkint.pp and send it a "message" or "command" LM_CREATE. gtkint.pp says 'Hey, I received a LM_CREATE so they want me to create something!" (That's the English version of gtkint.pp talking of course) gtkint then checks the SELF parameter (as a tcontrol) and check's it's compstyle and says "Hey, it's a compstyle is csFORM so I'll create a FORM!'. (gtkint.pp is very excitable, that's why it talks that way.)

Aaarrrgghhhh. This is exactly where I am having the problem!!! "Hey, it's a compstyle is csFORM so I'll create a FORM!' HOW!!! Presumably the TForm is in the process of being created (which is why I got the LM_CREATE in the first place). What this LCL TForm is missing is a Window, a window handler, and events. Below, you cover the events. I know how to create a window. Where do I create, or is already created, the window handler??? I have read it is already in TObject in one place, and that I have to create it in another, and I am lost as to what I am supposed to do.

So, now in order to detect when someone clicks on the form, TControl (for TForm) calls SetCAllBack(LM_CLICKED) and that's passed onto gtkint.pp. GtKINT.PP get's it's SetCallBack called with a SELF and a LM_CLICKED so it sets a callback procedure up to be called when a clicked event occurs. In that callback, it uses the SELF to call DISPATCH(LM_CLICKED).

Again, where is this callback procedure declared? In gtkint.pp? How do you get a unique one for each control if the code is in gtkint.pp?

Show quoted text 7 lines
The LM_CLICKED is dispatch to TOBJECT, and it climbs UP the object tree looking for a procedure defined as Procedure Something(var Message) message LM_CLICKED; and when it sees that, it calls that procedure.... Basically that's how the messaging works. You should be able to do the exact same thing with WIN32.

With the two exceptions above, I follow you. But gtk hides so much of what is going on in the DLL's it is impossible for me to know what is going on. Just seeing a call to gtk_main tells me nothing. It is beginning to look like I am going to have to create a completely independent TForm which is equivalent to a gtk widget (I forget the name, the one called by the create for MainForm). This can't be right.

I hope this helps.

I wish it did. Thanks for trying. It must be getting on everyones nerves by now. I feel as thick as the base of the great pyramid right now.

Jeff.

Reply by email

Jeffrey A. Wormsley
Marc Weustink wrote
You can pass extra info to a Windows window. This way you could store the "self" value when you create it. When you receive a Windows message you

can

retrieve the "self" value for this HWND. Look at GetProp, SetProc (user32.lib, windows.h) etc.

The point was, at the time of LM_Create, I didn't think I had a windows procedure. What Michael is suggesting is that I have one and only one, and it does the job for every component, and hence has to know (via a TList) about each and every component. This is completely different from Delphi, in that Delphi has a single window procedure for every component, and that window procedure only need to know about itself. The confusion is the definition of "Window Procedure". I am using it to mean the procedure that is associated in Windows to the HWnd handle (I will refer to this in "'s). So that if windows detects a window handle that needs a message, it calls the "window procedure" associated with that handle. In Delphi, this is a trivial process, since the "window procedure" associated to the handle is on a one on one basis, each Hwnd handle only has its own "window procedure" that messages can be passed to.

Going the way Michael has suggested would mean that every Hwnd is associated with one single "window procedure" and that procedure would be responsible for looking up the Hwnd in a list, retrieving the Data pointer that was passed in the LM_CREATE SendMessage, and then using the Dispatch method of the TObject pointed to by the Data pointer to send the apporopriate message to the component for processing by the attached message handler, if present. Dispatch is calling the LCL [window procedure] (brackets as opposed to "'s), or message handler if you will, that searches up the component tree trying to find a handler for the message.

This is feasible, but I am not convinced it is the best way to do things. For one, it would be a real bottleneck in terms of performance. Having to look up in a list of hundreds or thousands of components would seem to be a needless slowdown, as compared to having a unique "window procedure" for each component.

When I started this, I was hoping to do it the Delphi way, where each window handle had it's own "window procedure" as a method of the TControl object, but there is no way I can see at the Interface.pp level, that I can see, to do this. It has to be done at the TControl level, but TControl is in the LCL, and hence should ideally be API toolkit independent. The quick and dirty fix would be to make the TControl use IFDEFs to check for windows and compile in the "window procedure" code, and let that procedure take the WM_xxx messages and Dispatch the LM_xxx equivalents. It isn't clear how to go the other way, though. In other words, how does a form, on recieving a LM_RESIZE send a LM_RESIZE to all of it's children. My guess is that it can bypass the "window procedure" completely and just Dispatch the LM_RESIZE to each of the children directly.

I think I have most of the confusion cleared up now, and can now concentrate on how best to implement whichever mechanism is deemed best.

Jeff.

Reply by email

Michael A. Hess
to Jeffrey A. Wormsley: This makes my previous post moot, then, if this works as advertised. I will look into it…
Jeffrey A. Wormsley wrote 7 lines
This makes my previous post moot, then, if this works as advertised. I will look into it immediately! >Let me know if you need some more explaination. :-) I will let you know as soon as I finish this bit of research!

If you do find that this isn't possible then there still might be a way to do it via the one WindProc for each control method. It will be a little strange but it just might work. If you can attach the "Self" value to the HWND that would be the prefered method so keep looking at how to do that.

I have to run out to the mighty WalMart so I won't be back until later. Let me know what you find out and if it is negative I'll give you my thoughts on the other way of doing it.

Talk at you later,

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

Reply by email

Shane Miller

Buy have their stock and they just reported record earnings today. :-)
------------------------------------------------------------ Shane Miller

Home page : http://www.lakefield.net/~smiller

Auto-IP Publisher : http://www.lakefield.net/~smiller/autoip

Advanced Clipboard : http://www.lakefield.net/~smiller/advclipboard

Lazarus : http://www.pcpros.net/~vbman
----------------------------------------------------------

Earlier message 38 lines
-----Original Message----- From: Michael A. Hess To: Date: Tuesday, August 10, 1999 4:12 PM Subject: Re: [lazarus] More Native Win32 stuff(Pascal,canyouhelphere?) >Jeffrey A. Wormsley wrote: >> >> This makes my previous post moot, then, if this works as advertised. >> I will look into it immediately! >> >> >Let me know if you need some more explaination. :-) >> >> I will let you know as soon as I finish this bit of research! > >If you do find that this isn't possible then there still might be a way >to do it via the one WindProc for each control method. It will be a >little strange but it just might work. If you can attach the "Self" >value to the HWND that would be the prefered method so keep looking at >how to do that. > >I have to run out to the mighty WalMart so I won't be back until later. >Let me know what you find out and if it is negative I'll give you my >thoughts on the other way of doing it. > >Talk at you later, >-- >==== 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

Jeff Wormsley
to Shane Miller: Here is a basic map of how it's done: We call gtkint.pp and send it a "message" or…
Michael A. Hess wrote 12 lines
this is the problem. At present I don't see an easy way to get the value Self back to the callback. The other issue is that ALL messages for a given window (which in windows means buttons, scrollbars, just about everything) goes through only ONE callback for that control. So the callback must determine which message it is getting and then tranlate the message to an LM_XXX message and call Dispatch. However since Self isn't readily available something tricky needs to take place to determine which "Self" the passed HWND represents. The only really, really nice thing about this is that ALL and I mean ALL of the messages from ALL of the controls will go through just ONE callback routine. It will make that part of the win32int a whole lot cleaner and smaller than the GTK version.

I said I was leaving, but... This answers a WHOLE LOT about what you have been trying to tell me. I saw in the VCL that Delphi implemented a (native) window procedure for each and every component. You are saying to implement one native window procedure for all components, then have that call the LCL window procedure via the callbacks, after figuring out which component it is via the Hwnd variable. Now that I can probably do, if I keep a list of each component I create along with the Self and HWnd, then the dispatch becomes a search and a call. When I get a LM_Destroy I remove the item from the list.

Jeff.

Reply by email

Jeffrey A. Wormsley
Michael A. Hess wrote 11 lines
If you do find that this isn't possible then there still might be a way to do it via the one WindProc for each control method. It will be a little strange but it just might work. If you can attach the "Self" value to the HWND that would be the prefered method so keep looking at how to do that. I have to run out to the mighty WalMart so I won't be back until later. Let me know what you find out and if it is negative I'll give you my thoughts on the other way of doing it. Talk at you later,

It certainly looks possible. See my previous post (assuming the list keeps them in order, often the third message I send to the list is the first to arrive back.)

There are certain window types that will not use what I sent in the other message directly. For instance, dialog boxes work differently than other windows, using CreateDialog instead of CreateWindow, but I'll save those for later. All in all, it looks feasible, once I get just a few more nasties out of the way.

There may not be much code written, but all in all I would call this a very productive day!

Jeff.

Reply by email

Shane Miller

No...that's not the way to do it.

First, I think each control should have it's own.
You keep saying that it's not possible to do because you would need to assign TControl's windowproc, but that makes it easy! All you do is during the create (LM_CREATE) in win32int.pp (or whatever) you create a callback procedure that gets passed the Sender. Then in that callback you do a TCOntrtol(Data_Received_In_Call_Back).WindowProc or something like that and you'll be calling THAT control's windowproc.

It should be almost exactly like Delphi's method of handling it...... Because win32int.pp has the SENDER property it CAN call the windowProc. Another method would be to do a
TObject(Data_Received_In_Call_Back).Dispatch(LM_message) after determining what message you received in the callback. That's how we are doing gtk. Then the dispatch sends the message and tcontrol or whatever class that has a
Procedure Something(var msg) message LM_Message;
gets called and handles the message.

------------------------------------------------------------ Shane Miller

Home page : http://www.lakefield.net/~smiller

Auto-IP Publisher : http://www.lakefield.net/~smiller/autoip

Advanced Clipboard : http://www.lakefield.net/~smiller/advclipboard

Lazarus : http://www.pcpros.net/~vbman
----------------------------------------------------------

Earlier message 69 lines
-----Original Message----- From: Jeffrey A. Wormsley To: Date: Tuesday, August 10, 1999 3:52 PM Subject: Re: [lazarus] More Native Win32 stuff(Pascal,canyouhelphere?) >On 8/10/99, at 11:44 PM, Marc Weustink wrote: > >>You can pass extra info to a Windows window. This way you could store the >>"self" value when you create it. When you receive a Windows message you >can >>retrieve the "self" value for this HWND. Look at GetProp, SetProc >>(user32.lib, windows.h) etc. > >The point was, at the time of LM_Create, I didn't think I had a windows >procedure. What Michael is suggesting is that I have one and only one, and >it does the job for every component, and hence has to know (via a TList) >about each and every component. This is completely different from Delphi, >in that Delphi has a single window procedure for every component, and that >window procedure only need to know about itself. The confusion is the >definition of "Window Procedure". I am using it to mean the procedure that >is associated in Windows to the HWnd handle (I will refer to this in "'s). >So that if windows detects a window handle that needs a message, it calls >the "window procedure" associated with that handle. In Delphi, this is a >trivial process, since the "window procedure" associated to the handle is >on a one on one basis, each Hwnd handle only has its own "window procedure" >that messages can be passed to. > >Going the way Michael has suggested would mean that every Hwnd is >associated with one single "window procedure" and that procedure would be >responsible for looking up the Hwnd in a list, retrieving the Data pointer >that was passed in the LM_CREATE SendMessage, and then using the Dispatch >method of the TObject pointed to by the Data pointer to send the >apporopriate message to the component for processing by the attached >message handler, if present. Dispatch is calling the LCL [window >procedure] (brackets as opposed to "'s), or message handler if you will, >that searches up the component tree trying to find a handler for the >message. > >This is feasible, but I am not convinced it is the best way to do things. >For one, it would be a real bottleneck in terms of performance. Having to >look up in a list of hundreds or thousands of components would seem to be a >needless slowdown, as compared to having a unique "window procedure" for >each component. > >When I started this, I was hoping to do it the Delphi way, where each >window handle had it's own "window procedure" as a method of the TControl >object, but there is no way I can see at the Interface.pp level, that I can >see, to do this. It has to be done at the TControl level, but TControl is >in the LCL, and hence should ideally be API toolkit independent. The quick >and dirty fix would be to make the TControl use IFDEFs to check for windows >and compile in the "window procedure" code, and let that procedure take the >WM_xxx messages and Dispatch the LM_xxx equivalents. It isn't clear how to >go the other way, though. In other words, how does a form, on recieving a >LM_RESIZE send a LM_RESIZE to all of it's children. My guess is that it >can bypass the "window procedure" completely and just Dispatch the >LM_RESIZE to each of the children directly. > >I think I have most of the confusion cleared up now, and can now >concentrate on how best to implement whichever mechanism is deemed best. > >Jeff. > >_________________________________________________________________ > To unsubscribe: mail with > "unsubscribe" as the Subject > archives at http://www.miraclec.com/list_archives/lazarus >

Reply by email

Shane Miller

During the LM_CREATE, you have the SENDER, so you could also create a TLISt (if it's still nil) then ADD an object (sender) and the handle returned from the CreateWindowEx. However, you may receive the handle AFTER the WM_CREATE is passed.

Look at TCreateParams in Delphi. What is the Param property? Could that be used?

>> "Michael A. Hess" 08/10 3:47 PM >>>
Shane Miller wrote 15 lines
Here is a basic map of how it's done: We call gtkint.pp and send it a "message" or "command" LM_CREATE. gtkint.pp says 'Hey, I received a LM_CREATE so they want me to create something!" (That's the English version of gtkint.pp talking of course) gtkint then checks the SELF parameter (as a tcontrol) and check's it's compstyle and says "Hey, it's a compstyle is csFORM so I'll create a FORM!'. (gtkint.pp is very excitable, that's why it talks that way.) So, now in order to detect when someone clicks on the form, TControl (for TForm) calls SetCAllBack(LM_CLICKED) and that's passed onto gtkint.pp.

All of this is easy to do and he won't have any problems doing what is indicated above. However .....

GtKINT.PP get's it's SetCallBack called with a SELF and a LM_CLICKED so it sets a callback procedure up to be called when a clicked event occurs. In that callback, it uses the SELF to call DISPATCH(LM_CLICKED).

this is the problem. At present I don't see an easy way to get the value Self back to the callback. The other issue is that ALL messages for a given window (which in windows means buttons, scrollbars, just about everything) goes through only ONE callback for that control. So the callback must determine which message it is getting and then tranlate the message to an LM_XXX message and call Dispatch. However since Self isn't readily available something tricky needs to take place to determine which "Self" the passed HWND represents. The only really, really nice thing about this is that ALL and I mean ALL of the messages from ALL of the controls will go through just ONE callback routine. It will make that part of the win32int a whole lot cleaner and smaller than the GTK version.

That is assuming we can figure out a clean and easy way to get the "Self" value to the callback.

==== 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

Couldn't you inherit CONTROLS.PP or FORMS.PP or whereever the TApplication is stored and run through it's components list and see if the handles match, then use the object in the list to call Dispatch.

Not sure if that's possible.
Shane

>> "Michael A. Hess" 08/10 3:41 PM >>>

OK I did some digging in the Windows API when I got home and here is what I have found.

First off you will be handling this exactly the same way we are doing it for GTK. The only difference is that you are going to be calling the Windows API.

If you look in the current gtkint unit you will see that in IntSendMessage3 (this will eventually be the only routine for handling messages) the LM_Create message calls CreateComponent passing it the Sender value. This is the Pointer to the TObject that is requesting creation. In our example it is a Form (aka window).

Now if you look in the CreateComponent routine you see that it next determines what it needs to create by looking at the CompStyle found in the TControl Class which is what Sender represents. Again we assume in this case that this is csForm since we want to create a Form (aka window).

It is in this csForm section where you will to the actual call to the Windows API (CreateWindow or CreateWindowEx) to make the window. Now as the API states before this returns it sends the WM_CREATE message to the Windows Procedure. Well the Windows Procedure is the callback handler from Windows. This is what you need to define in the WNDCLASS structure for the CLASS (window class) that you are creating. This Window Procedure routine will be located within the win32int unit.

You will need to have it point to a procedure that matches that which Windows expects to be calling. In the API it looks like this:

LRESULT CALLBACK WindowProc(

    HWND  hwnd,	// handle of window
    UINT  uMsg,	// message identifier
    WPARAM  wParam,	// first message parameter
    LPARAM  lParam 	// second message parameter
   );

but you will have to adjust the types to match what is setup in Free Pascal.

Now when this procedure receives the message which in this case is WM_CREATE, you actually want to send:

TObject().Dispatch(LM_CREATE);

Which will call any

    procedure DoCreate(var msg); message LM_CREATE;

that has been setup for the control and that will in turn call a OnCreate TNotifyEvents that have been established for this control.

To do this you will need to case the WindowProc callback to determine which message is sent and translate it to the appropriate LM_XXX message.

OK, now after all of that, here is the only part that you have to get cute about. You need to be able to determine WHICH LCL control needs to receive the Dispatch. In GTK you are able to pass a pointer to user specific data that can be anything you wish. It is in this data, that gets passed to the callback, were we placed the pointer to Self. This is then how we call the correct Dispatch by doing.

TObject(data).Dispatch(LM_XXX);

were data was the passed value containing "Self".

In Windows it passes back the HWND for the control. That doesn't relate to the LCL will have to figure out a way to relate the HWND value to the control created by the LCL. At this point I'm not exactly sure how to do that but it should be possible all the same. Either you need to relate HWND or you need to find a way to pass additional information, the "Self" value, back to the callback routine.

Now have I made things clearer or have I just muddied the water more?

:-)

==== 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

Jeffrey A. Wormsley
Show quoted text 8 lines
Oh, excellent news!!! I had hoped this was possible but I didn't dig around in the API enough to see if this was possible. Again great news thanks. Did you get this Jeff??

This makes my previous post moot, then, if this works as advertised. I will look into it immediately!

Let me know if you need some more explaination. :-)

I will let you know as soon as I finish this bit of research!

Jeff.

Reply by email

Shane Miller
Show quoted text 6 lines
Presumably all I need to do there is to translate the LM_xxx to the Win32 equivalent and away I go. But, what if there is no equivalent? >See this is where you keep confusing me. You should never have to >translate an LM_XXX to a Win32 equivalent. You should only every be >translating a Win32 to it's LM_XXX equivalent.

Actually you both are right. In the callback, when the FORM calls the "callback" procedure you set up, you will receive a wm_LButtonDown or something like that. You haveto do a DISPATCH(LM_LButtonDown) (or whatever it is) so you do have to convert to LM_??? then.

I'm not sure about the other way around though. You would have top convert from LM_??? to WM_??? if you were setting up individual messages to the LM_?? messages and each had a callback, but if what I hear is true and there is ONLY 1 callback for the entire control, then you will have to decipher which message the callback got and do a dispatch(LM_????)

I LOVE THERE TYPES OF CONVERSATIONS!!!!!!!

So much better than...."Hey, would it look cool if the edit boxxes had green backgrounjds?" or something lame like that...!!!

Shane

Reply by email

Marc Weustink
to Jeffrey A. Wormsley: can The point was, at the time of LM_Create, I didn't think I had a windows procedure. …

At 18:32 10-08-99 -0400, "Jeffrey A. Wormsley"

Show quoted text 21 lines
On 8/10/99, at 11:44 PM, Marc Weustink wrote: >You can pass extra info to a Windows window. This way you could store the >"self" value when you create it. When you receive a Windows message you can >retrieve the "self" value for this HWND. Look at GetProp, SetProc >(user32.lib, windows.h) etc. The point was, at the time of LM_Create, I didn't think I had a windows procedure. What Michael is suggesting is that I have one and only one, and it does the job for every component, and hence has to know (via a TList) about each and every component. This is completely different from Delphi, in that Delphi has a single window procedure for every component, and that window procedure only need to know about itself. The confusion is the definition of "Window Procedure". I am using it to mean the procedure that is associated in Windows to the HWnd handle (I will refer to this in "'s). So that if windows detects a window handle that needs a message, it calls the "window procedure" associated with that handle. In Delphi, this is a trivial process, since the "window procedure" associated to the handle is on a one on one basis, each Hwnd handle only has its own "window procedure" that messages can be passed to.

Correct.

Going the way Michael has suggested would mean that every Hwnd is associated with one single "window procedure" and that procedure would be responsible for looking up the Hwnd in a list, retrieving the Data pointer that was passed in the LM_CREATE SendMessage,

Retrieving that datapointer is the only "overhead" here, but not a big issue if you want to have a certian platform independency.

Show quoted text 7 lines
and then using the Dispatch method of the TObject pointed to by the Data pointer to send the apporopriate message to the component for processing by the attached message handler, if present. Dispatch is calling the LCL [window procedure] (brackets as opposed to "'s), or message handler if you will, that searches up the component tree trying to find a handler for the message.

Thats more or less the same delphi does, only in stead of one dispatch method, they use an overridable winproc method which finally calls the dispatch method

Show quoted text 5 lines
This is feasible, but I am not convinced it is the best way to do things. For one, it would be a real bottleneck in terms of performance. Having to look up in a list of hundreds or thousands of components would seem to be a needless slowdown, as compared to having a unique "window procedure" for each component.

I dont think getting your data by a GetProp will be a bottleneck. Delphi itself uses it to check if a window is a delphi window.

Show quoted text 12 lines
When I started this, I was hoping to do it the Delphi way, where each window handle had it's own "window procedure" as a method of the TControl object, but there is no way I can see at the Interface.pp level, that I can see, to do this. It has to be done at the TControl level, but TControl is in the LCL, and hence should ideally be API toolkit independent. The quick and dirty fix would be to make the TControl use IFDEFs to check for windows and compile in the "window procedure" code, and let that procedure take the WM_xxx messages and Dispatch the LM_xxx equivalents. It isn't clear how to go the other way, though. In other words, how does a form, on recieving a LM_RESIZE send a LM_RESIZE to all of it's children. My guess is that it can bypass the "window procedure" completely and just Dispatch the LM_RESIZE to each of the children directly.

AFAIK Delphi does not send a resize message to its children.

Marc

Reply by email

Shane Miller
Show quoted text 16 lines
When I started this, I was hoping to do it the Delphi way, where each window handle had it's own "window procedure" as a method of the TControl object, but there is no way I can see at the Interface.pp level, that I can see, to do this. It has to be done at the TControl level, but TControl is in the LCL, and hence should ideally be API toolkit independent. The quick and dirty fix would be to make the TControl use IFDEFs to check for windows and compile in the "window procedure" code, and let that procedure take the WM_xxx messages and Dispatch the LM_xxx equivalents. It isn't clear how to go the other way, though. In other words, how does a form, on recieving a LM_RESIZE send a LM_RESIZE to all of it's children. My guess is that it can bypass the "window procedure" completely and just Dispatch the LM_RESIZE to each of the children directly. >AFAIK Delphi does not send a resize message to its children. >Marc

Delphi calls a requestadjustment (or something close to that) and then resizes the children manually, not by sending a RESIZE message.

Shane

Reply by email