can windows be reparented?

Medland, Bill Bill.Medland at accpac.com
Wed Aug 14 12:03:14 CDT 2002


> -----Original Message-----
> From: Dmitry Timoshkov [mailto:dmitry at baikal.ru]
> Sent: Wednesday, August 14, 2002 9:34 AM
> To: Medland, Bill
> Cc: wine-devel at winehq.com
> Subject: Re: Re:can windows be reparented?
> 
> 
> keep cc'ing wine-devel please

Sorry; I just realised.  It's the way I have Outlook set up; I get confused.

> 
> "Medland, Bill" <Bill.Medland at accpac.com> wrote:
> 
> > > Could you please test patch posted by Bill Medland to 
> > > wine-patches today? It's
> > > not entirely correct though. My tests show that 
> > > SetWindowLong(GWL_HWNDPARENT)
> > > call changes simultaneously both parent and owner for top 
> > > level windows and
> > > returns old value (not sure old owner or parent it is).
> > 
> > Even if the window is not in fact a child?
> 
> Yes. According to my test program.
> 
> >  Please excuse my ignorance here;
> > I am still a little shaky on terminology.  Surely if it is 
> a top level
> > window then its parent is the desktop and always will be.
> > 
> > Or are you saying that it reparents to the desktop (and so 
> the problem is
> > down in the SetParent code)?
> 
> I don't see a reparenting to desktop in the relay trace.
> 
> > > But top level windows created by Visual Vasic are special: 
> > > they have no parent,
> > > but only owner according to Spy++. In my tests I can't 
> > > reproduce it yet.
> > 
> > So you suspect that Spy++ is not telling the truth?  (It 
> wouldn't be the
> > first time)
> 
> I incline to trust Spy++ here. It correctly shows paerent/owner for my
> test application playing with SetParent/SetWindowLong. It seems that
> Windows always sets 0 in the parent field if the parent is 
> desktop. Even
> after explicit SetParent(GetDesktopWindow()) or 
> SetWindowLong(GWL_HWNDPARENT,
> GetDesktopWindow()) GetWindowLong(GWL_HWNDPARENT)/GetWindow(GW_OWNER)
> return 0 in my tests.
> 
> > > A bit of investigation of Wine source revealed that some 
> places use
> > > GetAncestor(hwnd, GA_PARENT), while others use GetParent(hwnd).
> > 
> > And, in the case of WIN_CreateWindowEx, GetAncestor (hwnd, GA_ROOT)
> > 
> > > Since
> > > their behaviour is different in respect of top level and 
> > > child windows,
> > > some major clean up in that area in Wine is needed.
> > 
> > Careful.
> > 
> > In our particular case, according to Spy++ the owner of the 
> ThunderRT6FormDC
> > is a third-generation window. viz. the actual window 
> requested, not one of
> > its ancestors.
> > 
> > i.e. I see the call to SetWindowLong (30056 (The 
> ThunderRT6FormDC), -8,
> > 10046 (The ThunderRT6UserControlDC))
> > 
> > I guess an important point here is that in our case the 
> Visual Basic is an
> > OCX sitting inside a container and so the 
> ThunderRT6UserControlDC is not
> > first generation.
> 
> Now I don't understand your terminology. parent - child - sibling are
> the termings in the Windows world. Who of them was born 
> earlier matters
> only when Z order and visibility are taken into account (and 
> can be easily
> changed).

Sorry; I am being unclear.  I mean that (statically, according to Spy++,
when the popup form is active)

1. The ThunderRT6FormDC which "is" the form has style WS_OVERLAPPED, no
parent (i.e. the desktop) and owner is the ThunderRT6UserControlDC
2. The ThunderRT6UserControlDC which, I believe, "is" the ocx, has style
WS_OVERLAPPED and no owner, but its parent is an ATL window
3. That ATL window's parent is another ATL window
4. That second ATL window has no parent.

(So, by generations I am talking about the static parent relationship,
independent of how it came to be; c.f. old people adopting young ones
resulting in skipped generations)

> 
> -- 
> Dmitry.
> 
> 
> 

And I have just noticed the lie in MSDN.  It says (Platform SDK - Windows
User Interface - Owned windows) that once the window has been created, with
an owner, you cannot change the owner.  That has to be wrong.

A propos.

I think there is a related error in CreateWindowEx.  At least it disagrees
with MSDN.

If passed a parent
    If this is a child
        set parent to the paremt passed in and leave the owner 0
    else
        set the parent to the desktop and the owner to the GA_ROOT ancestor
of the window passed in.

Surely it should be (according to MSDN)

if passed a parent
    if style includes WS_OVERLAPPED or WS_POPUP
        assert style does not include WS_CHILD
         if the parent is itself WS_OVERLAPPED or WS_POPUP
            parent is desktop and owner is the parent passed in
        else if the parent is a WS_CHILD then
            parent is desktop and owner is the GetAncestor(parent, GA_ROOT)
        else
            assert false?
    else
        assert WS_CHILD
        owner is 0 and parent is as specified

Comments?

One datum of use.  In our particular case this fits; the ThunderRT6FormDC is
WS_OVERLAPPED with no parent.  Its owner is the ThunderRT6UserControlDC
which also is WS_OVERLAPPED but has a parent.

Bill




More information about the wine-devel mailing list