Sign in Join

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

Mailing lists / lazarus / 1999-08

Creating Components...

29 messages · 8 people ·

Reply by email Subscribe to this list Your subscription

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

Shane Miller
Show quoted text 6 lines
Looking a bit deeper, I see that the button is created in the Form's oncreate event passing Self. I would have thought that Self would refer to the Form, but instead it is referring to the button. Didn't someone else have this problem recently? Do you recall their fix? Jeff.

The button is created in the Forms OnCreate? The Button is created where ever the user puts the Button := TButton.Create(Owner). Owner is set to the Form that the TButton is owned by.

If the stdcontrols (or where ever the TButton class is defined) it should eventually call SendMessage3 sending the SELF (which in this case is the button).

The button should have it's parent assigned already in Control.Create or TWinControl.Create.
You may need to look at the difference of "owner" and "Parent". Parent is used in TControl to hold the TWinControl I believe, so I think you should use owner.

If Owner is set in TControl's create (which is called whne tbutton calls the inherited creates) then by the time the sendmessage is called, FOwner is set.

In win32int.pp (or whatever) you recieve this message (LM_CREATE) call Createcomponent. When you case the fcompstyle and determine it's a csButton, you can also check TControl(data).Owner.handle (or whatever) to get it's owners handle.

Shane

Reply by email

Marc Weustink
to Shane Miller

Watching this thread I see some possible "misunderstandings" about a control owner and a control parent.
The control owner is the delphi object owner. If the owner gets destroyed, the control gets destroyed. When you create a control, you pass the owner. At this point the control has no parent and the windows part of it is not yet created. (refering to the windowshandle causes an exeption).

The control parent is the "graphical owner" or "Windows owner". So if you move the parent, the control is moved as wel (as a part of the parent). When a parent is set, the Windows part of the control is created as soon as the handle is needed.

For instance if you execute the following in a OnCreate event an instance of the button is created, but no Graphical/Windows part.

  TButton.Create(Self);
If you pass a parent, the graphical part gets created as well.
  TButton.Create(Self).Parent := Self;

HtH
Marc

"Shane Miller" wrote 33 lines
The button is created in the Forms OnCreate? The Button is created where ever the user puts the Button := TButton.Create(Owner). Owner is set to the Form that the TButton is owned by. If the stdcontrols (or where ever the TButton class is defined) it should eventually call SendMessage3 sending the SELF (which in this case is the button). The button should have it's parent assigned already in Control.Create or TWinControl.Create. You may need to look at the difference of "owner" and "Parent". Parent is used in TControl to hold the TWinControl I believe, so I think you should use owner. If Owner is set in TControl's create (which is called whne tbutton calls the inherited creates) then by the time the sendmessage is called, FOwner is set. In win32int.pp (or whatever) you recieve this message (LM_CREATE) call Createcomponent. When you case the fcompstyle and determine it's a csButton, you can also check TControl(data).Owner.handle (or whatever) to get it's owners handle. Shane _________________________________________________________________ To unsubscribe: mail with "unsubscribe" as the Subject archives at http://www.miraclec.com/list_archives/lazarus

Reply by email

Pascal Dutilleul
Show quoted text 6 lines
I would say to just create the button in the LM_ADDCHILD message and do nothing in the LM_CREATE message. Either that or send the parent information with the LM_CREATE message and then do nothing in the LM_ADDCHILD message.

Just my $.02 :

Could you treat LM_CREATE as a constructor for the button : create the object, and setting the right properties (reading from the DFM (or replacement)-file, ), but don't create the button 'physically' (no WINAPI calls in LM_CREATE).

In LM_ADDCHILD there you could create the button-window, using the WINAPI.

Pascal

_________________________________________________________ Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

Reply by email

Jeff Wormsley
to Pascal Dutilleul
Pascal Dutilleul wrote 9 lines
Just my $.02 : Could you treat LM_CREATE as a constructor for the button : create the object, and setting the right properties (reading from the DFM (or replacement)-file, ), but don't create the button 'physically' (no WINAPI calls in LM_CREATE). In LM_ADDCHILD there you could create the button-window, using the WINAPI.

The problem is that I would rather not duplicate the entire LCL in win32, which is what I would need to do in order to do something like that. In other words, I would have the LCL TButton, and then a TWin32Button in the interface. This seems to be the way GTK operates, with all of its widgets already made and (at least in Win32) stored in the shared libraries (GTKDLL's), and GtkInt maps an LCL control to a Gtk widget. However, if it is possible to avoid, and it seems to be, then I will avoid it at all costs. My big hurdle right now is that for every 1 LM_xxxx message, there seem to be 5 or 6 WM_xxxx messages that it takes to do that task. For instance, LM_CREATE causes a window to be created, which fires about 5 windows messages, starting with WM_GETMINMAXINFO (from memory), and ending with WM_SHOWWINDOW.

Jeff.

Reply by email

Jeffrey A. Wormsley

Looking a bit deeper, I see that the button is created in the Form's oncreate event passing Self. I would have thought that Self would refer to the Form, but instead it is referring to the button. Didn't someone else have this problem recently? Do you recall their fix?

Jeff.

Reply by email

Curtis White
to Jeffrey A. Wormsley: Work is moving forward on the win32 stuff, but I have now ran into another problem that…

Michael can probably give you a better answer to this since he knows the gtkint internals really well, but here are my ideas on it anyway.

On 12-Aug-99 Jeffrey A. Wormsley wrote 10 lines
My problem is the way in which messages are sent to create the button. The first message sent is the LM_CREATE, then the LM_ADDCHILD to tell the button what it's parent is. However, win32 wants to know the window handle of the button's parent when the button is created. I don't have that information yet!!! I won't get that until the LM_ADDCHILD message is recieved. I have all of the other data needed, such as the size and the position of the button, but not the parent. The net result is that I get the main form and a very small form that contains the button, since windows creates a form to go around the button because it has no parent.

I would say to just create the button in the LM_ADDCHILD message and do nothing in the LM_CREATE message. Either that or send the parent information with the LM_CREATE message and then do nothing in the LM_ADDCHILD message. If it is possible, I think it would be better to pass the parent info along with the LM_CREATE message and create it there and leave the LM_ADDCHILD message blank. That would be a more appropriate location to create the control. I just don't know if this is possible or not.

Must I move the creation of the button to the LM_ADDCHILD handler? Will this cause problems if the button has it's parent changed?

I can't think of any reason it would cause problems if the parent changed. The control will know who its parent is. The message handler won't be tracking who the parent of each control is, will it?

How much code does it break to have the buttons parent already assigned to the Parent property before the call to SendMessage is made?

I don't think this will really hurt anything either. The control doesn't really expect its parent to be assigned until the end of the Create statement. The only place where I can think that this could break some code is if in the Create statement for a control, there is a reference to the Parent before the AddControl function. But that shouldn't be the case anywhere anyway. And if it is, we should probably fix it.

Like I said, Michael may shed a whole new light on this, but this is from my limited understanding of how the message handling currently works with the gtk units.

Curtis

Reply by email

Jeffrey A. Wormsley

I'll cycle my compiler and try before turning in...

Jeff.

*********** REPLY PARTITION ***********

Michael A. Hess wrote 21 lines
Curtis White wrote: > > Yes, this is a bug in the compiler. Peter said he has to wait for one > of the other FPC guys to get back from vacation to fix it. Actually Peter did fix this several days ago. If you have a newly cycled compiler you will find that this works. I was able to use teh Self and Sender as it was suppose to be used in my comDialogs example. If you have a new compiler this should work. -- ==== 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 Pascal Dutilleul: Just my $.02 : Could you treat LM_CREATE as a constructor for the button : create the…
Jeff Wormsley wrote 10 lines
On 8/12/99, at 10:08 AM, Michael A. Hess wrote: >Then of course add the DoYYY procedure to the controls.inc file. Just >because it isn't something that GTK sends back to the control doesn't >mean we can't add it for Windows. So it isn't considered a problem to have code in the controls.pp that will only be executed in a windows environment, as long as it doesn't require linking in any windows specific units?

Correct. As long as you can link the LCL against the GTK libraries and it doesn't require anything from Windows it is fine. The real main portability issue is at the application level.

Using hellp.pp and helloform.pp as the example they do not reference anything that has anything to do with the API. It just says create a form and create a button. How the LCL does it is it's business. I just want it to do it with either GTK or Windows or Qt or whatever. Just as in the Delphi VCL you have the source but you don't need it. You link against build DCU's and thus it will be with Lazarus. Most people will link there application against a prebuilt set of DCUs for the base LCL classes and the API unit of their choosing.

That will make things a bit easier. I was trying to avoid touching the base LCL only thing you want to avoid in the LCL are direct call to a given

API code set. No direct GTK calls, no direct Qt calls, no direct Windows calls. If you need to place something in the control class to support being able to call the Windows API from the win32int unit that is just fine.

Show quoted text 5 lines
If I can add properties, messages and events that are only used by windows there, it will make my job a lot easier. This will give me my state storage that I need. As long as all of this is kept either private, or heavily commented that it is not to be used directly by applications, then there shouldn't be any portability problems.

Correct. In most cases general application don't or won't be accessing these kind of things. Just as in Delphi you don't generally write any code that deals with how the control calls the Windows API.

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

Reply by email

Jeffrey A. Wormsley
Curtis White wrote
Michael can probably give you a better answer to this since he knows the

gtkint

internals really well, but here are my ideas on it anyway.

Thanks, all the help I can get is appreciated.

I would say to just create the button in the LM_ADDCHILD message and do

nothing

in the LM_CREATE message. Either that or send the parent information with

the

LM_CREATE message and then do nothing in the LM_ADDCHILD message. If it is possible, I think it would be better to pass the parent info along with

the

LM_CREATE message and create it there and leave the LM_ADDCHILD message

blank.

That would be a more appropriate location to create the control. I just

don't

know if this is possible or not.

I am going to will probably make a lot of changes in this area, but should be safe because I won't commit them.

I can't think of any reason it would cause problems if the parent changed.

The

control will know who its parent is. The message handler won't be tracking

who

the parent of each control is, will it?

Actually, I am not sure if it will or not. The way it is set up, it can. That is how I hoped to set the parent window for the button, by using the window handle of the buttons parent in the call to CreateWindow, but the buttons parent wasn't set yet.

Jeff.

Reply by email

Shane Miller
Show quoted text 9 lines
My problem is the way in which messages are sent to create the button. The first message sent is the LM_CREATE, then the LM_ADDCHILD to tell the button what it's parent is. However, win32 wants to know the window handle of the button's parent when the button is created. I don't have that information yet!!! I won't get that until the LM_ADDCHILD message is recieved. I have all of the other data needed, such as the size and the position of the button, but not the parent. The net result is that I get the main form and a very small form that contains the button, since windows creates a form to go around the button because it has no parent.

If you are using the SENDMESSAGE3 procedure to call LM_CREATE, then you are sending SELF. The TButton has a owner property that is a TControl and tcontrol's have handles.... See how you get the handle from that?

Wherever the SendMessage3(LM_Create,Self) is, make sure the TCOntrol was created because that's where the FOWNER is set (I think) and the owner property can be typecast to a TControl to get it's handle....

Shane

Reply by email

Curtis White
to Jeffrey A. Wormsley: Looking a bit deeper, I see that the button is created in the Form's oncreate event…

Yes, this is a bug in the compiler. Peter said he has to wait for one of the other FPC guys to get back from vacation to fix it. So now when anything refers to Self, it doesn't really refer to Self. It refers to its child instead. It is a real pain to do anything with it this way because it seems like things are broke when they are just getting the wrong pointer. So for now, until it is fixed, you have to actually specify the name of the form instead of Self or even the implied self.

Curtis

On 12-Aug-99 Jeffrey A. Wormsley wrote 7 lines
Looking a bit deeper, I see that the button is created in the Form's oncreate event passing Self. I would have thought that Self would refer to the Form, but instead it is referring to the button. Didn't someone else have this problem recently? Do you recall their fix? Jeff.

Reply by email

Michael A. Hess
to Pascal Dutilleul: Just my $.02 : Could you treat LM_CREATE as a constructor for the button : create the…
Jeff Wormsley wrote 6 lines
In other words, I would have the LCL TButton, and then a TWin32Button in the interface. This seems to be the way GTK operates, with all of its widgets already made and (at least in Win32) stored in the shared libraries (GTKDLL's), and GtkInt maps an LCL control to a Gtk widget.

That is exactly the same thing you are doing with the Windows API. The GTK library is just calls to create the widget. It passes the handle of the widget it created back to you. That is what gets stored in the fComponent variable. This is a pointer to the allocated memory that is the object information (aka widget).

In the Win32 stuff you are doing exactly the same thing by calling the CreateWindow function. It is returning the HWND handle which is the pointer to the memory area that contains the object information. This should also be stored in fComponent.

The different between GTK and Windows is that you create every control with the same CreateWindow function and just pass it a different type of item to create. In GTK a separate function exists for each individual kind of widget.

Show quoted text 5 lines
My big hurdle right now is that for every 1 LM_xxxx message, there seem to be 5 or 6 WM_xxxx messages that it takes to do that task. For instance, LM_CREATE causes a window to be created, which fires about 5 windows messages, starting with WM_GETMINMAXINFO (from memory), and ending with WM_SHOWWINDOW.

Why is that a problem? This would be a message that is begin sent to the WindowProc for the control, correct? If it is something the control needs to handle well then just pass it on with the correct LM_XXX message. If it is something that really isn't used and can be ignored well then just ignore it in the callback (WindowProc) routine. If it is something that every control would receive and it is something that might need to be handled by the LCL control well then add it to the control.

Add this new message (LM_YYYY) to the list of messages and then add this handler to the basic TControl class.

procedure DoYYY(var msg); message LM_YYY;

Then of course add the DoYYY procedure to the controls.inc file. Just because it isn't something that GTK sends back to the control doesn't mean we can't add it for Windows.

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

Reply by email

Jeff Wormsley
to Marc Weustink: Without the parent, the control doesn't know it's color, left, top, etc. yourself, why…
Marc Weustink wrote
>Let us know if you'd be interested in lending a hand. > of course

If you want to work on linux and GTK, go to the main web /lazarus and surf down to the components and find one you would like to work on. Check the recent mailing list history for some specific requests. If you would like to help on the win32 end, send me a private email at and I'll zip and send you what I have so far.

Jeff.

Reply by email

Jeff Wormsley
to Pascal Dutilleul: Just my $.02 : Could you treat LM_CREATE as a constructor for the button : create the…
Michael A. Hess wrote
Then of course add the DoYYY procedure to the controls.inc file. Just because it isn't something that GTK sends back to the control doesn't mean we can't add it for Windows.

So it isn't considered a problem to have code in the controls.pp that will only be executed in a windows environment, as long as it doesn't require linking in any windows specific units? That will make things a bit easier. I was trying to avoid touching the base LCL I can add properties, messages and events that are only used by windows there, it will make my job a lot easier. This will give me my state storage that I need. As long as all of this is kept either private, or heavily commented that it is not to be used directly by applications, then there shouldn't be any portability problems.

Jeff.

Reply by email

Jeffrey A. Wormsley
Curtis White wrote
Yes, this is a bug in the compiler. Peter said he has to wait for one of

the

other FPC guys to get back from vacation to fix it. So now when anything

refers

to Self, it doesn't really refer to Self. It refers to its child instead.

It is

a real pain to do anything with it this way because it seems like things

are

broke when they are just getting the wrong pointer. So for now, until it

is

fixed, you have to actually specify the name of the form instead of Self

or

even the implied self.

In that case I'm going to give it up for the night. I had hoped to have something to show tonight, but it seems until I find the right place to work around this, I am out of luck. I replaced the creation of the button witht the form name (HELLO) instead of Self, and I still got passed the value of the Button, not the Form. Aaarrrgggghh...

Good night.
Jeff.

Reply by email

Michael A. Hess
to Jeffrey A. Wormsley
Jeffrey A. Wormsley wrote
In that case I'm going to give it up for the night.

As I mentioned this has been fixed. If you are using a new compiler the Self value being passed to TButton is the Self of the Form. This is setting the owner up for the button to be the Form.

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

Reply by email

Shane Miller

Thanks for the info. I forgot that bit about settting the parent. Without the parent, the control doesn't know it's color, left, top, etc. I did make a quick reference to that yesterday. So, a smart person like yourself, why aren't you helping us????? :-)

Let us know if you'd be interested in lending a hand.

Shane

>> Marc Weustink 08/12 1:49 PM >>>

Watching this thread I see some possible "misunderstandings" about a control owner and a control parent.
The control owner is the delphi object owner. If the owner gets destroyed, the control gets destroyed. When you create a control, you pass the owner. At this point the control has no parent and the windows part of it is not yet created. (refering to the windowshandle causes an exeption).

The control parent is the "graphical owner" or "Windows owner". So if you move the parent, the control is moved as wel (as a part of the parent). When a parent is set, the Windows part of the control is created as soon as the handle is needed.

For instance if you execute the following in a OnCreate event an instance of the button is created, but no Graphical/Windows part.

  TButton.Create(Self);
If you pass a parent, the graphical part gets created as well.
  TButton.Create(Self).Parent := Self;

HtH
Marc

"Shane Miller" wrote 33 lines
The button is created in the Forms OnCreate? The Button is created where ever the user puts the Button := TButton.Create(Owner). Owner is set to the Form that the TButton is owned by. If the stdcontrols (or where ever the TButton class is defined) it should eventually call SendMessage3 sending the SELF (which in this case is the button). The button should have it's parent assigned already in Control.Create or TWinControl.Create. You may need to look at the difference of "owner" and "Parent". Parent is used in TControl to hold the TWinControl I believe, so I think you should use owner. If Owner is set in TControl's create (which is called whne tbutton calls the inherited creates) then by the time the sendmessage is called, FOwner is set. In win32int.pp (or whatever) you recieve this message (LM_CREATE) call Createcomponent. When you case the fcompstyle and determine it's a csButton, you can also check TControl(data).Owner.handle (or whatever) to get it's owners handle. Shane _________________________________________________________________ To unsubscribe: mail with "unsubscribe" as the Subject archives at http://www.miraclec.com/list_archives/lazarus

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

Reply by email

Jeffrey A. Wormsley
Michael A. Hess wrote
Actually Peter did fix this several days ago. If you have a newly cycled compiler you will find that this works. I was able to use teh Self and Sender as it was suppose to be used in my comDialogs example. If you have a new compiler this should work.

Ok, I CVS'd the latest compiler and tried again. Much better, as shown by...

IntSendMessage3 - Start, Received (LM_Create)
IntSendMessage3 - Value of Sender = $0043E878
IntSendMessage3 - Calling CreateComponent
CreateComponent - Start
CreateComponent - Value of Sender is $0043E878
CreateComponent - ----------------------Creating component in TWin32Object- CreateComponent - 1
CreateComponent - Creating Button
CreateComponent - Value of Button Parent is $0043E878 CreateComponent - Value of Button Owner is $0043E070 CreateComponent - Value of ParentControl is $0043E070 CreateComponent - Value of (ParentControl as TControl).FComponent is $00000E70
CreateComponent - Value of Button Parent Window is $00000E70 CreateComponent - Button Window Handle Value = $00000BB4 CreateComponent - Creating a Button - SetProp
CreateComponent - Assigning window to TControl
IntSendMessage3 - Called CreateComponent
IntSendMessage3 - Exit

The button isn't visible, and has no OnClick behavior, but at least this part is now working correctly.

Thanks, All!

Jeff.

Reply by email

Michael A. Hess
to Curtis White: Yes, this is a bug in the compiler. Peter said he has to wait for one of the other FPC…
Curtis White wrote
Yes, this is a bug in the compiler. Peter said he has to wait for one of the other FPC guys to get back from vacation to fix it.

Actually Peter did fix this several days ago. If you have a newly cycled compiler you will find that this works. I was able to use teh Self and Sender as it was suppose to be used in my comDialogs example. If you have a new compiler this should work.

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

Reply by email

Michael A. Hess
to Shane Miller: The button is created in the Forms OnCreate? The Button is created where ever the user…
Shane Miller wrote
The button is created in the Forms OnCreate? The Button is created where ever the user puts the Button := TButton.Create(Owner). Owner is set to the Form that the TButton is owned by.

If you are using helloform.pp then the button is created in the Forms.Create constructor not in the OnCreate event handler. If you notice it follows the inherited Create for the form so all of the Form information has been established and the Self that is passed to the TButton.Create(Self); is setting the buttons owner to the Form.

If the stdcontrols (or where ever the TButton class is defined) it should eventually call SendMessage3 sending the SELF (which in this case is the button).

Again if you look in buttons.inc you will see that in the TButton.Create it first calls inherited Create which establishes everything for this object including setting the owner information. After everything is created then the CreatComponent method is called. Currently the method still asks for the Owner to be passed but this has been depricated and isn't needed any more.

In win32int.pp (or whatever) you recieve this message (LM_CREATE) call Createcomponent. When you case the fcompstyle and determine it's a csButton, you can also check TControl(data).Owner.handle (or whatever) to get it's owners handle.

As Shane indicates all you need to do is use the Sender data being sent to SendMessage to drill down and find the Senders owner which in your case will be the form. From that you can get the fComponent of the owner which will be the HWND which is the Window Handle of the owner control.

Just really repeating what Shane already said. :-)

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

Reply by email

Jeffrey A. Wormsley
Shane Miller wrote
The button is created in the Forms OnCreate? The Button is created where ever the user puts the Button := TButton.Create(Owner). Owner is set to

the

Form that the TButton is owned by.

I meant to say in the Form's constructor. The actual call is

button1 := TButton.Create(Self);

I tried changing it to

button1 := TButton.Create(Hello); (Hello is tha name of the form).

With the new compiler, I changed it back.

The button should have it's parent assigned already in Control.Create or TWinControl.Create.

Parent is assigned to the button's Self.

You may need to look at the difference of "owner" and "Parent". Parent is used in TControl to hold the TWinControl I believe, so I think you should use owner.

Owner is set correctly, with the new compiler.

Things are moving along better, but I am still sleepy.

Good night.

Jeff

Reply by email

Jeffrey A. Wormsley

Hello all,
Work is moving forward on the win32 stuff, but I have now ran into another problem that maybe you guys can help with.

I am currently using the HELLO.PP example as my test base. I am creating the form and the button only, the Font and ControlCanvas are do-nothing right now.

My problem is the way in which messages are sent to create the button. The first message sent is the LM_CREATE, then the LM_ADDCHILD to tell the button what it's parent is. However, win32 wants to know the window handle of the button's parent when the button is created. I don't have that information yet!!! I won't get that until the LM_ADDCHILD message is recieved. I have all of the other data needed, such as the size and the position of the button, but not the parent. The net result is that I get the main form and a very small form that contains the button, since windows creates a form to go around the button because it has no parent.

Must I move the creation of the button to the LM_ADDCHILD handler? Will this cause problems if the button has it's parent changed?

How much code does it break to have the buttons parent already assigned to the Parent property before the call to SendMessage is made?

Jeff.

Reply by email

Jeffrey A. Wormsley
Show quoted text 6 lines
For instance if you execute the following in a OnCreate event an instance of the button is created, but no Graphical/Windows part. TButton.Create(Self); If you pass a parent, the graphical part gets created as well. TButton.Create(Self).Parent := Self;

How is this supposed to be handled? If I understand correctly, windows will automatcally destroy any window children when the parent destroy is called. If you create a window with no parent, this does not happen. How do you, after the create, tell a window that it has a parent, when it did not have one when it was created?

Jeff.

Reply by email

Marc Weustink
to Jeffrey A. Wormsley
"Jeffrey A. Wormsley" wrote 10 lines
>For instance if you execute the following in a OnCreate event an instance >of the button is created, but no Graphical/Windows part. > TButton.Create(Self); > >If you pass a parent, the graphical part gets created as well. > TButton.Create(Self).Parent := Self; How is this supposed to be handled? If I understand correctly, windows will automatcally destroy any window children when the parent destroy is called.

Thats correct. The windows part at least, the delphi object part should be don by delphi (of course ;-)

If you create a window with no parent, this does not happen.

You create the delphi object (like line 1) so then next construction is complete valid.

1: b := TButton.Create(Self);
2: p := TPanel.Create(Self);
3: b.Parent := p;
4: p.Parent := Self;

line 1 and 2 creates the objects, line 3 tells the button that its parent is the panel. The buttonchecks if his parent has a windows handle. This is not the case so nothing happens.
Line 4 tells the panel that its parent is the form. The form has a handle --> every Windows part is created.

If you lateron somewhere in your code change parent, the windows part is moved to the new parent:

5: p2 := TPanel.Create(Self);
6: p2.Parent := Self;
7: b.Parent := p2;

Now the button is part of the second panel (and all are still owned by your form)

How do you, after the create, tell a window that it has a parent, when it did not have one when it was created?

like line 3 and 4.

Marc

Reply by email

Jeff Wormsley
to Marc Weustink

On 8/13/99, at 7:16 PM, Marc Weustink wrote:

All of the deleted part is understood.

Show quoted text 5 lines
>How >do you, after the create, tell a window that it has a parent, when it did >not have one when it was created? like line 3 and 4.

No, not the object, the window, the thing pointed to by the HWnd handle. When you call CreateWindow, you pass either a parent window handle, or you pass 0 for no parent. If you create the handle with a 0, can you change the window parent later? If so, how? This has nothing to do with the TWinControl or whatever object, only the HWnd data.

Jeff.

Reply by email

Marc Weustink
to Marc Weustink: In fact you do. The desktop will function as a kind of a parent. First I think the window…
"Jeff Wormsley" wrote 15 lines
On 8/13/99, at 9:41 PM, Marc Weustink wrote: >First I think the window shouldn't be created by then. Create it when it >has a parent (it has no graphical function anyhow) >But if you have to .... >You can change the parent of any window whose hwnd you know to any other >parent by the winapi function SetParent: > >HWND SetParent( > HWND hWndChild, // handle of window whose parent is changing > HWND hWndNewParent // handle of new parent window > ); Ok, that's not a problem then. But, if I shouldn't create the window until it has a parent (except perhaps the MainForm???)

Yes it depends on the window style. If is is ws_child (a control is mostly a child) then this applies. A form is created after is is visible (!)

then how do I know when the parent is set in the Interfaces code?

You don't.

Does that mean I'll need to implement a new LM_xxx message, such as LM_SET_PARENT, and instead of creating the window on LM_CREATE,

If I recall it correctly LM_CREATE is sent to the interface to create the Windows/GTK/? object. You shouldn't get this message before a parent is set.

Looking at delphi, TWinControl

Assigning a parent to control results in the following actions

C.Parent := AParent --> C.SetParent(AParent) --> AParent.InsertControl(C) -->
(1 the parent is invisible) or (2 the parent is visible)

(1) --> AlignControl(C) --> AParent.GetClientRect --> a Handle is needed --> GetHandle --> HAndleNeeded --> CreateHandle -->

(2) --> AParent.UpdateControlState --> AParent.UpdateShowing --> CreateHandle --> CreateWnd

I think this behaviour is not different al other platforms (since is is just a grapical if to the user)

instead create it on LM_SET_PARENT? Or is that what LM_ADDCHILD is for? If that is the case, though, then either what is stored in FComponent (currently the window handle) is inappropriate, and it is the contents of FComponent that are sent to LM_ADDCHILD if I remember

correctly.

<guessing part>

FComponent was if I remember it (from this list) the HWND of that component. I guess the LM_CREATE and LM_ADDCHILD were needed by the GTK libs ? You first create a "Control" with LM_CREATE and then add it to a parent with LM_ADDCHILD ??

I think if my guessings are right, in a Delphi point of view LM_ADDCHILD and LM_CREATE are one and the same.

</guessing part>

The interaction between Owner, Parent, the contents of FComponent, and the LM_xxx message handling is so many balls to keep in the air at once that I find I drop more than I juggle!

:-))

I can imagine. This story took me more than an hour to investigate. I never bothered about when exactly a window was created upon now.

Marc

Reply by email

Marc Weustink
to Marc Weustink: Thats correct. The windows part at least, the delphi object part should be don by delphi…
you wrote 13 lines
On 8/13/99, at 7:16 PM, Marc Weustink wrote: All of the deleted part is understood. >>How >>do you, after the create, tell a window that it has a parent, when it did >>not have one when it was created? > >like line 3 and 4. No, not the object, the window, the thing pointed to by the HWnd handle. When you call CreateWindow, you pass either a parent window handle, or you pass 0 for no parent.

In fact you do. The desktop will function as a kind of a parent.

If you create the handle with a 0, can you change the window parent later?

First I think the window shouldn't be created by then. Create it when it has a parent (it has no graphical function anyhow) But if you have to ....
You can change the parent of any window whose hwnd you know to any other parent by the winapi function SetParent:

HWND SetParent(
HWND hWndChild, // handle of window whose parent is changing HWND hWndNewParent // handle of new parent window

   );
If so, how? This has nothing to do with the TWinControl or whatever object, only the HWnd data.

Marc

Reply by email

Samuel Liddicott
to Marc Weustink: Yes it depends on the window style. If is is ws_child (a control is mostly a child) then…
Show quoted text 29 lines
-----Original Message----- From: Marc Weustink Sent: 13 August 1999 10:15 PM To: Cc: Subject: Re: Owners and Parents Was: Re: [lazarus] Creating Components... At 15:47 13-08-99 -0400, "Jeff Wormsley" wrote: >On 8/13/99, at 9:41 PM, Marc Weustink wrote: > >>First I think the window shouldn't be created by then. Create it when it >>has a parent (it has no graphical function anyhow) >>But if you have to .... >>You can change the parent of any window whose hwnd you know to any other >>parent by the winapi function SetParent: >> >>HWND SetParent( >> HWND hWndChild, // handle of window whose parent is changing >> HWND hWndNewParent // handle of new parent window >> ); > >Ok, that's not a problem then. But, if I shouldn't create the window until >it has a parent (except perhaps the MainForm???) Yes it depends on the window style. If is is ws_child (a control is mostly a child) then this applies. A form is created after is is visible (!)

Yes but this is a hack in the VCL. For forms the "visible" property is treated specially when the form is being loaded from the .dfm file.

Sometimes the form will get a window handle created before all the properties have been loaded from the .dfm file, as a result of what some of the properties values are.

FComponent was if I remember it (from this list) the HWND of that component.

Surely not! What is FHandle for then?

Sam

Reply by email