56

In Win32 programming, what is the difference between a window's parent and a window's owner? I thought I had it figured out, then I came across this code:

SetWindowLong(handle, GWL_HWNDPARENT, foo);

This actually sets the window's owner, not the parent - despite the GWL_HWNDPARENT being used. Are the terms parent/owner interchangeable, or is there actually a difference?

Jon Tackabury
  • 47,710
  • 52
  • 130
  • 168

4 Answers4

30

Ownership is a relationship between two top level windows while Parent is a relationship between a top level and a WS_CHILD, or a WS_CHILD and another WS_CHILD.

The parent of a button is the form it is on, while a message box is owned by the form that showed it.

Read this article from Microsoft Win32 Window Hierarchy and Styles to get a much clearer understanding of Ownership, Parenting, ZOrder, SetWindowLong, GetWindow and all the other nasty bits of the Win32 api for creating window relationships.

EDIT: Looks like Microsoft took down that content, here is another reasonable summary of Ownership / Parenting.

Evg
  • 25,259
  • 5
  • 41
  • 83
Maurice Flanagan
  • 5,179
  • 3
  • 30
  • 37
20

Owner is the Window* responsible for a control or dialog (for example, responsible for creating/destroying the window).

Parent is the next-senior window* to a control or dialog in the window chain, but isn't actually responsible for it (doesn't necessarily care about its lifecycle, etc). A window's parent can also be its owner.

*Window vs window: Window is an actual window displayed on the screen; window is any object with a HWND (includes buttons, panels, etc).

TheSmurf
  • 15,337
  • 3
  • 40
  • 48
  • 4
    Thanks for the window vs window tip as well - sometimes these things get a bit confusing when trying to discuss with other people. – Jon Tackabury Feb 03 '09 at 16:53
  • 38
    This is not correct. A window can have a parent or an owner but not both. – Raymond Chen Oct 01 '11 at 20:01
  • 4
    Raymond, I think part of the confusion is that Spy++ and GetAncestor(GA_PARENT) will return a 'next window one level up in the HWND tree' even for top-level owned HWNDs, so colloquially speaking, they have a 'parent', even if it's not tracked that way internally. There's basically two ways of looking at the HWND tree; the naive 'single tree rooted at desktop' view that you see with Spy++ / GetAncestor / EnumChildWindows / GetWindow(GA_FIRST/NEXT), and then there 'internals-oriented' view, where every HWND has a single slot that's either parent or owner depending on WS_CHILD. – BrendanMcK Oct 01 '11 at 22:59
  • 6
    Yes. Unfortunately, people tend to be sloppy with the terminology, which only compounds the confusion. (And internally, there are actually two slots, but the API design is "clever" and exposes them as just one parameter which chooses between the two slots based on context.) – Raymond Chen Oct 01 '11 at 23:46
1

Chen's blog post is the one to read. The key point for me is that the WS_CHILD style must be used on the child window. You can attempt to create a child window and pass the parent handle in to CreateWindow( ), but if you don't have the WS_CHILD style set the two windows will have the owner relationship, not the parent/child relationship.

osullivj
  • 341
  • 1
  • 5
0

It's super easy: the code is wrong. End of story right here.

Yes, some windows may happen to react favorably to such a call - someone not knowing any better may have implemented support for it. Quoth documentation (and it's old documentation) - You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.

So, all there's to it: you came upon buggy code, change it to SetParent or refactor to do something else, and keep going?

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313