Implemented GetAncestor and removed WIN_GetTopParent.
Removed a few more accesses to the WND structure.
diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec
index f94c176..96497c5 100644
--- a/dlls/user/user32.spec
+++ b/dlls/user/user32.spec
@@ -655,6 +655,7 @@
# win98/win2k
@ stdcall AllowSetForegroundWindow (long) AllowSetForegroundWindow
@ stdcall AnimateWindow(long long long) AnimateWindow
+@ stdcall GetAncestor(long long) GetAncestor
@ stdcall DrawMenuBarTemp(long long) DrawMenuBarTemp
@ stdcall EnumDisplaySettingsExA(str long ptr long) EnumDisplaySettingsExA
@ stdcall EnumDisplaySettingsExW(wstr long ptr long) EnumDisplaySettingsExW
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index b8bb817..4fb4408 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -488,22 +488,17 @@
if (zorder)
{
/* find window that this one must be after */
- WND *prev = win->parent->child;
- if (prev == win) /* top child */
+ HWND prev = GetWindow( win->hwndSelf, GW_HWNDPREV );
+ if (!prev) /* top child */
{
changes.stack_mode = Above;
mask |= CWStackMode;
}
else
{
- while (prev && prev->next != win) prev = prev->next;
- if (prev)
- {
- changes.stack_mode = Below;
- changes.sibling = get_whole_window(prev);
- mask |= CWStackMode | CWSibling;
- }
- else ERR( "previous window not found for %x, list corrupted?\n", win->hwndSelf );
+ changes.stack_mode = Below;
+ changes.sibling = X11DRV_get_whole_window(prev);
+ mask |= CWStackMode | CWSibling;
}
}
@@ -970,27 +965,6 @@
}
-/***********************************************************************
- * X11DRV_get_top_window
- *
- * Return the X window associated with the top-level parent of a window
- */
-Window X11DRV_get_top_window( HWND hwnd )
-{
- Window ret = 0;
- WND *win = WIN_FindWndPtr( hwnd );
- while (win && win->parent->hwndSelf != GetDesktopWindow())
- WIN_UpdateWndPtr( &win, win->parent );
- if (win)
- {
- struct x11drv_win_data *data = win->pDriverData;
- ret = data->whole_window;
- WIN_ReleaseWndPtr( win );
- }
- return ret;
-}
-
-
/*****************************************************************
* SetParent (X11DRV.@)
*/
@@ -1142,45 +1116,37 @@
Display *display = thread_display();
XWindowAttributes win_attr;
Window win;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- WND *w = wndPtr;
-
- if (!wndPtr) return;
/* Only mess with the X focus if there's */
/* no desktop window and if the window is not managed by the WM. */
- if (root_window != DefaultRootWindow(display)) goto done;
-
- while (w && !get_whole_window(w)) w = w->parent;
- if (!w) goto done;
- if (w->dwExStyle & WS_EX_MANAGED) goto done;
+ if (root_window != DefaultRootWindow(display)) return;
if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
{
if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
+ return;
}
- else if ((win = get_whole_window(w)))
+
+ hwnd = GetAncestor( hwnd, GA_ROOT );
+ if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED) return;
+ if (!(win = X11DRV_get_whole_window( hwnd ))) return;
+
+ /* Set X focus and install colormap */
+ wine_tsx11_lock();
+ if (XGetWindowAttributes( display, win, &win_attr ) &&
+ (win_attr.map_state == IsViewable))
{
- /* Set X focus and install colormap */
- wine_tsx11_lock();
- if (XGetWindowAttributes( display, win, &win_attr ) &&
- (win_attr.map_state == IsViewable))
- {
- /* If window is not viewable, don't change anything */
+ /* If window is not viewable, don't change anything */
- /* we must not use CurrentTime (ICCCM), so try to use last message time instead */
- /* FIXME: this is not entirely correct */
- XSetInputFocus( display, win, RevertToParent,
- /*CurrentTime*/ GetMessageTime() + X11DRV_server_startticks );
- if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
- XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
- }
- wine_tsx11_unlock();
+ /* we must not use CurrentTime (ICCCM), so try to use last message time instead */
+ /* FIXME: this is not entirely correct */
+ XSetInputFocus( display, win, RevertToParent,
+ /*CurrentTime*/ GetMessageTime() + X11DRV_server_startticks );
+ if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
+ XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
}
-
- done:
- WIN_ReleaseWndPtr( wndPtr );
+ wine_tsx11_unlock();
}
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 3470ea4..81004a2 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -557,13 +557,15 @@
*
* FIXME: hide/show owned popups when owner visibility changes.
*/
-static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, WORD flags)
+static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
{
- WND *w = WIN_LockWndPtr(pDesktop->child);
+ HWND *list = NULL;
+ HWND owner = GetWindow( hwnd, GW_OWNER );
+ LONG style = GetWindowLongW( hwnd, GWL_STYLE );
- WARN("(%04x) hInsertAfter = %04x\n", wndPtr->hwndSelf, hwndInsertAfter );
+ WARN("(%04x) hInsertAfter = %04x\n", hwnd, hwndInsertAfter );
- if( (wndPtr->dwStyle & WS_POPUP) && wndPtr->owner )
+ if ((style & WS_POPUP) && owner)
{
/* make sure this popup stays above the owner */
@@ -571,35 +573,40 @@
if( hwndInsertAfter != HWND_TOP )
{
- while( w && w != wndPtr->owner )
+ if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
{
- if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
- if( hwndLocalPrev == hwndInsertAfter ) break;
- WIN_UpdateWndPtr(&w,w->next);
+ int i;
+ for (i = 0; list[i]; i++)
+ {
+ if (list[i] == owner) break;
+ if (list[i] != hwnd) hwndLocalPrev = list[i];
+ if (hwndLocalPrev == hwndInsertAfter) break;
+ }
+ hwndInsertAfter = hwndLocalPrev;
}
- hwndInsertAfter = hwndLocalPrev;
}
}
- else if( wndPtr->dwStyle & WS_CHILD )
- goto END;
+ else if (style & WS_CHILD) return hwndInsertAfter;
- WIN_UpdateWndPtr(&w, pDesktop->child);
-
- while( w )
+ if (!list) list = WIN_BuildWinArray( GetDesktopWindow() );
+ if (list)
{
- if( w == wndPtr ) break;
-
- if( (w->dwStyle & WS_POPUP) && w->owner == wndPtr )
+ int i;
+ for (i = 0; list[i]; i++)
{
- SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
- hwndInsertAfter = w->hwndSelf;
+ if (list[i] == hwnd) break;
+ if ((GetWindowLongW( list[i], GWL_STYLE ) & WS_POPUP) &&
+ GetWindow( list[i], GW_OWNER ) == hwnd)
+ {
+ SetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
+ SWP_NOSENDCHANGING | SWP_DEFERERASE );
+ hwndInsertAfter = list[i];
+ }
}
- WIN_UpdateWndPtr(&w, w->next);
+ WIN_ReleaseWinArray( list );
}
-END:
- WIN_ReleaseWndPtr(w);
return hwndInsertAfter;
}
@@ -705,9 +712,8 @@
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
{
- if( wndPtr->parent->hwndSelf == GetDesktopWindow() )
- winpos->hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr,
- winpos->hwndInsertAfter, winpos->flags );
+ if (GetAncestor( winpos->hwnd, GA_PARENT ) == GetDesktopWindow())
+ winpos->hwndInsertAfter = SWP_DoOwnedPopups( winpos->hwnd, winpos->hwndInsertAfter );
}
/* Common operations */
@@ -729,7 +735,7 @@
RECT rect;
UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow);
- DCE_InvalidateDCE(wndPtr, &rect);
+ DCE_InvalidateDCE(wndPtr->hwndSelf, &rect);
}
oldWindowRect = wndPtr->rectWindow;
@@ -1152,7 +1158,7 @@
Window root, top;
RECT rect;
- DCE_InvalidateDCE( win, &win->rectWindow );
+ DCE_InvalidateDCE( hwnd, &win->rectWindow );
win->dwStyle &= ~WS_MINIMIZE;
win->dwStyle |= WS_VISIBLE;
WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
diff --git a/include/dce.h b/include/dce.h
index 6e28da7..637cce2 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -9,8 +9,6 @@
#include "windef.h"
-struct tagWND;
-
/* internal DCX flags */
#define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000
@@ -40,8 +38,8 @@
extern DCE* DCE_AllocDCE( HWND hWnd, DCE_TYPE type );
extern DCE* DCE_FreeDCE( DCE *dce );
-extern void DCE_FreeWindowDCE( struct tagWND* );
-extern INT DCE_ExcludeRgn( HDC, struct tagWND*, HRGN );
-extern BOOL DCE_InvalidateDCE( struct tagWND*, const RECT* );
+extern void DCE_FreeWindowDCE( HWND );
+extern INT DCE_ExcludeRgn( HDC, HWND, HRGN );
+extern BOOL DCE_InvalidateDCE( HWND, const RECT* );
#endif /* __WINE_DCE_H */
diff --git a/include/win.h b/include/win.h
index 02d3b40..9d8ef27 100644
--- a/include/win.h
+++ b/include/win.h
@@ -89,10 +89,8 @@
extern BOOL WIN_UnlinkWindow( HWND hwnd );
extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
extern HWND WIN_FindWinToRepaint( HWND hwnd );
-extern BOOL WIN_DestroyThreadWindows( HWND hwnd );
+extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void);
-extern HWND WIN_GetTopParent( HWND hwnd );
-extern WND* WIN_GetTopParentPtr( WND* pWnd );
extern BOOL WIN_IsWindowDrawable(WND*, BOOL );
extern HWND *WIN_BuildWinArray( HWND hwnd );
extern void WIN_ReleaseWinArray( HWND *wndArray );
diff --git a/include/winuser.h b/include/winuser.h
index cce1900..16beba9 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -1089,6 +1089,11 @@
#define GW_OWNER 4
#define GW_CHILD 5
+/* GetAncestor() constants */
+#define GA_PARENT 1
+#define GA_ROOT 2
+#define GA_ROOTOWNER 3
+
/* WM_GETMINMAXINFO struct */
typedef struct
{
@@ -3537,16 +3542,17 @@
HWND WINAPI FindWindowExA(HWND,HWND,LPCSTR,LPCSTR);
HWND WINAPI FindWindowExW(HWND,HWND,LPCWSTR,LPCWSTR);
#define FindWindowEx WINELIB_NAME_AW(FindWindowEx)
-BOOL WINAPI FlashWindow(HWND,BOOL);
-INT WINAPI FrameRect(HDC,const RECT*,HBRUSH);
-HWND WINAPI GetActiveWindow(void);
+BOOL WINAPI FlashWindow(HWND,BOOL);
+INT WINAPI FrameRect(HDC,const RECT*,HBRUSH);
+HWND WINAPI GetActiveWindow(void);
+HWND WINAPI GetAncestor(HWND,UINT);
DWORD WINAPI GetAppCompatFlags(HTASK);
WORD WINAPI GetAsyncKeyState(INT);
-HWND WINAPI GetCapture(void);
-UINT WINAPI GetCaretBlinkTime(void);
-BOOL WINAPI GetCaretPos(LPPOINT);
-BOOL WINAPI GetClassInfoA(HINSTANCE,LPCSTR,WNDCLASSA *);
-BOOL WINAPI GetClassInfoW(HINSTANCE,LPCWSTR,WNDCLASSW *);
+HWND WINAPI GetCapture(void);
+UINT WINAPI GetCaretBlinkTime(void);
+BOOL WINAPI GetCaretPos(LPPOINT);
+BOOL WINAPI GetClassInfoA(HINSTANCE,LPCSTR,WNDCLASSA *);
+BOOL WINAPI GetClassInfoW(HINSTANCE,LPCWSTR,WNDCLASSW *);
#define GetClassInfo WINELIB_NAME_AW(GetClassInfo)
BOOL WINAPI GetClassInfoExA(HINSTANCE,LPCSTR,WNDCLASSEXA *);
BOOL WINAPI GetClassInfoExW(HINSTANCE,LPCWSTR,WNDCLASSEXW *);
diff --git a/include/x11drv.h b/include/x11drv.h
index 9c3fca3..2fa33f7 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -395,7 +395,6 @@
extern Window X11DRV_get_client_window( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd );
-extern Window X11DRV_get_top_window( HWND hwnd );
inline static Window get_client_window( WND *wnd )
{
diff --git a/windows/dce.c b/windows/dce.c
index b7bb024..d206458 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -143,7 +143,7 @@
*
* Remove owned DCE and reset unreleased cache DCEs.
*/
-void DCE_FreeWindowDCE( WND* pWnd )
+void DCE_FreeWindowDCE( HWND hwnd )
{
DCE *pDCE;
@@ -152,14 +152,16 @@
while( pDCE )
{
- if( pDCE->hwndCurrent == pWnd->hwndSelf )
+ if( pDCE->hwndCurrent == hwnd )
{
+ WND *pWnd = WIN_FindWndPtr( hwnd );
if( pDCE == pWnd->dce ) /* owned or Class DCE*/
{
if (pWnd->clsStyle & CS_OWNDC) /* owned DCE*/
{
pDCE = DCE_FreeDCE( pDCE );
pWnd->dce = NULL;
+ WIN_ReleaseWndPtr( pWnd );
continue;
}
else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) ) /* Class DCE*/
@@ -188,6 +190,7 @@
pDCE->DCXflags |= DCX_DCEEMPTY;
pDCE->hwndCurrent = 0;
}
+ WIN_ReleaseWndPtr( pWnd );
}
pDCE = pDCE->next;
}
@@ -257,17 +260,17 @@
* an ancestor and whose client rect intersects with specified update
* rectangle. In addition, pWnd->parent DCEs may need to be updated if
* DCX_CLIPCHILDREN flag is set. */
-BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate)
+BOOL DCE_InvalidateDCE(HWND hwnd, const RECT* pRectUpdate)
{
- WND* wndScope = WIN_LockWndPtr(pWnd->parent);
+ HWND hwndScope = GetAncestor( hwnd, GA_PARENT );
BOOL bRet = FALSE;
- if( wndScope )
+ if( hwndScope )
{
DCE *dce;
TRACE("scope hwnd = %04x, (%i,%i - %i,%i)\n",
- wndScope->hwndSelf, pRectUpdate->left,pRectUpdate->top,
+ hwndScope, pRectUpdate->left,pRectUpdate->top,
pRectUpdate->right,pRectUpdate->bottom);
if(TRACE_ON(dc))
DCE_DumpCache();
@@ -276,72 +279,66 @@
for (dce = firstDCE; (dce); dce = dce->next)
{
- if( !(dce->DCXflags & DCX_DCEEMPTY) )
- {
- WND* wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
+ WND* wndCurrent;
+ HWND tmp;
+ INT xoffset = 0, yoffset = 0;
- if( wndCurrent )
- {
- WND* wnd = NULL;
- INT xoffset = 0, yoffset = 0;
+ if (dce->DCXflags & DCX_DCEEMPTY) continue;
+ if ((dce->hwndCurrent == hwndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN))
+ continue; /* child window positions don't bother us */
+ if (!(wndCurrent = WIN_FindWndPtr(dce->hwndCurrent))) continue;
- if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) )
- {
- /* child window positions don't bother us */
- WIN_ReleaseWndPtr(wndCurrent);
- continue;
+ /* check if DCE window is within the z-order scope */
+
+ for (tmp = dce->hwndCurrent; tmp; tmp = GetAncestor( tmp, GA_PARENT ))
+ {
+ if (tmp == hwndScope )
+ {
+ RECT wndRect;
+
+ wndRect = wndCurrent->rectWindow;
+
+ OffsetRect( &wndRect, xoffset - wndCurrent->rectClient.left,
+ yoffset - wndCurrent->rectClient.top);
+
+ if (hwnd == wndCurrent->hwndSelf ||
+ IntersectRect( &wndRect, &wndRect, pRectUpdate ))
+ {
+ if( !(dce->DCXflags & DCX_DCEBUSY) )
+ {
+ /* Don't bother with visible regions of unused DCEs */
+
+ TRACE("\tpurged %08x dce [%04x]\n",
+ (unsigned)dce, wndCurrent->hwndSelf);
+
+ dce->hwndCurrent = 0;
+ dce->DCXflags &= DCX_CACHE;
+ dce->DCXflags |= DCX_DCEEMPTY;
+ }
+ else
+ {
+ /* Set dirty bits in the hDC and DCE structs */
+
+ TRACE("\tfixed up %08x dce [%04x]\n",
+ (unsigned)dce, wndCurrent->hwndSelf);
+
+ dce->DCXflags |= DCX_DCEDIRTY;
+ SetHookFlags16(dce->hDC, DCHF_INVALIDATEVISRGN);
+ bRet = TRUE;
+ }
}
-
- /* check if DCE window is within the z-order scope */
-
- for( wnd = WIN_LockWndPtr(wndCurrent); wnd; WIN_UpdateWndPtr(&wnd,wnd->parent))
- {
- if( wnd == wndScope )
- {
- RECT wndRect;
-
- wndRect = wndCurrent->rectWindow;
-
- OffsetRect( &wndRect, xoffset - wndCurrent->rectClient.left,
- yoffset - wndCurrent->rectClient.top);
-
- if (pWnd == wndCurrent ||
- IntersectRect( &wndRect, &wndRect, pRectUpdate ))
- {
- if( !(dce->DCXflags & DCX_DCEBUSY) )
- {
- /* Don't bother with visible regions of unused DCEs */
-
- TRACE("\tpurged %08x dce [%04x]\n",
- (unsigned)dce, wndCurrent->hwndSelf);
-
- dce->hwndCurrent = 0;
- dce->DCXflags &= DCX_CACHE;
- dce->DCXflags |= DCX_DCEEMPTY;
- }
- else
- {
- /* Set dirty bits in the hDC and DCE structs */
-
- TRACE("\tfixed up %08x dce [%04x]\n",
- (unsigned)dce, wndCurrent->hwndSelf);
-
- dce->DCXflags |= DCX_DCEDIRTY;
- SetHookFlags16(dce->hDC, DCHF_INVALIDATEVISRGN);
- bRet = TRUE;
- }
- }
- WIN_ReleaseWndPtr(wnd);
- break;
- }
- xoffset += wnd->rectClient.left;
- yoffset += wnd->rectClient.top;
- }
- }
- WIN_ReleaseWndPtr(wndCurrent);
- }
+ break;
+ }
+ else
+ {
+ WND* wnd = WIN_FindWndPtr( tmp );
+ xoffset += wnd->rectClient.left;
+ yoffset += wnd->rectClient.top;
+ WIN_ReleaseWndPtr( wnd );
+ }
+ }
+ WIN_ReleaseWndPtr(wndCurrent);
} /* dce list */
- WIN_ReleaseWndPtr(wndScope);
}
return bRet;
}
@@ -353,24 +350,22 @@
* Translate given region from the wnd client to the DC coordinates
* and add it to the clipping region.
*/
-INT DCE_ExcludeRgn( HDC hDC, WND* wnd, HRGN hRgn )
+INT DCE_ExcludeRgn( HDC hDC, HWND hwnd, HRGN hRgn )
{
POINT pt = {0, 0};
DCE *dce = firstDCE;
while (dce && (dce->hDC != hDC)) dce = dce->next;
- if( dce )
+ if (!dce) return ERROR;
+
+ MapWindowPoints( hwnd, dce->hwndCurrent, &pt, 1);
+ if( dce->DCXflags & DCX_WINDOW )
{
- MapWindowPoints( wnd->hwndSelf, dce->hwndCurrent, &pt, 1);
- if( dce->DCXflags & DCX_WINDOW )
- {
- wnd = WIN_FindWndPtr(dce->hwndCurrent);
- pt.x += wnd->rectClient.left - wnd->rectWindow.left;
- pt.y += wnd->rectClient.top - wnd->rectWindow.top;
- WIN_ReleaseWndPtr(wnd);
- }
+ WND *wnd = WIN_FindWndPtr(dce->hwndCurrent);
+ pt.x += wnd->rectClient.left - wnd->rectWindow.left;
+ pt.y += wnd->rectClient.top - wnd->rectWindow.top;
+ WIN_ReleaseWndPtr(wnd);
}
- else return ERROR;
OffsetRgn(hRgn, pt.x, pt.y);
return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
@@ -401,6 +396,7 @@
DWORD dcxFlags = 0;
BOOL bUpdateVisRgn = TRUE;
BOOL bUpdateClipOrigin = FALSE;
+ HWND parent;
TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n",
hwnd, hrgnClip, (unsigned)flags);
@@ -431,7 +427,8 @@
if (flags & DCX_WINDOW) flags &= ~DCX_CLIPCHILDREN;
- if (!wndPtr->parent || (wndPtr->parent->hwndSelf == GetDesktopWindow()))
+ parent = GetAncestor( hwnd, GA_PARENT );
+ if (!parent || (parent == GetDesktopWindow()))
flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
/* it seems parent clip is ignored when clipping siblings or children */
@@ -439,11 +436,11 @@
if( flags & DCX_PARENTCLIP )
{
- if( (wndPtr->dwStyle & WS_VISIBLE) && (wndPtr->parent->dwStyle & WS_VISIBLE) )
+ LONG parent_style = GetWindowLongW( parent, GWL_STYLE );
+ if( (wndPtr->dwStyle & WS_VISIBLE) && (parent_style & WS_VISIBLE) )
{
flags &= ~DCX_CLIPCHILDREN;
- if( wndPtr->parent->dwStyle & WS_CLIPSIBLINGS )
- flags |= DCX_CLIPSIBLINGS;
+ if (parent_style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
}
}
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 6b60957..f15d43e 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -162,14 +162,14 @@
WND *wndPtr = WIN_FindWndPtr( hwnd );
BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
- TRACE("%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
+ TRACE("%04x %i\n", hwnd, (wParam!=0) );
if( wParam )
{
if( !bVisible )
{
wndPtr->dwStyle |= WS_VISIBLE;
- DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
+ DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
}
}
else if( bVisible )
@@ -177,8 +177,8 @@
if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
- RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam );
- DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
+ RedrawWindow( hwnd, NULL, 0, wParam );
+ DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
wndPtr->dwStyle &= ~WS_VISIBLE;
}
WIN_ReleaseWndPtr( wndPtr );
@@ -520,7 +520,7 @@
if( wParam == VK_F4 ) /* try to close the window */
{
- HWND top = WIN_GetTopParent( hwnd );
+ HWND top = GetAncestor( hwnd, GA_ROOT );
if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
@@ -537,7 +537,7 @@
/* Press and release F10 or ALT */
if (((wParam == VK_MENU) && iMenuSysKey) ||
((wParam == VK_F10) && iF10Key))
- SendMessageW( WIN_GetTopParent(hwnd), WM_SYSCOMMAND, SC_KEYMENU, 0L );
+ SendMessageW( GetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
iMenuSysKey = iF10Key = 0;
break;
diff --git a/windows/dialog.c b/windows/dialog.c
index 7b863e6..985c230 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -100,14 +100,13 @@
* Helper function for modal dialogs to enable again the
* owner of the dialog box.
*/
-void DIALOG_EnableOwner( HWND hOwner, BOOL ownerWasEnabled)
+void DIALOG_EnableOwner( HWND hOwner )
{
/* Owner must be a top-level window */
if (hOwner)
- hOwner = WIN_GetTopParent( hOwner );
+ hOwner = GetAncestor( hOwner, GA_ROOT );
if (!hOwner) return;
- if (ownerWasEnabled)
- EnableWindow( hOwner, TRUE );
+ EnableWindow( hOwner, TRUE );
}
@@ -121,7 +120,7 @@
{
/* Owner must be a top-level window */
if (hOwner)
- hOwner = WIN_GetTopParent( hOwner );
+ hOwner = GetAncestor( hOwner, GA_ROOT );
if (!hOwner) return FALSE;
if (IsWindowEnabled( hOwner ))
{
@@ -841,8 +840,7 @@
{
if (hFont) DeleteObject( hFont );
if (hMenu) DestroyMenu( hMenu );
- if (modal)
- DIALOG_EnableOwner(owner, ownerEnabled);
+ if (modal && ownerEnabled) DIALOG_EnableOwner(owner);
return 0;
}
wndPtr = WIN_FindWndPtr( hwnd );
@@ -904,8 +902,7 @@
}
WIN_ReleaseWndPtr(wndPtr);
if( IsWindow(hwnd) ) DestroyWindow( hwnd );
- if (modal)
- DIALOG_EnableOwner(owner, ownerEnabled);
+ if (modal && ownerEnabled) DIALOG_EnableOwner(owner);
return 0;
}
@@ -1044,7 +1041,7 @@
DIALOGINFO * dlgInfo;
MSG msg;
INT retval;
- HWND ownerMsg = WIN_GetTopParent( owner );
+ HWND ownerMsg = GetAncestor( owner, GA_ROOT );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
@@ -1075,7 +1072,7 @@
if (dlgInfo->flags & DF_END) break;
}
}
- DIALOG_EnableOwner( owner, (dlgInfo->flags & DF_OWNERENABLED) );
+ if (dlgInfo->flags & DF_OWNERENABLED) DIALOG_EnableOwner( owner );
retval = dlgInfo->idResult;
WIN_ReleaseWndPtr(wndPtr);
DestroyWindow( hwnd );
@@ -1242,6 +1239,7 @@
WND * wndPtr = WIN_FindWndPtr( hwnd );
BOOL wasEnabled = TRUE;
DIALOGINFO * dlgInfo;
+ HWND owner;
TRACE("%04x %d\n", hwnd, retval );
@@ -1257,14 +1255,15 @@
dlgInfo->flags |= DF_END;
wasEnabled = (dlgInfo->flags & DF_OWNERENABLED);
}
+ WIN_ReleaseWndPtr(wndPtr);
- if(wndPtr->owner)
- DIALOG_EnableOwner( wndPtr->owner->hwndSelf, wasEnabled );
-
+ if (wasEnabled && (owner = GetWindow( hwnd, GW_OWNER )))
+ DIALOG_EnableOwner( owner );
+
/* Windows sets the focus to the dialog itself in EndDialog */
if (IsChild(hwnd, GetFocus()))
- SetFocus(wndPtr->hwndSelf);
+ SetFocus( hwnd );
/* Don't have to send a ShowWindow(SW_HIDE), just do
SetWindowPos with SWP_HIDEWINDOW as done in Windows */
@@ -1272,7 +1271,6 @@
SetWindowPos(hwnd, (HWND)0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
- WIN_ReleaseWndPtr(wndPtr);
/* unblock dialog loop */
PostMessageA(hwnd, WM_NULL, 0, 0);
return TRUE;
@@ -1286,89 +1284,76 @@
{
HWND hwndControl = hwnd;
HWND hwndNext;
- WND *wndPtr;
- BOOL RetVal = FALSE;
INT dlgCode;
+ WCHAR buffer[128];
- do
+ do
+ {
+ DWORD style = GetWindowLongW( hwndControl, GWL_STYLE );
+ if ((style & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE)
{
- wndPtr = WIN_FindWndPtr( hwndControl );
- if ( (wndPtr != NULL) &&
- ((wndPtr->dwStyle & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE) )
+ dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
+ if ( (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) &&
+ GetWindowTextW( hwndControl, buffer, sizeof(buffer)/sizeof(WCHAR) ))
{
- dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
- if ( (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) &&
- (wndPtr->text!=NULL))
+ /* find the accelerator key */
+ LPWSTR p = buffer - 2;
+ char a_char = vKey;
+ WCHAR w_char = 0;
+
+ do
{
- /* find the accelerator key */
- LPWSTR p = wndPtr->text - 2;
- char a_char = vKey;
- WCHAR w_char = 0;
-
- do
- {
- p = strchrW( p + 2, '&' );
- }
- while (p != NULL && p[1] == '&');
-
- /* and check if it's the one we're looking for */
- MultiByteToWideChar(CP_ACP, 0, &a_char, 1, &w_char, 1);
- if (p != NULL && toupperW( p[1] ) == toupperW( w_char ) )
- {
- if ((dlgCode & DLGC_STATIC) ||
- (wndPtr->dwStyle & 0x0f) == BS_GROUPBOX )
- {
- /* set focus to the control */
- SendMessageA( hwndDlg, WM_NEXTDLGCTL,
- hwndControl, 1);
- /* and bump it on to next */
- SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0);
- }
- else if (dlgCode & DLGC_BUTTON)
- {
- /* send BM_CLICK message to the control */
- SendMessageA( hwndControl, BM_CLICK, 0, 0 );
- }
-
- RetVal = TRUE;
- WIN_ReleaseWndPtr(wndPtr);
- break;
- }
+ p = strchrW( p + 2, '&' );
}
- hwndNext = GetWindow( hwndControl, GW_CHILD );
- }
- else
- {
- hwndNext = 0;
- }
- WIN_ReleaseWndPtr(wndPtr);
- if (!hwndNext)
- {
- hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
- }
- while (!hwndNext && hwndControl)
- {
- hwndControl = GetParent( hwndControl );
- if (hwndControl == hwndDlg)
- {
- if(hwnd==hwndDlg){ /* prevent endless loop */
- hwndNext=hwnd;
- break;
- }
- hwndNext = GetWindow( hwndDlg, GW_CHILD );
- }
- else
- {
- hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
- }
- }
- hwndControl = hwndNext;
- }
- while (hwndControl && (hwndControl != hwnd));
+ while (p != NULL && p[1] == '&');
- return RetVal;
+ /* and check if it's the one we're looking for */
+ MultiByteToWideChar(CP_ACP, 0, &a_char, 1, &w_char, 1);
+ if (p != NULL && toupperW( p[1] ) == toupperW( w_char ) )
+ {
+ if ((dlgCode & DLGC_STATIC) || (style & 0x0f) == BS_GROUPBOX )
+ {
+ /* set focus to the control */
+ SendMessageA( hwndDlg, WM_NEXTDLGCTL, hwndControl, 1);
+ /* and bump it on to next */
+ SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0);
+ }
+ else if (dlgCode & DLGC_BUTTON)
+ {
+ /* send BM_CLICK message to the control */
+ SendMessageA( hwndControl, BM_CLICK, 0, 0 );
+ }
+ return TRUE;
+ }
+ }
+ hwndNext = GetWindow( hwndControl, GW_CHILD );
+ }
+ else hwndNext = 0;
+
+ if (!hwndNext) hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
+
+ while (!hwndNext && hwndControl)
+ {
+ hwndControl = GetParent( hwndControl );
+ if (hwndControl == hwndDlg)
+ {
+ if(hwnd==hwndDlg) /* prevent endless loop */
+ {
+ hwndNext=hwnd;
+ break;
+ }
+ hwndNext = GetWindow( hwndDlg, GW_CHILD );
+ }
+ else
+ hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
+ }
+ hwndControl = hwndNext;
+ }
+ while (hwndControl && (hwndControl != hwnd));
+
+ return FALSE;
}
-
+
/***********************************************************************
* DIALOG_FindMsgDestination
*
@@ -1596,47 +1581,25 @@
*/
INT16 WINAPI GetDlgCtrlID16( HWND16 hwnd )
{
- WND *wndPtr = WIN_FindWndPtr(hwnd);
- INT16 retvalue;
-
- if (!wndPtr) return 0;
-
- retvalue = wndPtr->wIDmenu;
- WIN_ReleaseWndPtr(wndPtr);
- return retvalue;
+ return GetDlgCtrlID( hwnd );
}
-
+
/***********************************************************************
* GetDlgCtrlID (USER32.@)
*/
INT WINAPI GetDlgCtrlID( HWND hwnd )
{
- INT retvalue;
- WND *wndPtr = WIN_FindWndPtr(hwnd);
- if (!wndPtr) return 0;
- retvalue = wndPtr->wIDmenu;
- WIN_ReleaseWndPtr(wndPtr);
- return retvalue;
+ return GetWindowLongW( hwnd, GWL_ID );
}
-
+
/***********************************************************************
* GetDlgItem (USER.91)
*/
HWND16 WINAPI GetDlgItem16( HWND16 hwndDlg, INT16 id )
{
- WND *pWnd;
-
- if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
- for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
- if (pWnd->wIDmenu == (UINT16)id)
- {
- HWND16 retvalue = pWnd->hwndSelf;
- WIN_ReleaseWndPtr(pWnd);
- return retvalue;
- }
- return 0;
+ return GetDlgItem( hwndDlg, id );
}
@@ -1645,17 +1608,16 @@
*/
HWND WINAPI GetDlgItem( HWND hwndDlg, INT id )
{
- WND *pWnd;
+ int i;
+ HWND *list = WIN_BuildWinArray( hwndDlg );
+ HWND ret = 0;
- if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
- for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
- if (pWnd->wIDmenu == (UINT16)id)
- {
- HWND retvalue = pWnd->hwndSelf;
- WIN_ReleaseWndPtr(pWnd);
- return retvalue;
- }
- return 0;
+ if (!list) return 0;
+
+ for (i = 0; list[i]; i++) if (GetWindowLongW( list[i], GWL_ID ) == id) break;
+ ret = list[i];
+ WIN_ReleaseWinArray( list );
+ return ret;
}
@@ -1989,11 +1951,7 @@
HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl,
BOOL fPrevious )
{
- WND *pWnd = NULL,
- *pWndLast = NULL,
- *pWndCtrl = NULL,
- *pWndDlg = NULL;
- HWND retvalue;
+ HWND hwnd, retvalue;
if(hwndCtrl)
{
@@ -2003,71 +1961,44 @@
hwndDlg = GetParent(hwndCtrl);
}
- if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
if (hwndCtrl)
{
- if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl )))
- {
- retvalue = 0;
- goto END;
- }
/* Make sure hwndCtrl is a top-level child */
- while (pWndCtrl->parent && (pWndCtrl->parent != pWndDlg))
- WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->parent);
- if (pWndCtrl->parent != pWndDlg)
- {
- retvalue = 0;
- goto END;
- }
+ HWND parent = GetParent( hwndCtrl );
+ while (parent && parent != hwndDlg) parent = GetParent(parent);
+ if (parent != hwndDlg) return 0;
}
else
{
/* No ctrl specified -> start from the beginning */
- if (!(pWndCtrl = WIN_LockWndPtr(pWndDlg->child)))
- {
- retvalue = 0;
- goto END;
- }
- if (fPrevious)
- while (pWndCtrl->next) WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->next);
+ if (!(hwndCtrl = GetWindow( hwndDlg, GW_CHILD ))) return 0;
+ if (fPrevious) hwndCtrl = GetWindow( hwndCtrl, GW_HWNDLAST );
}
- pWndLast = WIN_LockWndPtr(pWndCtrl);
- pWnd = WIN_LockWndPtr(pWndCtrl->next);
-
+ retvalue = hwndCtrl;
+ hwnd = GetWindow( hwndCtrl, GW_HWNDNEXT );
while (1)
{
- if (!pWnd || (pWnd->dwStyle & WS_GROUP))
+ if (!hwnd || (GetWindowLongW( hwnd, GWL_STYLE ) & WS_GROUP))
{
/* Wrap-around to the beginning of the group */
- WND *pWndTemp;
+ HWND tmp;
- WIN_UpdateWndPtr( &pWnd, pWndDlg->child );
- for ( pWndTemp = WIN_LockWndPtr( pWnd );
- pWndTemp;
- WIN_UpdateWndPtr( &pWndTemp, pWndTemp->next) )
+ hwnd = GetWindow( hwndDlg, GW_CHILD );
+ for (tmp = hwnd; tmp; tmp = GetWindow( tmp, GW_HWNDNEXT ) )
{
- if (pWndTemp->dwStyle & WS_GROUP) WIN_UpdateWndPtr( &pWnd, pWndTemp );
- if (pWndTemp == pWndCtrl) break;
+ if (GetWindowLongW( tmp, GWL_STYLE ) & WS_GROUP) hwnd = tmp;
+ if (tmp == hwndCtrl) break;
}
- WIN_ReleaseWndPtr( pWndTemp );
}
- if (pWnd == pWndCtrl) break;
- if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED))
- {
- WIN_UpdateWndPtr(&pWndLast,pWnd);
+ if (hwnd == hwndCtrl) break;
+ if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE)
+ {
+ retvalue = hwnd;
if (!fPrevious) break;
}
- WIN_UpdateWndPtr(&pWnd,pWnd->next);
+ hwnd = GetWindow( hwnd, GW_HWNDNEXT );
}
- retvalue = pWndLast->hwndSelf;
-
- WIN_ReleaseWndPtr(pWndLast);
- WIN_ReleaseWndPtr(pWnd);
-END:
- WIN_ReleaseWndPtr(pWndCtrl);
- WIN_ReleaseWndPtr(pWndDlg);
-
return retvalue;
}
diff --git a/windows/focus.c b/windows/focus.c
index 4820429..57582d5 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -59,39 +59,40 @@
HWND WINAPI SetFocus( HWND hwnd )
{
HWND hWndFocus = 0, hwndTop = hwnd;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
- BOOL16 bRet = 0;
+ BOOL bRet = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = QUEUE_Current()))
{
WARN("\tCurrent message queue not found. Exiting!\n" );
- goto CLEANUP;
+ return 0;
}
- if (wndPtr)
+ if (hwnd)
{
- /* Check if we can set the focus to this window */
+ /* Check if we can set the focus to this window */
+ WND *wndPtr;
- while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
- {
- if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) )
- goto CLEANUP;
- WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
- if (!wndPtr) goto CLEANUP;
- hwndTop = wndPtr->hwndSelf;
- }
+ for (;;)
+ {
+ HWND parent;
+ LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
+ if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
+ parent = GetAncestor( hwndTop, GA_PARENT );
+ if (!parent || parent == GetDesktopWindow()) break;
+ hwndTop = parent;
+ }
- /* definitely at the top window now */
- if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) ) goto CLEANUP;
+ if (!(wndPtr = WIN_FindWndPtr( hwndTop ))) return 0;
/* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
+ WIN_ReleaseWndPtr( wndPtr );
if ( !pMsgQ )
{
WARN("\tMessage queue not found. Exiting!\n" );
- goto CLEANUP;
+ return 0;
}
/* Make sure that message queue for the window we are setting focus to
@@ -133,7 +134,7 @@
else /* NULL hwnd passed in */
{
if( HOOK_CallHooksA( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hWndFocus ) )
- goto CLEANUP;
+ return 0;
/* Get the current focus from the perQ data of the current message Q */
hWndFocus = PERQDATA_GetFocusWnd( pCurMsgQ->pQData );
@@ -150,7 +151,6 @@
if ( pMsgQ )
QUEUE_Unlock( pMsgQ );
- WIN_ReleaseWndPtr(wndPtr);
return bRet ? hWndFocus : 0;
}
diff --git a/windows/mdi.c b/windows/mdi.c
index feb2430..aea293a 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -193,25 +193,24 @@
/**********************************************************************
* MDI_MenuModifyItem
*/
-static BOOL MDI_MenuModifyItem( HWND client, HWND hWndChild )
+static void MDI_MenuModifyItem( HWND client, HWND hWndChild )
{
- static const WCHAR format[] = {'%','d',' ',0};
-
MDICLIENTINFO *clientInfo = get_client_info( client );
WCHAR buffer[128];
UINT n, id;
- BOOL bRet;
- if (!clientInfo || !clientInfo->hWindowMenu) return FALSE;
+ if (!clientInfo || !clientInfo->hWindowMenu) return;
id = GetWindowLongA( hWndChild, GWL_ID );
- n = wsprintfW(buffer, format, id - clientInfo->idFirstChild + 1);
- GetWindowTextW( hWndChild, buffer + n, sizeof(buffer)/sizeof(WCHAR) - n );
+ if (id >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT) return;
+ buffer[0] = '&';
+ buffer[1] = '1' + id - clientInfo->idFirstChild;
+ buffer[2] = ' ';
+ GetWindowTextW( hWndChild, buffer + 3, sizeof(buffer)/sizeof(WCHAR) - 3 );
- n = GetMenuState(clientInfo->hWindowMenu, id, MF_BYCOMMAND);
- bRet = ModifyMenuW(clientInfo->hWindowMenu, id, MF_BYCOMMAND | MF_STRING, id, buffer );
+ n = GetMenuState(clientInfo->hWindowMenu, id, MF_BYCOMMAND);
+ ModifyMenuW(clientInfo->hWindowMenu, id, MF_BYCOMMAND | MF_STRING, id, buffer );
CheckMenuItem(clientInfo->hWindowMenu, id, n & MF_CHECKED);
- return bRet;
}
/**********************************************************************
@@ -276,28 +275,37 @@
static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
DWORD dwStyleMask )
{
- WND *wndPtr, *pWnd, *pWndLast = NULL;
-
+ int i;
+ HWND *list;
+ HWND last = 0;
+
dwStyleMask |= WS_DISABLED | WS_VISIBLE;
if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
- if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0;
+ if (!(list = WIN_BuildWinArray( GetParent(hWnd) ))) return 0;
+ i = 0;
+ /* start from next after hWnd */
+ while (list[i] && list[i] != hWnd) i++;
+ if (list[i]) i++;
- for ( pWnd = WIN_LockWndPtr(wndPtr->next); ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+ for ( ; list[i]; i++)
{
- if (!pWnd ) WIN_UpdateWndPtr(&pWnd,wndPtr->parent->child);
-
- if ( pWnd == wndPtr ) break; /* went full circle */
-
- if (!pWnd->owner && (pWnd->dwStyle & dwStyleMask) == WS_VISIBLE )
- {
- pWndLast = pWnd;
- if ( bNext ) break;
- }
+ if (GetWindow( list[i], GW_OWNER )) continue;
+ if ((GetWindowLongW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
+ last = list[i];
+ if (bNext) goto found;
}
- WIN_ReleaseWndPtr(wndPtr);
- WIN_ReleaseWndPtr(pWnd);
- return pWndLast ? pWndLast->hwndSelf : 0;
+ /* now restart from the beginning */
+ for (i = 0; list[i] && list[i] != hWnd; i++)
+ {
+ if (GetWindow( list[i], GW_OWNER )) continue;
+ if ((GetWindowLongW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
+ last = list[i];
+ if (bNext) goto found;
+ }
+ found:
+ WIN_ReleaseWinArray( list );
+ return last;
}
/**********************************************************************
@@ -775,7 +783,9 @@
/* The window to be activated must be displayed in the "Windows" menu */
if (id >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT)
{
- MDI_SwapMenuItems( GetParent(child), id, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
+ MDI_SwapMenuItems( GetParent(child),
+ id, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
+ id = clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1;
MDI_MenuModifyItem( GetParent(child), child );
}
@@ -1129,7 +1139,7 @@
WCHAR lpBuffer[MDI_MAXTITLELENGTH+1];
MDICLIENTINFO *ci = get_client_info( hClient );
- TRACE("repaint %i, frameText %s\n", repaint, (lpTitle)?debugstr_w(lpTitle):"NULL");
+ TRACE("repaint %i, frameText %s\n", repaint, debugstr_w(lpTitle));
if (!ci) return;
@@ -1149,42 +1159,30 @@
if (ci->frameTitle)
{
- WND* childWnd = WIN_FindWndPtr( ci->hwndChildMaximized );
-
- if( childWnd && childWnd->text )
+ if (ci->hwndChildMaximized)
{
/* combine frame title and child title if possible */
static const WCHAR lpBracket[] = {' ','-',' ','[',0};
static const WCHAR lpBracket2[] = {']',0};
int i_frame_text_length = strlenW(ci->frameTitle);
- int i_child_text_length = strlenW(childWnd->text);
lstrcpynW( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
{
strcatW( lpBuffer, lpBracket );
-
- if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
- {
- strcatW( lpBuffer, childWnd->text );
- strcatW( lpBuffer, lpBracket2 );
- }
- else
- {
- lstrcpynW( lpBuffer + i_frame_text_length + 4,
- childWnd->text, MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
- strcatW( lpBuffer, lpBracket2 );
- }
- }
+ if (GetWindowTextW( ci->hwndChildMaximized, lpBuffer + i_frame_text_length + 4,
+ MDI_MAXTITLELENGTH - i_frame_text_length - 5 ))
+ strcatW( lpBuffer, lpBracket2 );
+ else
+ lpBuffer[i_frame_text_length] = 0; /* remove bracket */
+ }
}
else
{
lstrcpynW(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH+1 );
}
- WIN_ReleaseWndPtr(childWnd);
-
}
else
lpBuffer[0] = '\0';
@@ -1514,7 +1512,7 @@
HWND childHwnd;
if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
/* User chose "More Windows..." */
- childHwnd = MDI_MoreWindowsDialog(hwnd);
+ childHwnd = MDI_MoreWindowsDialog(hwndMDIClient);
else
/* User chose one of the windows listed in the "Windows" menu */
childHwnd = MDI_GetChildByID(hwndMDIClient,id);
@@ -1945,24 +1943,32 @@
SCROLLINFO info;
RECT childRect, clientRect;
INT vmin, vmax, hmin, hmax, vpos, hpos;
- WND *pWnd;
+ HWND *list;
- if (!(pWnd = WIN_FindWndPtr( hwnd ))) return;
GetClientRect( hwnd, &clientRect );
SetRectEmpty( &childRect );
- for ( WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+ if ((list = WIN_BuildWinArray( hwnd )))
{
- if( pWnd->dwStyle & WS_MAXIMIZE )
- {
- WIN_ReleaseWndPtr(pWnd);
- ShowScrollBar(hwnd, SB_BOTH, FALSE);
- return;
- }
- if( pWnd->dwStyle & WS_VISIBLE )
- UnionRect( &childRect, &pWnd->rectWindow, &childRect );
- }
- WIN_ReleaseWndPtr(pWnd);
+ int i;
+ for (i = 0; list[i]; i++)
+ {
+ DWORD style = GetWindowLongW( list[i], GWL_STYLE );
+ if (style & WS_MAXIMIZE)
+ {
+ WIN_ReleaseWinArray( list );
+ ShowScrollBar( hwnd, SB_BOTH, FALSE );
+ return;
+ }
+ if (style & WS_VISIBLE)
+ {
+ WND *pWnd = WIN_FindWndPtr( list[i] );
+ UnionRect( &childRect, &pWnd->rectWindow, &childRect );
+ WIN_ReleaseWndPtr( pWnd );
+ }
+ }
+ WIN_ReleaseWinArray( list );
+ }
UnionRect( &childRect, &clientRect, &childRect );
hmin = childRect.left;
@@ -2132,28 +2138,38 @@
{
case WM_INITDIALOG:
{
- WND *pWnd;
UINT widest = 0;
UINT length;
UINT i;
- WND *pParentWnd = (WND *)WIN_FindWndPtr(lParam);
- MDICLIENTINFO *ci = (MDICLIENTINFO*)pParentWnd->wExtra;
+ MDICLIENTINFO *ci = get_client_info( (HWND)lParam );
HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
+ HWND *list, *sorted_list;
+
+ if (!(list = WIN_BuildWinArray( (HWND)lParam ))) return TRUE;
+ if (!(sorted_list = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(HWND) * ci->nActiveChildren )))
+ {
+ WIN_ReleaseWinArray( list );
+ return FALSE;
+ }
/* Fill the list, sorted by id... */
+ for (i = 0; list[i]; i++)
+ {
+ UINT id = GetWindowLongW( list[i], GWL_ID ) - ci->idFirstChild;
+ if (id < ci->nActiveChildren) sorted_list[id] = list[i];
+ }
+ WIN_ReleaseWinArray( list );
+
for (i = 0; i < ci->nActiveChildren; i++)
{
+ WCHAR buffer[128];
- /* Find the window with the current ID */
- for (pWnd = WIN_LockWndPtr(pParentWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd, pWnd->next))
- if (pWnd->wIDmenu == ci->idFirstChild + i)
- break;
-
- SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM) pWnd->text);
- SendMessageW(hListBox, LB_SETITEMDATA, i, (LPARAM) pWnd);
- length = strlenW(pWnd->text);
- WIN_ReleaseWndPtr(pWnd);
-
+ if (!GetWindowTextW( sorted_list[i], buffer, sizeof(buffer)/sizeof(WCHAR) ))
+ continue;
+ SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM)buffer );
+ SendMessageW(hListBox, LB_SETITEMDATA, i, (LPARAM)sorted_list[i] );
+ length = strlenW(buffer); /* FIXME: should use GetTextExtentPoint */
if (length > widest)
widest = length;
}
@@ -2168,6 +2184,9 @@
case WM_COMMAND:
switch (LOWORD(wParam))
{
+ default:
+ if (HIWORD(wParam) != LBN_DBLCLK) break;
+ /* fall through */
case IDOK:
{
/* windows are sorted by menu ID, so we must return the
@@ -2175,32 +2194,14 @@
*/
HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
UINT index = SendMessageW(hListBox, LB_GETCURSEL, 0, 0);
- WND *pWnd = (WND *)SendMessageW(hListBox, LB_GETITEMDATA, index, 0);
+ HWND hwnd = SendMessageW(hListBox, LB_GETITEMDATA, index, 0);
- EndDialog(hDlg, pWnd->hwndSelf);
+ EndDialog(hDlg, hwnd);
return TRUE;
}
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE;
-
- default:
- switch (HIWORD(wParam))
- {
- case LBN_DBLCLK:
- {
- /* windows are sorted by menu ID, so we must return the
- * window associated to the given id
- */
- HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
- UINT index = SendMessageW(hListBox, LB_GETCURSEL, 0, 0);
- WND *pWnd = (WND *)SendMessageW(hListBox, LB_GETITEMDATA, index, 0);
-
- EndDialog(hDlg, pWnd->hwndSelf);
- return TRUE;
- }
- }
- break;
}
break;
}
@@ -2256,17 +2257,16 @@
static void MDI_SwapMenuItems(HWND parent, UINT pos1, UINT pos2)
{
- WND *pWnd;
+ HWND *list;
+ int i;
- pWnd = WIN_FindWndPtr( GetWindow( parent, GW_CHILD ) );
- while (pWnd)
+ if (!(list = WIN_BuildWinArray( parent ))) return;
+ for (i = 0; list[i]; i++)
{
- if (pWnd->wIDmenu == pos1)
- pWnd->wIDmenu = pos2;
- else
- if (pWnd->wIDmenu == pos2)
- pWnd->wIDmenu = pos1;
- WIN_UpdateWndPtr(&pWnd,pWnd->next);
+ UINT id = GetWindowLongW( list[i], GWL_ID );
+ if (id == pos1) SetWindowLongW( list[i], GWL_ID, pos2 );
+ else if (id == pos2) SetWindowLongW( list[i], GWL_ID, pos1 );
}
+ WIN_ReleaseWinArray( list );
}
diff --git a/windows/message.c b/windows/message.c
index 99a276c..2134854 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -433,7 +433,7 @@
(raw_message == WM_RBUTTONDOWN) ||
(raw_message == WM_MBUTTONDOWN))
{
- HWND hwndTop = WIN_GetTopParent( msg->hwnd );
+ HWND hwndTop = GetAncestor( msg->hwnd, GA_ROOT );
/* Send the WM_PARENTNOTIFY,
* note that even for double/nonclient clicks
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 65a3f2e..172e122 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -1787,7 +1787,7 @@
NC_GetInsideRect( hwnd, rect );
OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
if (wndPtr->dwStyle & WS_CHILD)
- ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
+ ClientToScreen( GetParent(hwnd), (POINT *)rect );
if (TWEAK_WineLook == WIN31_LOOK) {
rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
@@ -2065,7 +2065,7 @@
{
case HTCAPTION:
{
- HWND top = WIN_GetTopParent(hwnd);
+ HWND top = GetAncestor( hwnd, GA_ROOT );
if( WINPOS_SetActiveWindow(top, TRUE, TRUE) || (GetActiveWindow() == top) )
SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
@@ -2187,8 +2187,11 @@
TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y );
- if (wndPtr->parent && (uCommand != SC_KEYMENU))
- ScreenToClient( wndPtr->parent->hwndSelf, &pt );
+ if (uCommand != SC_KEYMENU)
+ {
+ HWND parent = GetAncestor( hwnd, GA_PARENT );
+ if (parent != GetDesktopWindow()) ScreenToClient( parent, &pt );
+ }
switch (uCommand)
{
diff --git a/windows/painting.c b/windows/painting.c
index 6f73fe1..7536d64 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -96,12 +96,8 @@
* RDW_Paint() method.
*
*/
-static BOOL WIN_HaveToDelayNCPAINT(
- WND* wndPtr,
- UINT uncFlags)
+static BOOL WIN_HaveToDelayNCPAINT( HWND hwnd, UINT uncFlags)
{
- WND* parentWnd = NULL;
-
/*
* Test the shortcut first. (duh)
*/
@@ -122,22 +118,16 @@
* that doesn't have the WS_CLIPCHILDREN style and that
* has an invalid region.
*/
- parentWnd = WIN_LockWndPtr(wndPtr->parent);
-
- while (parentWnd!=NULL)
+ while ((hwnd = GetAncestor( hwnd, GA_PARENT )))
{
- if ( ((parentWnd->dwStyle & WS_CLIPCHILDREN) == 0) &&
- (parentWnd->hrgnUpdate != 0) )
- {
- WIN_ReleaseWndPtr(parentWnd);
- return TRUE;
- }
-
- WIN_UpdateWndPtr(&parentWnd, parentWnd->parent);
+ WND* parentWnd = WIN_FindWndPtr( hwnd );
+ if (!(parentWnd->dwStyle & WS_CLIPCHILDREN) && parentWnd->hrgnUpdate)
+ {
+ WIN_ReleaseWndPtr( parentWnd );
+ return TRUE;
+ }
+ WIN_ReleaseWndPtr( parentWnd );
}
-
- WIN_ReleaseWndPtr(parentWnd);
-
return FALSE;
}
@@ -188,7 +178,7 @@
* If the window's non-client area needs to be painted,
*/
if ( ( wnd->flags & WIN_NEEDS_NCPAINT ) &&
- !WIN_HaveToDelayNCPAINT(wnd, uncFlags) )
+ !WIN_HaveToDelayNCPAINT(wnd->hwndSelf, uncFlags) )
{
RECT r2, r3;
@@ -495,7 +485,7 @@
*/
static void RDW_ValidateParent(WND *wndChild)
{
- WND *wndParent = WIN_LockWndPtr(wndChild->parent);
+ HWND parent;
HRGN hrg;
if (wndChild->hrgnUpdate == 1 ) {
@@ -508,7 +498,10 @@
} else
hrg = wndChild->hrgnUpdate;
- while ((wndParent) && (wndParent->hwndSelf != GetDesktopWindow()) ) {
+ parent = GetAncestor( wndChild->hwndSelf, GA_PARENT );
+ while (parent && parent != GetDesktopWindow())
+ {
+ WND *wndParent = WIN_FindWndPtr( parent );
if (!(wndParent->dwStyle & WS_CLIPCHILDREN))
{
if (wndParent->hrgnUpdate != 0)
@@ -536,10 +529,10 @@
OffsetRgn( hrg, -ptOffset.x, -ptOffset.y );
}
}
- WIN_UpdateWndPtr(&wndParent, wndParent->parent);
+ WIN_ReleaseWndPtr( wndParent );
+ parent = GetAncestor( parent, GA_PARENT );
}
if (hrg != wndChild->hrgnUpdate) DeleteObject( hrg );
- WIN_ReleaseWndPtr(wndParent);
}
/***********************************************************************
@@ -559,8 +552,8 @@
*/
BOOL bHadOne = wndPtr->hrgnUpdate && hRgn;
- BOOL bChildren = ( wndPtr->child && !(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE)
- && ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) );
+ BOOL bChildren = (!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
+ ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) );
RECT r;
r.left = 0;
@@ -657,43 +650,48 @@
if( flags & (RDW_INVALIDATE | RDW_VALIDATE) )
{
- if( hRgn > 1 && bChildren )
+ HWND *list;
+ if( hRgn > 1 && bChildren && (list = WIN_BuildWinArray( wndPtr->hwndSelf )))
{
- WND* wnd = wndPtr->child;
POINT ptTotal, prevOrigin = {0,0};
POINT ptClient;
+ INT i;
ptClient.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
ptClient.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
- for( ptTotal.x = ptTotal.y = 0; wnd; wnd = wnd->next )
+ for(i = ptTotal.x = ptTotal.y = 0; list[i]; i++)
{
+ WND *wnd = WIN_FindWndPtr( list[i] );
+ if (!wnd) continue;
if( wnd->dwStyle & WS_VISIBLE )
{
- POINT ptOffset;
+ POINT ptOffset;
r.left = wnd->rectWindow.left + ptClient.x;
r.right = wnd->rectWindow.right + ptClient.x;
r.top = wnd->rectWindow.top + ptClient.y;
r.bottom = wnd->rectWindow.bottom + ptClient.y;
- ptOffset.x = r.left - prevOrigin.x;
- ptOffset.y = r.top - prevOrigin.y;
+ ptOffset.x = r.left - prevOrigin.x;
+ ptOffset.y = r.top - prevOrigin.y;
OffsetRect( &r, -ptTotal.x, -ptTotal.y );
if( RectInRegion( hRgn, &r ) )
{
OffsetRgn( hRgn, -ptOffset.x, -ptOffset.y );
RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
- prevOrigin.x = r.left + ptTotal.x;
- prevOrigin.y = r.top + ptTotal.y;
+ prevOrigin.x = r.left + ptTotal.x;
+ prevOrigin.y = r.top + ptTotal.y;
ptTotal.x += ptOffset.x;
ptTotal.y += ptOffset.y;
}
}
+ WIN_ReleaseWndPtr( wnd );
}
+ WIN_ReleaseWinArray( list );
OffsetRgn( hRgn, ptTotal.x, ptTotal.y );
- bChildren = 0;
+ bChildren = 0;
}
}
@@ -701,10 +699,20 @@
if( bChildren )
{
- WND* wnd;
- for( wnd = wndPtr->child; wnd; wnd = wnd->next )
- if( wnd->dwStyle & WS_VISIBLE )
- RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
+ HWND *list;
+ if ((list = WIN_BuildWinArray( wndPtr->hwndSelf )))
+ {
+ INT i;
+ for (i = 0; list[i]; i++)
+ {
+ WND *wnd = WIN_FindWndPtr( list[i] );
+ if (!wnd) continue;
+ if( wnd->dwStyle & WS_VISIBLE )
+ RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
+ WIN_ReleaseWndPtr( wnd );
+ }
+ WIN_ReleaseWinArray( list );
+ }
}
end:
@@ -762,7 +770,7 @@
* Check if this window should delay it's processing of WM_NCPAINT.
* See WIN_HaveToDelayNCPAINT for a description of the mechanism
*/
- if ((ex & RDW_EX_DELAY_NCPAINT) || WIN_HaveToDelayNCPAINT(wndPtr, 0) )
+ if ((ex & RDW_EX_DELAY_NCPAINT) || WIN_HaveToDelayNCPAINT(wndPtr->hwndSelf, 0) )
ex |= RDW_EX_DELAY_NCPAINT;
if (flags & RDW_UPDATENOW)
@@ -807,8 +815,8 @@
/* ... and its child windows */
- if( wndPtr->child && !(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE)
- && ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) )
+ if(!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
+ ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) )
{
HWND *list, *phwnd;
@@ -1209,7 +1217,7 @@
/* do ugly coordinate translations in dce.c */
- ret = DCE_ExcludeRgn( hdc, wndPtr, hrgn );
+ ret = DCE_ExcludeRgn( hdc, hwnd, hrgn );
DeleteObject( hrgn );
WIN_ReleaseWndPtr(wndPtr);
return ret;
diff --git a/windows/win.c b/windows/win.c
index e070ab8..544dddc 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -406,7 +406,7 @@
wndPtr->hSysMenu = 0;
}
USER_Driver.pDestroyWindow( wndPtr->hwndSelf );
- DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
+ DCE_FreeWindowDCE( wndPtr->hwndSelf ); /* Always do this to catch orphaned DCs */
WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
CLASS_RemoveWindow( wndPtr->class );
wndPtr->class = NULL;
@@ -423,34 +423,21 @@
* Destroy all children of 'wnd' owned by the current thread.
* Return TRUE if something was done.
*/
-BOOL WIN_DestroyThreadWindows( HWND hwnd )
+void WIN_DestroyThreadWindows( HWND hwnd )
{
- BOOL ret = FALSE;
- WND *wnd = WIN_FindWndPtr( hwnd );
+ HWND *list;
+ int i;
- if (!wnd) return FALSE;
- while (wnd->child)
+ if (!(list = WIN_BuildWinArray( hwnd ))) return;
+ for (i = 0; list[i]; i++)
{
- WND *tmp = WIN_LockWndPtr(wnd->child);
- ret = FALSE;
- while (tmp)
- {
- if (GetWindowThreadProcessId( tmp->hwndSelf, NULL ) == GetCurrentThreadId())
- {
- DestroyWindow( tmp->hwndSelf );
- ret = TRUE;
- break;
- }
- if (tmp->child && WIN_DestroyThreadWindows( tmp->hwndSelf ))
- ret = TRUE;
- else
- WIN_UpdateWndPtr(&tmp,tmp->next);
- }
- WIN_ReleaseWndPtr(tmp);
- if (!ret) break;
+ if (!IsWindow( list[i] )) continue;
+ if (GetWindowThreadProcessId( list[i], NULL ) == GetCurrentThreadId())
+ DestroyWindow( list[i] );
+ else
+ WIN_DestroyThreadWindows( list[i] );
}
- WIN_ReleaseWndPtr( wnd );
- return ret;
+ WIN_ReleaseWinArray( list );
}
/***********************************************************************
@@ -698,10 +685,8 @@
wndPtr->owner = NULL;
else
{
- WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
- wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
+ wndPtr->owner = WIN_FindWndPtr( GetAncestor( cs->hwndParent, GA_ROOT ));
WIN_ReleaseWndPtr(wndPtr->owner);
- WIN_ReleaseWndPtr(tmpWnd);
}
}
@@ -1053,92 +1038,40 @@
return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_PROC_32W );
}
+
/***********************************************************************
* WIN_SendDestroyMsg
*/
-static void WIN_SendDestroyMsg( WND* pWnd )
+static void WIN_SendDestroyMsg( HWND hwnd )
{
- if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
+ if( CARET_GetHwnd() == hwnd) DestroyCaret();
if (USER_Driver.pResetSelectionOwner)
- USER_Driver.pResetSelectionOwner( pWnd->hwndSelf, TRUE );
+ USER_Driver.pResetSelectionOwner( hwnd, TRUE );
/*
* Send the WM_DESTROY to the window.
*/
- SendMessageA( pWnd->hwndSelf, WM_DESTROY, 0, 0);
+ SendMessageA( hwnd, WM_DESTROY, 0, 0);
/*
* This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
* make sure that the window still exists when we come back.
*/
- if (IsWindow(pWnd->hwndSelf))
+ if (IsWindow(hwnd))
{
- HWND* pWndArray = NULL;
- WND* pChild = NULL;
- int nKidCount = 0;
+ HWND* pWndArray;
+ int i;
- /*
- * Now, if the window has kids, we have to send WM_DESTROY messages
- * recursively to it's kids. It seems that those calls can also
- * trigger re-entrant calls to DestroyWindow for the kids so we must
- * protect against corruption of the list of siblings. We first build
- * a list of HWNDs representing all the kids.
- */
- pChild = WIN_LockWndPtr(pWnd->child);
- while( pChild )
- {
- nKidCount++;
- WIN_UpdateWndPtr(&pChild,pChild->next);
- }
+ if (!(pWndArray = WIN_BuildWinArray( hwnd ))) return;
- /*
- * If there are no kids, we're done.
- */
- if (nKidCount==0)
- return;
+ /* start from the end (FIXME: is this needed?) */
+ for (i = 0; pWndArray[i]; i++) ;
- pWndArray = HeapAlloc(GetProcessHeap(), 0, nKidCount*sizeof(HWND));
-
- /*
- * Sanity check
- */
- if (pWndArray==NULL)
- return;
-
- /*
- * Now, enumerate all the kids in a list, since we wait to make the SendMessage
- * call, our linked list of siblings should be safe.
- */
- nKidCount = 0;
- pChild = WIN_LockWndPtr(pWnd->child);
- while( pChild )
- {
- pWndArray[nKidCount] = pChild->hwndSelf;
- nKidCount++;
- WIN_UpdateWndPtr(&pChild,pChild->next);
- }
-
- /*
- * Now that we have a list, go through that list again and send the destroy
- * message to those windows. We are using the HWND to retrieve the
- * WND pointer so we are effectively checking that all the kid windows are
- * still valid before sending the message.
- */
- while (nKidCount>0)
- {
- pChild = WIN_FindWndPtr(pWndArray[--nKidCount]);
-
- if (pChild!=NULL)
- {
- WIN_SendDestroyMsg( pChild );
- WIN_ReleaseWndPtr(pChild);
- }
- }
-
- /*
- * Cleanup
- */
- HeapFree(GetProcessHeap(), 0, pWndArray);
+ while (--i >= 0)
+ {
+ if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
+ }
+ WIN_ReleaseWinArray( pWndArray );
}
else
WARN("\tdestroyed itself while in WM_DESTROY!\n");
@@ -1162,46 +1095,29 @@
WND * wndPtr;
BOOL retvalue;
HWND h;
- BOOL bFocusSet = FALSE;
TRACE("(%04x)\n", hwnd);
/* Initialization */
if (hwnd == GetDesktopWindow()) return FALSE; /* Can't destroy desktop */
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
/* Look whether the focus is within the tree of windows we will
* be destroying.
*/
- h = GetFocus16();
- while (h && (GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
+ h = GetFocus();
+ if (h == hwnd || IsChild( hwnd, h ))
{
- if (h == hwnd)
- {
- SetFocus(GetParent(h));
- bFocusSet = TRUE;
- break;
- }
- h = GetParent(h);
- }
- /* If the focus is on the window we will destroy and it has no parent,
- * set the focus to 0.
- */
- if (! bFocusSet && (h == hwnd))
- {
- if (!(GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
- SetFocus(0);
+ HWND parent = GetAncestor( hwnd, GA_PARENT );
+ if (parent == GetDesktopWindow()) parent = 0;
+ SetFocus( parent );
}
/* Call hooks */
- if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
- {
- retvalue = FALSE;
- goto end;
- }
+ if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) ) return FALSE;
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
{
HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
@@ -1271,7 +1187,7 @@
/* Send destroy messages */
- WIN_SendDestroyMsg( wndPtr );
+ WIN_SendDestroyMsg( hwnd );
if (!IsWindow(hwnd))
{
retvalue = TRUE;
@@ -1348,70 +1264,50 @@
*
* Implementation of FindWindow() and FindWindowEx().
*/
-static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
- LPCWSTR title )
+static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className, LPCWSTR title )
{
- WND *pWnd;
+ HWND *list;
HWND retvalue;
+ int i = 0, len = 0;
+ WCHAR *buffer = NULL;
+
+ if (!parent) parent = GetDesktopWindow();
+ if (title)
+ {
+ len = strlenW(title) + 1; /* one extra char to check for chars beyond the end */
+ if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return 0;
+ }
+
+ if (!(list = WIN_BuildWinArray( parent )))
+ {
+ if (buffer) HeapFree( GetProcessHeap(), 0, buffer );
+ return 0;
+ }
if (child)
{
- if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
- if (parent)
- {
- if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
- {
- retvalue = 0;
- goto end;
- }
- }
- else if (pWnd->parent != pWndDesktop)
- {
- retvalue = 0;
- goto end;
- }
- WIN_UpdateWndPtr(&pWnd,pWnd->next);
- }
- else
- {
- if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
- {
- retvalue = 0;
- goto end;
- }
- WIN_UpdateWndPtr(&pWnd,pWnd->child);
- }
- if (!pWnd)
- {
- retvalue = 0;
- goto end;
+ while (list[i] && list[i] != child) i++;
+ if (!list[i]) return 0;
+ i++; /* start from next window */
}
- for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+ for ( ; list[i]; i++)
{
- if (className && (GetClassWord(pWnd->hwndSelf, GCW_ATOM) != className))
+ if (className && (GetClassWord(list[i], GCW_ATOM) != className))
continue; /* Not the right class */
/* Now check the title */
-
- if (!title)
- {
- retvalue = pWnd->hwndSelf;
- goto end;
- }
- if (pWnd->text && !strcmpW( pWnd->text, title ))
- {
- retvalue = pWnd->hwndSelf;
- goto end;
- }
+ if (!title) break;
+ if (GetWindowTextW( list[i], buffer, len ) && !strcmpiW( buffer, title )) break;
}
- retvalue = 0;
+ retvalue = list[i];
+ WIN_ReleaseWinArray( list );
+ if (buffer) HeapFree( GetProcessHeap(), 0, buffer );
+
/* In this case we need to check whether other processes
own a window with the given paramters on the Desktop,
but we don't, so let's at least warn about it */
- FIXME("Returning 0 without checking other processes\n");
-end:
- WIN_ReleaseWndPtr(pWnd);
+ if (!retvalue) FIXME("Returning 0 without checking other processes\n");
return retvalue;
}
@@ -2165,38 +2061,38 @@
}
-/*****************************************************************
- * WIN_GetTopParent
- *
- * Get the top-level parent for a child window.
- * returns a locked pointer
- */
-WND* WIN_GetTopParentPtr( WND* pWnd )
-{
- WND *tmpWnd = WIN_LockWndPtr(pWnd);
-
- while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
- {
- WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
- }
- return tmpWnd;
-}
/*****************************************************************
- * WIN_GetTopParent
- *
- * Get the top-level parent for a child window.
+ * GetAncestor (USER32.@)
*/
-HWND WIN_GetTopParent( HWND hwnd )
+HWND WINAPI GetAncestor( HWND hwnd, UINT type )
{
- HWND retvalue;
- WND *tmpPtr = WIN_FindWndPtr(hwnd);
- WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
-
- retvalue = wndPtr ? wndPtr->hwndSelf : 0;
- WIN_ReleaseWndPtr(tmpPtr);
- WIN_ReleaseWndPtr(wndPtr);
- return retvalue;
+ HWND ret;
+ WND *wndPtr, *parent;
+
+ if (hwnd == GetDesktopWindow()) return 0;
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ parent = wndPtr->parent;
+
+ switch(type)
+ {
+ case GA_PARENT:
+ WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
+ break;
+ case GA_ROOT:
+ while (wndPtr->parent->hwndSelf != GetDesktopWindow())
+ WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
+ break;
+ case GA_ROOTOWNER:
+ while (wndPtr->parent->hwndSelf != GetDesktopWindow())
+ WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
+ while (wndPtr->owner)
+ WIN_UpdateWndPtr( &wndPtr, wndPtr->owner );
+ break;
+ }
+ ret = wndPtr->hwndSelf;
+ WIN_ReleaseWndPtr( wndPtr );
+ return ret;
}
@@ -2481,6 +2377,7 @@
BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly )
{
int count = 0;
+ WND *pWnd;
HWND *win_array = WIN_BuildWinArray( GetDesktopWindow() );
if (!win_array) return TRUE;
@@ -2491,10 +2388,10 @@
while (win_array[count]) count++;
while (--count >= 0)
{
- WND *pWnd = WIN_FindWndPtr( win_array[count] );
- if (!pWnd) continue;
+ if (GetWindow( win_array[count], GW_OWNER ) != owner) continue;
+ if (!(pWnd = WIN_FindWndPtr( win_array[count] ))) continue;
- if (pWnd->owner && (pWnd->owner->hwndSelf == owner) && (pWnd->dwStyle & WS_POPUP))
+ if (pWnd->dwStyle & WS_POPUP)
{
if (fShow)
{
@@ -2545,7 +2442,7 @@
BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
{
int count = 0;
-
+ WND *pWnd;
HWND *win_array = WIN_BuildWinArray(GetDesktopWindow());
if (!win_array) return TRUE;
@@ -2553,10 +2450,10 @@
while (win_array[count]) count++;
while (--count >= 0)
{
- WND *pWnd = WIN_FindWndPtr( win_array[count] );
- if (!pWnd) continue;
+ if (GetWindow( win_array[count], GW_OWNER ) != owner) continue;
+ if (!(pWnd = WIN_FindWndPtr( win_array[count] ))) continue;
- if (pWnd->owner && (pWnd->owner->hwndSelf == owner) && (pWnd->dwStyle & WS_POPUP))
+ if (pWnd->dwStyle & WS_POPUP)
{
if (fShow)
{
@@ -2797,21 +2694,17 @@
*/
BOOL WINAPI AnyPopup(void)
{
- WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
+ int i;
BOOL retvalue;
-
- while (wndPtr)
+ HWND *list = WIN_BuildWinArray( GetDesktopWindow() );
+
+ if (!list) return FALSE;
+ for (i = 0; list[i]; i++)
{
- if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
- {
- retvalue = TRUE;
- goto end;
- }
- WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
+ if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
}
- retvalue = FALSE;
-end:
- WIN_ReleaseWndPtr(wndPtr);
+ retvalue = (list[i] != 0);
+ WIN_ReleaseWinArray( list );
return retvalue;
}
diff --git a/windows/winpos.c b/windows/winpos.c
index 19e0a15..ed7843e 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -187,13 +187,13 @@
*/
void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
{
- WND * wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr) return;
-
- CONV_RECT32TO16( &wndPtr->rectWindow, rect );
- if (wndPtr->parent)
- MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
- WIN_ReleaseWndPtr(wndPtr);
+ RECT rect32;
+
+ GetWindowRect( hwnd, &rect32 );
+ rect->left = rect32.left;
+ rect->top = rect32.top;
+ rect->right = rect32.right;
+ rect->bottom = rect32.bottom;
}
@@ -202,13 +202,11 @@
*/
BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
{
- WND * wndPtr = WIN_FindWndPtr( hwnd );
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return FALSE;
-
*rect = wndPtr->rectWindow;
- if (wndPtr->parent)
- MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
WIN_ReleaseWndPtr(wndPtr);
+ MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
TRACE("hwnd %04x (%d,%d)-(%d,%d)\n",
hwnd, rect->left, rect->top, rect->right, rect->bottom);
return TRUE;
@@ -528,38 +526,7 @@
*/
HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
{
- /* pt is in the client coordinates */
-
- WND* wnd = WIN_FindWndPtr(hwndParent);
- RECT rect;
- HWND retvalue;
-
- if( !wnd ) return 0;
-
- /* get client rect fast */
- rect.top = rect.left = 0;
- rect.right = wnd->rectClient.right - wnd->rectClient.left;
- rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
-
- if (!PtInRect( &rect, pt ))
- {
- retvalue = 0;
- goto end;
- }
- WIN_UpdateWndPtr(&wnd,wnd->child);
- while ( wnd )
- {
- if (PtInRect( &wnd->rectWindow, pt ))
- {
- retvalue = wnd->hwndSelf;
- goto end;
- }
- WIN_UpdateWndPtr(&wnd,wnd->next);
- }
- retvalue = hwndParent;
-end:
- WIN_ReleaseWndPtr(wnd);
- return retvalue;
+ return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
}
/*******************************************************************
@@ -576,50 +543,36 @@
/*******************************************************************
* ChildWindowFromPointEx (USER32.@)
*/
-HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt,
- UINT uFlags)
+HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
{
/* pt is in the client coordinates */
-
- WND* wnd = WIN_FindWndPtr(hwndParent);
+ HWND *list;
+ int i;
RECT rect;
- HWND retvalue;
+ HWND retvalue = 0;
- if( !wnd ) return 0;
+ GetClientRect( hwndParent, &rect );
+ if (!PtInRect( &rect, pt )) return 0;
+ if (!(list = WIN_BuildWinArray( hwndParent ))) return 0;
- /* get client rect fast */
- rect.top = rect.left = 0;
- rect.right = wnd->rectClient.right - wnd->rectClient.left;
- rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
-
- if (!PtInRect( &rect, pt ))
+ for (i = 0; list[i] && !retvalue; i++)
{
- retvalue = 0;
- goto end;
+ WND *wnd = WIN_FindWndPtr( list[i] );
+ if (!wnd) continue;
+ if (PtInRect( &wnd->rectWindow, pt ))
+ {
+ if ( (uFlags & CWP_SKIPINVISIBLE) &&
+ !(wnd->dwStyle & WS_VISIBLE) );
+ else if ( (uFlags & CWP_SKIPDISABLED) &&
+ (wnd->dwStyle & WS_DISABLED) );
+ else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
+ (wnd->dwExStyle & WS_EX_TRANSPARENT) );
+ else retvalue = list[i];
+ }
+ WIN_ReleaseWndPtr( wnd );
}
- WIN_UpdateWndPtr(&wnd,wnd->child);
-
- while ( wnd )
- {
- if (PtInRect( &wnd->rectWindow, pt )) {
- if ( (uFlags & CWP_SKIPINVISIBLE) &&
- !(wnd->dwStyle & WS_VISIBLE) );
- else if ( (uFlags & CWP_SKIPDISABLED) &&
- (wnd->dwStyle & WS_DISABLED) );
- else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
- (wnd->dwExStyle & WS_EX_TRANSPARENT) );
- else
- {
- retvalue = wnd->hwndSelf;
- goto end;
- }
-
- }
- WIN_UpdateWndPtr(&wnd,wnd->next);
- }
- retvalue = hwndParent;
-end:
- WIN_ReleaseWndPtr(wnd);
+ WIN_ReleaseWinArray( list );
+ if (!retvalue) retvalue = hwndParent;
return retvalue;
}
@@ -787,11 +740,10 @@
/*******************************************************************
* WINPOS_CanActivate
*/
-static BOOL WINPOS_CanActivate(WND* pWnd)
+static BOOL WINPOS_CanActivate(HWND hwnd)
{
- if( pWnd && ( (pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD))
- == WS_VISIBLE ) ) return TRUE;
- return FALSE;
+ if (!hwnd) return FALSE;
+ return ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_DISABLED|WS_VISIBLE|WS_CHILD)) == WS_VISIBLE);
}
@@ -1601,11 +1553,8 @@
if (hWnd)
{
/* walk up to the first unowned window */
- wndTemp = WIN_LockWndPtr(wndPtr);
- while (wndTemp->owner)
- {
- WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
- }
+ HWND tmp = GetAncestor( hWnd, GA_ROOTOWNER );
+ wndTemp = WIN_FindWndPtr( tmp );
/* and set last active owned popup */
wndTemp->hwndLastActive = hWnd;
@@ -1625,7 +1574,7 @@
{
HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
- if ( hOldFocus && WIN_GetTopParent( hOldFocus ) != hwndActive )
+ if ( hOldFocus && GetAncestor( hOldFocus, GA_ROOT ) != hwndActive )
FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus,
(wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
0 : hwndActive );
@@ -1673,8 +1622,9 @@
BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
{
BOOL bRet = 0;
- WND *pWnd, *pWndTo = NULL;
+ WND *pWnd;
HWND hwndActive = 0;
+ HWND hwndTo = 0;
/* Get current active window from the active queue */
if ( hActiveQueue )
@@ -1699,27 +1649,21 @@
}
if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
- !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
+ !WINPOS_CanActivate((hwndTo = GetAncestor( pWnd->owner->hwndSelf, GA_ROOT ))) )
{
- WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
+ HWND tmp = GetAncestor( pWnd->hwndSelf, GA_ROOT );
+ hwndTo = hwndPrevActive;
- WIN_ReleaseWndPtr(pWndTo);
- pWndTo = WIN_FindWndPtr(hwndPrevActive);
-
- while( !WINPOS_CanActivate(pWndTo) )
+ while( !WINPOS_CanActivate(hwndTo) )
{
/* by now owned windows should've been taken care of */
- WIN_UpdateWndPtr(&pWndTo,pWndPtr->next);
- WIN_UpdateWndPtr(&pWndPtr,pWndTo);
- if( !pWndTo ) break;
+ tmp = hwndTo = GetWindow( tmp, GW_HWNDNEXT );
+ if( !hwndTo ) break;
}
- WIN_ReleaseWndPtr(pWndPtr);
}
WIN_ReleaseWndPtr( pWnd );
- bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
-
- if( pWndTo ) WIN_ReleaseWndPtr(pWndTo);
+ bRet = WINPOS_SetActiveWindow( hwndTo, FALSE, TRUE );
hwndPrevActive = 0;
return bRet;
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 293e518..83e7205 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -353,7 +353,7 @@
/*
* Query the selection owner for the TARGETS property
*/
- w = X11DRV_get_top_window(hWnd);
+ w = X11DRV_get_whole_window( GetAncestor(hWnd,GA_ROOT) );
aTargets = TSXInternAtom(display, "TARGETS", False);
@@ -892,7 +892,8 @@
if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) )
{
Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
- owner = X11DRV_get_top_window( hWndClipWindow ? hWndClipWindow : AnyPopup() );
+ owner = X11DRV_get_whole_window( GetAncestor( hWndClipWindow ? hWndClipWindow : AnyPopup(),
+ GA_ROOT ) );
/* Grab PRIMARY selection if not owned */
if ( !(selectionAcquired & S_PRIMARY) )
@@ -1047,7 +1048,7 @@
{
XEvent xe;
Atom propRequest;
- Window w = X11DRV_get_top_window(hWnd);
+ Window w = X11DRV_get_whole_window( GetAncestor( hWnd, GA_ROOT ));
/* Map the format ID requested to an X selection property.
* If the format is in the cache, use the atom associated
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 3541f68..3071d99 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -386,16 +386,15 @@
x -= data->client_rect.left;
y -= data->client_rect.top;
}
- while (win->parent && win->parent->hwndSelf != GetDesktopWindow())
- {
- x += win->rectClient.left;
- y += win->rectClient.top;
- WIN_UpdateWndPtr( &win, win->parent );
- }
- pt->x = x + win->rectClient.left;
- pt->y = y + win->rectClient.top;
- *hwnd = win->hwndSelf;
WIN_ReleaseWndPtr( win );
+
+ pt->x = x;
+ pt->y = y;
+ if (*hwnd != GetDesktopWindow())
+ {
+ ClientToScreen( *hwnd, pt );
+ *hwnd = GetAncestor( *hwnd, GA_ROOT );
+ }
}