-----Original Message----- From: Dmitry Timoshkov [mailto:dmitry@baikal.ru] Sent: Wednesday, August 14, 2002 9:34 AM To: Medland, Bill Cc: wine-devel@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@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