diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index f94c176b445..96497c58725 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec @@ -655,6 +655,7 @@ debug_channels (accel caret class clipboard combo cursor dc dde ddeml dialog dri # 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 b8bb8174d7b..4fb440857f5 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -488,22 +488,17 @@ int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder ) 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 @@ Window X11DRV_get_whole_window( HWND hwnd ) } -/*********************************************************************** - * 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 @@ void X11DRV_SetFocus( HWND hwnd ) 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 3470ea479e1..81004a2ab5c 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -557,13 +557,15 @@ static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos, * * 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 @@ static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, 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 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) 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 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) RECT rect; UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow); - DCE_InvalidateDCE(wndPtr, &rect); + DCE_InvalidateDCE(wndPtr->hwndSelf, &rect); } oldWindowRect = wndPtr->rectWindow; @@ -1152,7 +1158,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event ) 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 6e28da7e217..637cce2285d 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 @@ typedef struct tagDCE 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 02d3b409ac4..9d8ef27b716 100644 --- a/include/win.h +++ b/include/win.h @@ -89,10 +89,8 @@ extern void WIN_WalkWindows( HWND hwnd, int indent ); 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 cce19006b7d..16beba9a078 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -1089,6 +1089,11 @@ typedef struct { #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 FindWindowW(LPCWSTR,LPCWSTR); 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 9c3fca33cd7..2fa33f751c3 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -395,7 +395,6 @@ typedef struct x11drv_win_data X11DRV_WND_DATA; 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 b7bb0243c94..d20645876cd 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -143,7 +143,7 @@ DCE* DCE_FreeDCE( DCE *dce ) * * Remove owned DCE and reset unreleased cache DCEs. */ -void DCE_FreeWindowDCE( WND* pWnd ) +void DCE_FreeWindowDCE( HWND hwnd ) { DCE *pDCE; @@ -152,14 +152,16 @@ void DCE_FreeWindowDCE( WND* pWnd ) 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 @@ void DCE_FreeWindowDCE( WND* pWnd ) pDCE->DCXflags |= DCX_DCEEMPTY; pDCE->hwndCurrent = 0; } + WIN_ReleaseWndPtr( pWnd ); } pDCE = pDCE->next; } @@ -257,17 +260,17 @@ static INT DCE_ReleaseDC( DCE* dce ) * 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 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) 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 @@ BOOL DCE_InvalidateDCE(WND* pWnd, const RECT* pRectUpdate) * 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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) 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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) 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 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) 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 6b60957be5b..f15d43e7527 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -162,14 +162,14 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam ) 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 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam ) 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 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa 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 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa /* 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 7b863e65cc3..985c230c34b 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -100,14 +100,13 @@ const struct builtin_class_descr DIALOG_builtin_class = * 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 @@ BOOL DIALOG_DisableOwner( HWND hOwner ) { /* 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 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, { 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 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, } 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 @@ static INT DIALOG_DoDialogBox( HWND hwnd, HWND owner ) 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 @@ static INT DIALOG_DoDialogBox( HWND hwnd, HWND owner ) 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 @@ BOOL WINAPI EndDialog( HWND hwnd, INT retval ) WND * wndPtr = WIN_FindWndPtr( hwnd ); BOOL wasEnabled = TRUE; DIALOGINFO * dlgInfo; + HWND owner; TRACE("%04x %d\n", hwnd, retval ); @@ -1257,14 +1255,15 @@ BOOL WINAPI EndDialog( HWND hwnd, INT retval ) dlgInfo->flags |= DF_END; wasEnabled = (dlgInfo->flags & DF_OWNERENABLED); } + WIN_ReleaseWndPtr(wndPtr); + + if (wasEnabled && (owner = GetWindow( hwnd, GW_OWNER ))) + DIALOG_EnableOwner( owner ); - if(wndPtr->owner) - DIALOG_EnableOwner( wndPtr->owner->hwndSelf, wasEnabled ); - /* 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 @@ BOOL WINAPI EndDialog( HWND hwnd, INT retval ) 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 @@ static BOOL DIALOG_IsAccelerator( HWND hwnd, HWND hwndDlg, WPARAM vKey ) { 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 @@ BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg ) */ 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 @@ HWND16 WINAPI GetDlgItem16( HWND16 hwndDlg, INT16 id ) */ 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 @@ HWND16 WINAPI GetNextDlgGroupItem16( HWND16 hwndDlg, HWND16 hwndCtrl, 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 @@ HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, 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 48204292e44..57582d5cd96 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -59,39 +59,40 @@ HWND16 WINAPI SetFocus16( HWND16 hwnd ) 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 @@ HWND WINAPI SetFocus( HWND hwnd ) 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 @@ CLEANUP: if ( pMsgQ ) QUEUE_Unlock( pMsgQ ); - WIN_ReleaseWndPtr(wndPtr); return bRet ? hWndFocus : 0; } diff --git a/windows/mdi.c b/windows/mdi.c index feb2430b791..aea293a8c60 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -193,25 +193,24 @@ static MDICLIENTINFO *get_client_info( HWND client ) /********************************************************************** * 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 BOOL MDI_MenuDeleteItem( HWND client, HWND hWndChild ) 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 @@ static LONG MDI_ChildActivate( HWND client, HWND child ) /* 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 @@ static void MDI_UpdateFrameText( HWND frame, HWND hClient, 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 @@ static void MDI_UpdateFrameText( HWND frame, HWND hClient, 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 @@ LRESULT WINAPI DefFrameProcW( HWND hwnd, HWND hwndMDIClient, 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 @@ void WINAPI CalcChildScroll( HWND hwnd, INT scroll ) 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 @@ static BOOL WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, { 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 @@ static BOOL WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, 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 @@ static BOOL WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, */ 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 HWND MDI_MoreWindowsDialog(HWND hwnd) 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 99a276cd7ed..2134854f0f3 100644 --- a/windows/message.c +++ b/windows/message.c @@ -433,7 +433,7 @@ static BOOL process_cooked_mouse_message( MSG *msg, BOOL remove ) (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 65a3f2e2e87..172e1222779 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -1787,7 +1787,7 @@ void NC_GetSysPopupPos( HWND hwnd, RECT* rect ) 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 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) { 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 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt ) 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 6f73fe17771..7536d6466e9 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -96,12 +96,8 @@ static void add_paint_count( HWND hwnd, int incr ) * 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 @@ static BOOL WIN_HaveToDelayNCPAINT( * 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 @@ static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags ) * 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 @@ HBRUSH16 WINAPI GetControlBrush16( HWND16 hwnd, HDC16 hdc, UINT16 ctlType ) */ static void RDW_ValidateParent(WND *wndChild) { - WND *wndParent = WIN_LockWndPtr(wndChild->parent); + HWND parent; HRGN hrg; if (wndChild->hrgnUpdate == 1 ) { @@ -508,7 +498,10 @@ static void RDW_ValidateParent(WND *wndChild) } 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 @@ static void RDW_ValidateParent(WND *wndChild) 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 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs */ 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 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs 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 @@ static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecurs 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 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex ) * 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 @@ static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex ) /* ... 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 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd ) /* 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 e070ab82089..544dddc3349 100644 --- a/windows/win.c +++ b/windows/win.c @@ -406,7 +406,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) 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 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) * 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, 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 @@ HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className, 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 @@ BOOL WINAPI DestroyWindow( HWND hwnd ) 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 @@ BOOL WINAPI DestroyWindow( HWND hwnd ) /* Send destroy messages */ - WIN_SendDestroyMsg( wndPtr ); + WIN_SendDestroyMsg( hwnd ); if (!IsWindow(hwnd)) { retvalue = TRUE; @@ -1348,70 +1264,50 @@ BOOL WINAPI OpenIcon( HWND hwnd ) * * 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 @@ end: } -/***************************************************************** - * 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 @@ HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag ) 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 @@ BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly ) 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 @@ void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow ) 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 @@ BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow ) 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 @@ BOOL16 WINAPI AnyPopup16(void) */ 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 19e0a154802..ed7843e47a1 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -187,13 +187,13 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore ) */ 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 @@ void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect ) */ 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 @@ HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt ) */ 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 @@ HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uF /******************************************************************* * 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 @@ HWND WINAPI GetActiveWindow(void) /******************************************************************* * 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) 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 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus) { 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 @@ CLEANUP_END: 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 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd) } 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 293e518fa7b..83e72054ca8 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -353,7 +353,7 @@ int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName ) /* * 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 @@ void X11DRV_AcquireClipboard(void) 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 @@ BOOL X11DRV_GetClipboardData(UINT wFormat) { 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 3541f68fd48..3071d994905 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -386,16 +386,15 @@ static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt ) 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 ); + } }