Sign in Join

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

Mailing lists / lazarus / 1999-08

More Native Win32 stuff (Pascal, can youhelphere?)

19 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: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote 10 lines
On 8/10/99, at 9:52 AM, Shane Miller wrote: >Each component would have it's own unique windows procedure because >each control create's it's own unique TControl. Currently TControl does not define a windows procedure, and adding one would mean putting Win32 directly into the LCL, not moving it out under Interfaces. Could it be that the windows procedure would be ignored under linux?

As long as the procedure itself is located in the interfaces or win32int.pp (madeup file name) then it is still separating things. We would then just have to include the same procedure in the gtkint unit but it would just be empty and not do anything.

I'm not totally sure of what I am talking about because I have never dug down into the Windows messaging stuff to see how it works. So I'm not sure how the window procedure works or what it does.

The idea of the separation of the LCL and API is so that you don't need to change your application code when using a different API. If we need to add some variables and the like to the LCL TControl class so that it can work with an API well then we do that. We just have to make sure that each API interface we write deals with the calls or variables correctly. In some cases that might mean just having empty procedures that don't do anything other then exists so that linking works.

I'm quite sure we will find more of the same problems when we try a QT version or even a Gnome version for that matter.

Do you get my drift here? For example if you look at the Hello World example. It talkes only to the LCL. It doesn't know from API and shouldn't. The user should just be able to link his code with a different xxxint.pp file and it should work with xxx API. How the LCL and the different API's handle this is up to the LCL and API developers. Namely us at this point.

Did that make any sense???

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

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote 6 lines
Thats the whole point, it can't be in the interfaces or win32int.pp file (and that is the name I am using). The reason being that you must have a unique message handler (WinProc is the usual name) for each windows control.

<snip>

The LCL TControl however, does not define or implement a message handler.

Yes it does. The message handling that is being currently done is on a control by control bases. Every TControl object has it's OWN message handling. You don't find this code in the LCL because it is handled by the RTL. That is where the base TObject is defined. Every TObject has it's own message handler. That is what Dispatch is doing. When you call Dispatch you are calling Dispatch for that object and it goes through it's table of messages to determine which one it needs to deal with.

I guess this is why I am confused by your problem. There shouldn't be any problem having Windows call the same messaging handling that we are using for GTK. It is basically setup the same way that the Delphi messages are.

What am I missing???

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

Reply by email

Shane Miller

Each component would have it's own unique windows procedure because each control create's it's own unique TControl. I will have to look at how Delphi does it to give you anything useful. Right now I'm trying to find an SNA client so I can try to get TDS running under Linux using WINE.

I'll have to get back to you.
Shane

>> "Jeffrey A. Wormsley" 08/09 9:28 PM >>>

I am still struggling to figure out how to attach a message handler to a TForm. The TControl has an FWindowProc that should probably point to the function, but how do I get a unique window proc for each component? I was thinking of defining a TWindowObject and making the WindowProc a method, then creating a new TWindowObject for each control when I recieve the LM_Create message, but I don't think I can assign a method to FWindowProc in TControl, can I? Delphi's TWinControl has the WindowProc and default message handler built into the object already, but the LCL does not. So Delphi automatically gets a seperate window procedure and message handler for each component created. If I try to do the same for lazarus, and add these to the TControl and TWinControl objects, then I have put Win32 stuff into the main LCL, which is against the idea of splitting everything out. But it appears I can't create new, unique handlers for each component without them being part of the object to begin with. Unless I am missing something totally obvious, it is a catch 22.

It is almost as if the API independence needs to be done by having a different Dispatch function for each toolkit, but this would be reinventing the wheel for everone.

I hope I am not being stupid, but it is driving me up the wall!

Jeff.

_________________________________________________________________ To unsubscribe: mail with
"unsubscribe" as the Subject
archives at http://www.miraclec.com/list_archives/lazarus

Reply by email

Curtis White
to Jeff Wormsley: This is what I was getting at. Currently TControl does not define a windows procedure,…
On 10-Aug-99 Jeff Wormsley wrote 11 lines
This is what I was getting at. Currently TControl does not define a windows procedure, and adding one would mean putting Win32 directly into the LCL, not moving it out under Interfaces. Could it be that the windows procedure would be ignored under linux? Could it be implemented by making the include directories be divided into API levels, then the make file specifies the appropriate includes for each API, so that a GTK TControl does not have a windows procedure, but a Win32 one does? It breaks putting ev erything into Interfaces, but as long as these things are private, and the public and protected interface is the same, it could work.

I am wondering if putting that procedure into TControl would really be so bad. I am guessing that it wouldn't hurt as long as it only calls the windowsint units to do anything that is specific to the API. If it does not need to do anything in the gtkint unit, then it can just be an empty function in gtkint. This would allow you to add the procedure you need to make it work in Windows without breaking the gtk code. You would just need to make sure that the function made calls to the windows API only through the windowsint units. Is that possible?

I don't completely understand the problem, so I may be way off base here.

Curtis

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Shane Miller wrote
Each component would have it's own unique windows procedure because each control create's it's own unique TControl. I will have to look at how Delphi does it to give you anything useful. Right now I'm trying to find an SNA client so I can try to get TDS running under Linux using WINE.

This is what I was getting at. Currently TControl does not define a windows procedure, and adding one would mean putting Win32 directly into the LCL, not moving it out under Interfaces. Could it be that the windows procedure would be ignored under linux? Could it be implemented by making the include directories be divided into API levels, then the make file specifies the appropriate includes for each API, so that a GTK TControl does not have a windows procedure, but a Win32 one does? It breaks putting everything into Interfaces, but as long as these things are private, and the public and protected interface is the same, it could work.

Jeff.

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Michael A. Hess wrote
As long as the procedure itself is located in the interfaces or win32int.pp (madeup file name) then it is still separating things. We would then just have to include the same procedure in the gtkint unit but it would just be empty and not do anything.

Thats the whole point, it can't be in the interfaces or win32int.pp file (and that is the name I am using). The reason being that you must have a unique message handler (WinProc is the usual name) for each windows control. Delphi does this by making it a method of the TControl object, so that every time you create a new TControl, you automatically have a new message handler that does nothing but handle messages for that control and no other, not even other instances of the same control type. It is all set up in the Create method, check the source for Controls.Pas in Delphi, look for TControl and TWinControl, check the WindowProc property, and how it is all set up in the Create methods.

The LCL TControl however, does not define or implement a message handler. To add one would put Win32 code into the LCL directly.

I'm quite sure we will find more of the same problems when we try a QT version or even a Gnome version for that matter.

This type of thing is why I went ahead and started on Win32 now, before we got way too deep to rethink philosophies. If this issue came up six months from now, it could be much worse to deal with.

Did that make any sense???

I understand about the application independence from the toolkit.

Jeff.

Reply by email

Shane Miller

I would have to agree with Michael. What messages are you trying to capture that you currently aren't capturing? If your missing some, simply add some probcedure's in TCOntrol with the message LM_MEssage
definition. Then those procedure's will call those fuinctions. If your interested in getting ALL messages to ONE procedure, then implement a call to your win32interface that assigns the windowproc to TCOntrol's windowproc.

Shane

>> "Michael A. Hess" 08/10 11:32 AM >>>
Jeff Wormsley wrote 6 lines
Thats the whole point, it can't be in the interfaces or win32int.pp file (and that is the name I am using). The reason being that you must have a unique message handler (WinProc is the usual name) for each windows control.

<snip>

The LCL TControl however, does not define or implement a message handler.

Yes it does. The message handling that is being currently done is on a control by control bases. Every TControl object has it's OWN message handling. You don't find this code in the LCL because it is handled by the RTL. That is where the base TObject is defined. Every TObject has it's own message handler. That is what Dispatch is doing. When you call Dispatch you are calling Dispatch for that object and it goes through it's table of messages to determine which one it needs to deal with.

I guess this is why I am confused by your problem. There shouldn't be any problem having Windows call the same messaging handling that we are using for GTK. It is basically setup the same way that the Delphi messages are.

What am I missing???

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

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote
I will have to look into the RTL TObject declaration. It was my understanding that this had nothing to do with native Windows messages,

It doesn't have anything to do with Windows native handling. If I understand things correctly in Windows the callbacks aka messages from Windows are sent to a Dispatch routine in Delphi. This then takes care of sending it to the correct handler that was defined by the

procedure xxxxxx; message;

etc. etc.

This is estentially what Free Pascal and the LCL does. You define

procedure xxxx; message LM_XXX;

This means that this routine is used as a message handler for the message LM_XXX.

When you call

  TObject(data).Dispatch(LM_XXX);

It will call the handler that was defined for that Object.

Now with what you are doing you will be creating the Window, Component or whatever using the Windows API with code written in the win32int.pp unit. It will know it needs to do this by the LM_Create message sent by the LCL. Now when you create the Window you will need to setup what is used as the callback/handler (whatever). At this point it will be a routine within the win32int unit. Now I assume you can pass to the windows object you are creating some data of your own choosing. This would be the Self value passed in the SendMessage. Then in the callback I again assume that this data is available. You would then use that as the TObject for calling the Dispatch with the correct and valid message.

So, if this is in the TObject, then I should be able to catch a LM_xxx message in Interfaces, translate it to a windows message, and then call TObject(Sender).Dispatch(Win32Message) ??? Is this what I missed?

Which way are you talking about the message being sent? Are you talking about the message coming from Windows back to the LCL code to a message handler or are you sending a message to Windows?

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

Reply by email

Marc Weustink
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…

At 14:58 10-08-99 -0400, "Michael A. Hess" wrote:

[snip]

Show quoted text 12 lines
Do not confuse this with any kind of messaging used in Windows or X. This is simply an internal thing between the LCL and the xxxint.pp unit in question. It is calling the InterfaceObject.IntSendMessage method. It is inside this method that you need to determine which message was sent, in this case LM_CREATE, what type of component is sending it, you check the controlstyle for this, and then from that you will call the appropriate Windows API routines to actually create the control. Then you will attach any required callbacks to this Windows control so that they also come back through the win32int unit to be sent to the correct control via the Dispatch routine.

Just hooking in this list, and before I get more confused, this Dispatch routine you mentioned here, is this to dispatch the internal (between the LCL and the xxxint.pp and vv) or is this the delphi dispatch method ?

Marc

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…

Followed you fine till here...

Show quoted text 7 lines
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.

Just one, right? Not one for each component, but only one total? It was my interpretation of reading the Delphi VCL that every single Delphi component had its own window procedure.

Show quoted text 13 lines
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.

This I don't will ask more this evening when I get home.

Show quoted text 36 lines
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?

Some things clearer, some muddier. A trade off. I am late leaving work. Will get back on the mail in about an hour.

Jeff.

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…

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

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote 9 lines
On 8/10/99, at 2:21 PM, Michael A. Hess wrote: >Which way are you talking about the message being sent? Are you >talking about the message coming from Windows back to the LCL code to >a message handler or are you sending a message to Windows? I was focusing first on the handling the LM_xxx messages generated by the LCL, not from windows itself.

That is what I was afraid you were going to say. That has been the whole confusion. We are not talking about the same thing. Shane and I are refering to the callbacks from Windows and how these messages get translated to the objects. That is what the messaging and Dispatch we are talking about is used for.

Show quoted text 5 lines
All I was looking to do first was just LM_CREATE and LM_DESTROY to create and destroy a form, and ignore everything else. But I couldn't get past LM_CREATE, because as I thought there was not enough info to create what I needed. If I am reading the rest of the message right, I just didn't get deep enough into the tree to find what I needed.

No, that isn't correct because we are talking about different things. However this still is confusing to me because I don't understand your problem. In the LCL a control sends the following to the win32int unit.

SendMessage(LM_CREATE, Self, nil);

Do not confuse this with any kind of messaging used in Windows or X. This is simply an internal thing between the LCL and the xxxint.pp unit in question. It is calling the InterfaceObject.IntSendMessage method.

It is inside this method that you need to determine which message was sent, in this case LM_CREATE, what type of component is sending it, you check the controlstyle for this, and then from that you will call the appropriate Windows API routines to actually create the control.

Then you will attach any required callbacks to this Windows control so that they also come back through the win32int unit to be sent to the correct control via the Dispatch routine.

Everything you need should already be available in the TControl that is being passed in the SendMessage as Self.

Does this make any sense now?

I will be interested to see how a message from Windows is handled, though.

Everything I talked about in the previous emails is how it is done.

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

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote
One other question, on the above issue. Do I define one callback that Windows will call for the entire application?

I think this was answered in another email but anyway.

In your case it will be easiest to create just one callback for everything.

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

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Jeff Wormsley wrote 6 lines
Let's see if I have this right, then... I know I am still in the air about callbacks... TForm in its create calls SendMessage(LM_CREATE, Self)

Correct

Show quoted text 6 lines
TInteface processes the SendMessage, cases off of the message to LM_CREATE, then what??? I though it would create a window and set a variable of type HWnd, then somhow create/initialize a window procedure for that window handle. I could create the window, but had no clue as to what to use for a window procedure. According to the posts today, it would seem that is in TObject.

Defining and setting the callback (which is the windproc) is your job. You will need to have this callback in the win32int unit and define it in the WndClass structure that you pass to the CreateWindow routine. This is then the callback that Windows will use for this control.

Somewhere there is this mysterious SetCallBack to handle.

This is where it is a little different then GTK. In GTK you can set a whole host of different callbacks routines for ONE control. The appropriate callback routine is called for the appropriate message. In the Windows case ALL of the messages are passed back to just ONE callback. The WindProc routine. This means that you will then have to case the established Windproc routine to find what message is being passed back, translate that into the appropriate LCL message (LM_XXX) and then call Dispatch for that object with that LCL message.

Show quoted text 5 lines
If I read this right, when TInterface is told to set a callback, there is a method (of TObject?) that I can use that will update a list of messages and the handler address for the message, so that the objects WindowProc can then detect that type of message and call the appropriate handler.

Somewhat correct. Read above.

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.

So, to summarize, the messages from the component are handled by TInterface casing the SendMessage, and messages from Windows are handled by callbacks, which are put in place by messages from TInterface and SendMessage. Is this correct?

Correct.

I am in the process of writing another email which gives more detail using actual Windows names and references that might help you as well.

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

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Michael A. Hess wrote
Which way are you talking about the message being sent? Are you talking about the message coming from Windows back to the LCL code to a message handler or are you sending a message to Windows?

I was focusing first on the handling the LM_xxx messages generated by the LCL, not from windows itself. All I was looking to do first was just LM_CREATE and LM_DESTROY to create and destroy a form, and ignore everything else. But I couldn't get past LM_CREATE, because as I thought there was not enough info to create what I needed. If I am reading the rest of the message right, I just didn't get deep enough into the tree to find what I needed. Since I don't have code at work, I'll look deeper into this tonight. Hopefully I have been shown the missing links, and can get on with it. I will be interested to see how a message from Windows is handled, though.

Jeff.

Reply by email

Marc Weustink
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…

At 16:44 10-08-99 -0400, "Michael A. Hess" wrote:

[snip]

Show quoted text 17 lines
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.

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.

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

For me you did

Marc

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Michael A. Hess wrote
Do not confuse this with any kind of messaging used in Windows or X. This is simply an internal thing between the LCL and the xxxint.pp unit in question. It is calling the InterfaceObject.IntSendMessage method.

<snip>

Everything I talked about in the previous emails is how it is done.

Let's see if I have this right, then... I know I am still in the air about callbacks...

TForm in its create calls SendMessage(LM_CREATE, Self)

TInteface processes the SendMessage, cases off of the message to LM_CREATE, then what??? I though it would create a window and set a variable of type HWnd, then somhow create/initialize a window procedure for that window handle. I could create the window, but had no clue as to what to use for a window procedure. According to the posts today, it would seem that is in TObject.

Somewhere there is this mysterious SetCallBack to handle. If I read this right, when TInterface is told to set a callback, there is a method (of TObject?) that I can use that will update a list of messages and the handler address for the message, so that the objects WindowProc can then detect that type of message and call the appropriate handler. 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? Or it takes more than one Windows message to signal what other toolkits do in one? Does TInterface need to maintain state information on every control it creates?

So, to summarize, the messages from the component are handled by TInterface casing the SendMessage, and messages from Windows are handled by callbacks, which are put in place by messages from TInterface and SendMessage. Is this correct?

Jeff.

Reply by email

Jeff Wormsley
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Show quoted text 7 lines
Yes it does. The message handling that is being currently done is on a control by control bases. Every TControl object has it's OWN message handling. You don't find this code in the LCL because it is handled by the RTL. That is where the base TObject is defined. Every TObject has it's own message handler. That is what Dispatch is doing. When you call Dispatch you are calling Dispatch for that object and it goes through it's table of messages to determine which one it needs to deal with.

I will have to look into the RTL TObject declaration. It was my understanding that this had nothing to do with native Windows messages, hence the definition for a WindowProc _variable_ in TControl, but no implementation for it. But, if I have to go all the way to the RTL to catch messages and translate them to Windows, where do I put this code? Does that mean I need to modify TObject?

Show quoted text 6 lines
I guess this is why I am confused by your problem. There shouldn't be any problem having Windows call the same messaging handling that we are using for GTK. It is basically setup the same way that the Delphi messages are. What am I missing???

Like I said earlier, it may be me that is missing something. All I know is that I could find no property of a TControl that I could translate a message such as LM_Create to and cause an instance of TForm to define a window handler for. I didn't see this when I looked at TControl, and only glanced down the tree at TObject (since Delphi did it at TControl/TWinControl, I didn't go much deeper in LCL). So, if this is in the TObject, then I should be able to catch a LM_xxx message in Interfaces, translate it to a windows message, and then call TObject(Sender).Dispatch(Win32Message) ??? Is this what I missed?

Jeff.

Reply by email

Michael A. Hess
to Shane Miller: Each component would have it's own unique windows procedure because each control create's…
Marc Weustink wrote 5 lines
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.

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

When you call the CreateWindow routine you will need to pass the "Self" parameter to it. This will get stored as extra information int he HWND structure itself. (I'm not exactly sure how to do this yet just from the above message that it can be done.)

Now you will also need to create the callback procedure. Now I don't know if Delphi creates a separate callback (WindProc) for every component or not. I would assume it would and it would be just a procedure that is a method of the class object in Delphi. Now we could have done something like this as well but then this would have tied the LCL to a API. We don't want to do that. So you will need to create just the one callback in the win32int.pp unit. This is the callback that every control you create will use. Now since you are attaching the "Self" information into the HWND information you are all set.

In the callback which gets passed the HWND pointer you will retrieve the LCL Self pointer. Then you just need to case the WM_MESSAGE and translate it into the LM_MESSAGE. Finally you will call the Dispatch method with the correct data.

Man I have to go get something to eat.

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

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

Reply by email