Added WIN_ListParents function and renamed WIN_BuildWinArray into
WIN_ListChildren. Made owner field in WND structure an HWND.
diff --git a/controls/icontitle.c b/controls/icontitle.c
index 6b9dad4..03bb6da 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -58,12 +58,10 @@
wndPtr = WIN_FindWndPtr( hWnd );
if( wndPtr )
{
- WND *wnd = WIN_FindWndPtr(owner);
- wndPtr->owner = wnd; /* MDI depends on this */
+ wndPtr->owner = owner; /* MDI depends on this */
wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER);
if (!IsWindowEnabled(owner)) wndPtr->dwStyle |= WS_DISABLED;
WIN_ReleaseWndPtr(wndPtr);
- WIN_ReleaseWndPtr(wnd);
return hWnd;
}
return 0;
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index 4fb4408..1bb66ab 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -347,9 +347,9 @@
/* transient for hint */
if (win->owner)
{
- struct x11drv_win_data *owner_data = win->owner->pDriverData;
- XSetTransientForHint( display, data->whole_window, owner_data->whole_window );
- group_leader = owner_data->whole_window;
+ Window owner_win = X11DRV_get_whole_window( win->owner );
+ XSetTransientForHint( display, data->whole_window, owner_win );
+ group_leader = owner_win;
}
else group_leader = data->whole_window;
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 81004a2..0bfbe3f 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -573,7 +573,7 @@
if( hwndInsertAfter != HWND_TOP )
{
- if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
+ if ((list = WIN_ListChildren( GetDesktopWindow() )))
{
int i;
for (i = 0; list[i]; i++)
@@ -588,7 +588,7 @@
}
else if (style & WS_CHILD) return hwndInsertAfter;
- if (!list) list = WIN_BuildWinArray( GetDesktopWindow() );
+ if (!list) list = WIN_ListChildren( GetDesktopWindow() );
if (list)
{
int i;
@@ -604,7 +604,7 @@
hwndInsertAfter = list[i];
}
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
}
return hwndInsertAfter;
diff --git a/include/win.h b/include/win.h
index 9d8ef27..63fe1ba 100644
--- a/include/win.h
+++ b/include/win.h
@@ -25,7 +25,7 @@
struct tagWND *next; /* Next sibling */
struct tagWND *child; /* First child */
struct tagWND *parent; /* Window parent (from CreateWindow) */
- struct tagWND *owner; /* Window owner */
+ HWND owner; /* Window owner */
struct tagCLASS *class; /* Window class */
HWINDOWPROC winproc; /* Window procedure */
DWORD dwMagic; /* Magic number (must be WND_MAGIC) */
@@ -92,8 +92,8 @@
extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void);
extern BOOL WIN_IsWindowDrawable(WND*, BOOL );
-extern HWND *WIN_BuildWinArray( HWND hwnd );
-extern void WIN_ReleaseWinArray( HWND *wndArray );
+extern HWND *WIN_ListParents( HWND hwnd );
+extern HWND *WIN_ListChildren( HWND hwnd );
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
extern HWND CARET_GetHwnd(void);
diff --git a/windows/dialog.c b/windows/dialog.c
index 985c230..ca15e7f 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -1609,14 +1609,14 @@
HWND WINAPI GetDlgItem( HWND hwndDlg, INT id )
{
int i;
- HWND *list = WIN_BuildWinArray( hwndDlg );
+ HWND *list = WIN_ListChildren( hwndDlg );
HWND ret = 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 );
+ HeapFree( GetProcessHeap(), 0, list );
return ret;
}
diff --git a/windows/mdi.c b/windows/mdi.c
index aea293a..e0fd58f 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -141,13 +141,13 @@
HWND *win_array;
int i;
- if (!(win_array = WIN_BuildWinArray( hwnd ))) return 0;
+ if (!(win_array = WIN_ListChildren( hwnd ))) return 0;
for (i = 0; win_array[i]; i++)
{
if (GetWindowLongA( win_array[i], GWL_ID ) == id) break;
}
ret = win_array[i];
- WIN_ReleaseWinArray( win_array );
+ HeapFree( GetProcessHeap(), 0, win_array );
return ret;
}
@@ -282,7 +282,7 @@
dwStyleMask |= WS_DISABLED | WS_VISIBLE;
if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
- if (!(list = WIN_BuildWinArray( GetParent(hWnd) ))) return 0;
+ if (!(list = WIN_ListChildren( GetParent(hWnd) ))) return 0;
i = 0;
/* start from next after hWnd */
while (list[i] && list[i] != hWnd) i++;
@@ -304,7 +304,7 @@
if (bNext) goto found;
}
found:
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
return last;
}
@@ -857,7 +857,7 @@
if (ci->nActiveChildren == 0) return 0;
- if (!(win_array = WIN_BuildWinArray( client ))) return 0;
+ if (!(win_array = WIN_ListChildren( client ))) return 0;
/* remove all the windows we don't want */
for (i = total = 0; win_array[i]; i++)
@@ -890,7 +890,7 @@
SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
}
}
- WIN_ReleaseWinArray( win_array );
+ HeapFree( GetProcessHeap(), 0, win_array );
if (has_icons) ArrangeIconicWindows( client );
return 0;
@@ -910,7 +910,7 @@
if (ci->nActiveChildren == 0) return;
- if (!(win_array = WIN_BuildWinArray( client ))) return;
+ if (!(win_array = WIN_ListChildren( client ))) return;
/* remove all the windows we don't want */
for (i = total = 0; win_array[i]; i++)
@@ -975,7 +975,7 @@
x += xsize;
}
}
- WIN_ReleaseWinArray( win_array );
+ HeapFree( GetProcessHeap(), 0, win_array );
if (has_icons) ArrangeIconicWindows( client );
}
@@ -1948,7 +1948,7 @@
GetClientRect( hwnd, &clientRect );
SetRectEmpty( &childRect );
- if ((list = WIN_BuildWinArray( hwnd )))
+ if ((list = WIN_ListChildren( hwnd )))
{
int i;
for (i = 0; list[i]; i++)
@@ -1956,7 +1956,7 @@
DWORD style = GetWindowLongW( list[i], GWL_STYLE );
if (style & WS_MAXIMIZE)
{
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
ShowScrollBar( hwnd, SB_BOTH, FALSE );
return;
}
@@ -1967,7 +1967,7 @@
WIN_ReleaseWndPtr( pWnd );
}
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
}
UnionRect( &childRect, &clientRect, &childRect );
@@ -2145,11 +2145,11 @@
HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
HWND *list, *sorted_list;
- if (!(list = WIN_BuildWinArray( (HWND)lParam ))) return TRUE;
+ if (!(list = WIN_ListChildren( (HWND)lParam ))) return TRUE;
if (!(sorted_list = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HWND) * ci->nActiveChildren )))
{
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
return FALSE;
}
@@ -2159,7 +2159,7 @@
UINT id = GetWindowLongW( list[i], GWL_ID ) - ci->idFirstChild;
if (id < ci->nActiveChildren) sorted_list[id] = list[i];
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
for (i = 0; i < ci->nActiveChildren; i++)
{
@@ -2260,13 +2260,13 @@
HWND *list;
int i;
- if (!(list = WIN_BuildWinArray( parent ))) return;
+ if (!(list = WIN_ListChildren( parent ))) return;
for (i = 0; list[i]; i++)
{
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 );
+ HeapFree( GetProcessHeap(), 0, list );
}
diff --git a/windows/painting.c b/windows/painting.c
index 7536d64..ffcd643 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -651,7 +651,7 @@
if( flags & (RDW_INVALIDATE | RDW_VALIDATE) )
{
HWND *list;
- if( hRgn > 1 && bChildren && (list = WIN_BuildWinArray( wndPtr->hwndSelf )))
+ if( hRgn > 1 && bChildren && (list = WIN_ListChildren( wndPtr->hwndSelf )))
{
POINT ptTotal, prevOrigin = {0,0};
POINT ptClient;
@@ -689,7 +689,7 @@
}
WIN_ReleaseWndPtr( wnd );
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
OffsetRgn( hRgn, ptTotal.x, ptTotal.y );
bChildren = 0;
}
@@ -700,7 +700,7 @@
if( bChildren )
{
HWND *list;
- if ((list = WIN_BuildWinArray( wndPtr->hwndSelf )))
+ if ((list = WIN_ListChildren( wndPtr->hwndSelf )))
{
INT i;
for (i = 0; list[i]; i++)
@@ -711,7 +711,7 @@
RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
WIN_ReleaseWndPtr( wnd );
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
}
}
@@ -820,7 +820,7 @@
{
HWND *list, *phwnd;
- if( (list = WIN_BuildWinArray( wndPtr->hwndSelf )) )
+ if( (list = WIN_ListChildren( wndPtr->hwndSelf )) )
{
for (phwnd = list; *phwnd; phwnd++)
{
@@ -830,7 +830,7 @@
hrgn = RDW_Paint( wndPtr, hrgn, flags, ex );
WIN_ReleaseWndPtr(wndPtr);
}
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
}
}
diff --git a/windows/user.c b/windows/user.c
index 40b5c91..9380233 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -224,7 +224,7 @@
/* We have to build a list of all windows first, as in EnumWindows */
- if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
+ if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return FALSE;
/* Send a WM_QUERYENDSESSION message to every window */
@@ -243,7 +243,7 @@
if (!IsWindow( *phwnd )) continue;
SendMessageW( *phwnd, WM_ENDSESSION, result, 0 );
}
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
if (result) ExitKernel16();
return FALSE;
diff --git a/windows/win.c b/windows/win.c
index 544dddc..a8cc9ad 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -167,53 +167,6 @@
}
-/***********************************************************************
- * WIN_DumpWindow
- *
- * Dump the content of a window structure to stderr.
- */
-void WIN_DumpWindow( HWND hwnd )
-{
- WND *ptr;
- char className[80];
- int i;
-
- if (!(ptr = WIN_FindWndPtr( hwnd )))
- {
- WARN("%04x is not a window handle\n", hwnd );
- return;
- }
-
- if (!GetClassNameA( hwnd, className, sizeof(className ) ))
- strcpy( className, "#NULL#" );
-
- TRACE("Window %04x (%p):\n", hwnd, ptr );
- DPRINTF( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
- "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
- "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
- "client=%d,%d-%d,%d window=%d,%d-%d,%d"
- "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
- ptr->next, ptr->child, ptr->parent, ptr->owner,
- ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
- ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
- ptr->dwStyle, ptr->dwExStyle, (UINT)ptr->winproc,
- ptr->text ? debugstr_w(ptr->text) : "",
- ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
- ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
- ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
- ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
-
- if (ptr->cbWndExtra)
- {
- DPRINTF( "extra bytes:" );
- for (i = 0; i < ptr->cbWndExtra; i++)
- DPRINTF( " %02x", *((BYTE*)ptr->wExtra+i) );
- DPRINTF( "\n" );
- }
- DPRINTF( "\n" );
- WIN_ReleaseWndPtr(ptr);
-}
-
/***********************************************************************
* WIN_UnlinkWindow
@@ -428,7 +381,7 @@
HWND *list;
int i;
- if (!(list = WIN_BuildWinArray( hwnd ))) return;
+ if (!(list = WIN_ListChildren( hwnd ))) return;
for (i = 0; list[i]; i++)
{
if (!IsWindow( list[i] )) continue;
@@ -437,7 +390,7 @@
else
WIN_DestroyThreadWindows( list[i] );
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
}
/***********************************************************************
@@ -470,7 +423,7 @@
pWndDesktop->next = NULL;
pWndDesktop->child = NULL;
pWndDesktop->parent = NULL;
- pWndDesktop->owner = NULL;
+ pWndDesktop->owner = 0;
pWndDesktop->class = class;
pWndDesktop->dwMagic = WND_MAGIC;
pWndDesktop->hwndSelf = hwndDesktop;
@@ -675,19 +628,16 @@
if ((cs->style & WS_CHILD) && cs->hwndParent)
{
wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
- wndPtr->owner = NULL;
+ wndPtr->owner = 0;
WIN_ReleaseWndPtr(wndPtr->parent);
}
else
{
wndPtr->parent = pWndDesktop;
if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
- wndPtr->owner = NULL;
+ wndPtr->owner = 0;
else
- {
- wndPtr->owner = WIN_FindWndPtr( GetAncestor( cs->hwndParent, GA_ROOT ));
- WIN_ReleaseWndPtr(wndPtr->owner);
- }
+ wndPtr->owner = GetAncestor( cs->hwndParent, GA_ROOT );
}
@@ -1062,7 +1012,7 @@
HWND* pWndArray;
int i;
- if (!(pWndArray = WIN_BuildWinArray( hwnd ))) return;
+ if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
/* start from the end (FIXME: is this needed?) */
for (i = 0; pWndArray[i]; i++) ;
@@ -1071,7 +1021,7 @@
{
if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
}
- WIN_ReleaseWinArray( pWndArray );
+ HeapFree( GetProcessHeap(), 0, pWndArray );
}
else
WARN("\tdestroyed itself while in WM_DESTROY!\n");
@@ -1158,31 +1108,40 @@
{
for (;;)
{
- WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child); /* First sibling */
- while (siblingPtr)
- {
- if (siblingPtr->owner == wndPtr)
- {
- if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
- break;
- else
- siblingPtr->owner = NULL;
- }
- WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
- }
- if (siblingPtr)
- {
- DestroyWindow( siblingPtr->hwndSelf );
- WIN_ReleaseWndPtr(siblingPtr);
- }
- else break;
+ int i, got_one = 0;
+ HWND *list = WIN_ListChildren( wndPtr->parent->hwndSelf );
+ if (list)
+ {
+ for (i = 0; list[i]; i++)
+ {
+ WND *siblingPtr = WIN_FindWndPtr( list[i] );
+ if (!siblingPtr) continue;
+ if (siblingPtr->owner == hwnd)
+ {
+ if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
+ {
+ WIN_ReleaseWndPtr( siblingPtr );
+ DestroyWindow( list[i] );
+ got_one = 1;
+ continue;
+ }
+ else siblingPtr->owner = 0;
+ }
+ WIN_ReleaseWndPtr( siblingPtr );
+ }
+ HeapFree( GetProcessHeap(), 0, list );
+ }
+ if (!got_one) break;
}
WINPOS_ActivateOtherWindow(wndPtr->hwndSelf);
- if( wndPtr->owner &&
- wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
- wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
+ if (wndPtr->owner)
+ {
+ WND *owner = WIN_FindWndPtr( wndPtr->owner );
+ if (owner->hwndLastActive == hwnd) owner->hwndLastActive = wndPtr->owner;
+ WIN_ReleaseWndPtr( owner );
+ }
}
/* Send destroy messages */
@@ -1278,7 +1237,7 @@
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return 0;
}
- if (!(list = WIN_BuildWinArray( parent )))
+ if (!(list = WIN_ListChildren( parent )))
{
if (buffer) HeapFree( GetProcessHeap(), 0, buffer );
return 0;
@@ -1301,7 +1260,7 @@
if (GetWindowTextW( list[i], buffer, len ) && !strcmpiW( buffer, title )) break;
}
retvalue = list[i];
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
if (buffer) HeapFree( GetProcessHeap(), 0, buffer );
/* In this case we need to check whether other processes
@@ -2046,19 +2005,16 @@
{
WND *wndPtr;
HWND retvalue = 0;
-
- if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
- if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
- goto end;
- WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
- if (wndPtr)
- retvalue = wndPtr->hwndSelf;
-
-end:
- WIN_ReleaseWndPtr(wndPtr);
+ if ((wndPtr = WIN_FindWndPtr(hwnd)))
+ {
+ if (wndPtr->dwStyle & WS_CHILD)
+ retvalue = wndPtr->parent->hwndSelf;
+ else if (wndPtr->dwStyle & WS_POPUP)
+ retvalue = wndPtr->owner;
+ WIN_ReleaseWndPtr(wndPtr);
+ }
return retvalue;
-
}
@@ -2087,7 +2043,11 @@
while (wndPtr->parent->hwndSelf != GetDesktopWindow())
WIN_UpdateWndPtr( &wndPtr, wndPtr->parent );
while (wndPtr->owner)
- WIN_UpdateWndPtr( &wndPtr, wndPtr->owner );
+ {
+ WND *ptr = WIN_FindWndPtr( wndPtr->owner );
+ WIN_ReleaseWndPtr( wndPtr );
+ wndPtr = ptr;
+ }
break;
}
ret = wndPtr->hwndSelf;
@@ -2189,19 +2149,15 @@
*/
BOOL WINAPI IsChild( HWND parent, HWND child )
{
- WND * wndPtr = WIN_FindWndPtr( child );
- while (wndPtr && wndPtr->parent)
- {
- WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
- if (wndPtr->hwndSelf == GetDesktopWindow()) break;
- if (wndPtr->hwndSelf == parent)
- {
- WIN_ReleaseWndPtr(wndPtr);
- return TRUE;
- }
- }
- WIN_ReleaseWndPtr(wndPtr);
- return FALSE;
+ HWND *list = WIN_ListParents( child );
+ int i;
+ BOOL ret;
+
+ if (!list) return FALSE;
+ for (i = 0; list[i]; i++) if (list[i] == parent) break;
+ ret = (list[i] != 0);
+ HeapFree( GetProcessHeap(), 0, list );
+ return ret;
}
@@ -2219,19 +2175,16 @@
*/
BOOL WINAPI IsWindowVisible( HWND hwnd )
{
+ HWND *list;
BOOL retval;
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- while (wndPtr && wndPtr->parent)
- {
- if (!(wndPtr->dwStyle & WS_VISIBLE))
- {
- WIN_ReleaseWndPtr(wndPtr);
- return FALSE;
- }
- WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
- }
- retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
- WIN_ReleaseWndPtr(wndPtr);
+ int i;
+
+ if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) return FALSE;
+ if (!(list = WIN_ListParents( hwnd ))) return TRUE;
+ for (i = 0; list[i]; i++)
+ if (!(GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)) break;
+ retval = !list[i];
+ HeapFree( GetProcessHeap(), 0, list );
return retval;
}
@@ -2245,13 +2198,21 @@
*/
BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
{
- if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE;
- if ((wnd->dwStyle & WS_MINIMIZE) &&
- icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE;
- for(wnd = wnd->parent; wnd; wnd = wnd->parent)
- if( wnd->dwStyle & WS_MINIMIZE ||
- !(wnd->dwStyle & WS_VISIBLE) ) break;
- return (wnd == NULL);
+ HWND *list;
+ BOOL retval;
+ int i;
+
+ if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE;
+ if ((wnd->dwStyle & WS_MINIMIZE) &&
+ icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE;
+
+ if (!(list = WIN_ListParents( wnd->hwndSelf ))) return TRUE;
+ for (i = 0; list[i]; i++)
+ if ((GetWindowLongW( list[i], GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != WS_VISIBLE)
+ break;
+ retval = !list[i];
+ HeapFree( GetProcessHeap(), 0, list );
+ return retval;
}
@@ -2340,7 +2301,7 @@
goto end;
case GW_OWNER:
- retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
+ retval = wndPtr->owner;
goto end;
case GW_CHILD:
@@ -2378,7 +2339,7 @@
{
int count = 0;
WND *pWnd;
- HWND *win_array = WIN_BuildWinArray( GetDesktopWindow() );
+ HWND *win_array = WIN_ListChildren( GetDesktopWindow() );
if (!win_array) return TRUE;
@@ -2422,7 +2383,7 @@
}
WIN_ReleaseWndPtr( pWnd );
}
- WIN_ReleaseWinArray( win_array );
+ HeapFree( GetProcessHeap(), 0, win_array );
return TRUE;
}
@@ -2443,7 +2404,7 @@
{
int count = 0;
WND *pWnd;
- HWND *win_array = WIN_BuildWinArray(GetDesktopWindow());
+ HWND *win_array = WIN_ListChildren( GetDesktopWindow() );
if (!win_array) return TRUE;
@@ -2482,7 +2443,7 @@
}
WIN_ReleaseWndPtr( pWnd );
}
- WIN_ReleaseWinArray( win_array );
+ HeapFree( GetProcessHeap(), 0, win_array );
return TRUE;
}
@@ -2512,15 +2473,56 @@
/*******************************************************************
- * WIN_BuildWinArray
+ * WIN_ListParents
*
- * Build an array of pointers to the children of a given window.
- * The array must be freed with WIN_ReleaseWinArray. Return NULL
- * when no windows are found.
+ * Build an array of all parents of a given window, starting with
+ * the immediate parent. The array must be freed with HeapFree.
+ * Returns NULL if window is a top-level window.
*/
-HWND *WIN_BuildWinArray( HWND hwnd )
+HWND *WIN_ListParents( HWND hwnd )
{
- /* Future: this function will lock all windows associated with this array */
+ WND *parent, *wndPtr = WIN_FindWndPtr( hwnd );
+ HWND *list = NULL;
+ UINT i, count = 0;
+
+ /* First count the windows */
+
+ if (!wndPtr) return NULL;
+
+ parent = wndPtr->parent;
+ while (parent && parent->hwndSelf != GetDesktopWindow())
+ {
+ count++;
+ parent = parent->parent;
+ }
+
+ if (count)
+ {
+ if ((list = HeapAlloc( GetProcessHeap(), 0, sizeof(HWND) * (count + 1) )))
+ {
+ parent = wndPtr->parent;
+ for (i = 0; i < count; i++)
+ {
+ list[i] = parent->hwndSelf;
+ parent = parent->parent;
+ }
+ list[i] = 0;
+ }
+ }
+
+ WIN_ReleaseWndPtr( wndPtr );
+ return list;
+}
+
+
+/*******************************************************************
+ * WIN_ListChildren
+ *
+ * Build an array of the children of a given window. The array must be
+ * freed with HeapFree. Returns NULL when no windows are found.
+ */
+HWND *WIN_ListChildren( HWND hwnd )
+{
WND *pWnd, *wndPtr = WIN_FindWndPtr( hwnd );
HWND *list, *phwnd;
UINT count = 0;
@@ -2557,13 +2559,6 @@
return list;
}
-/*******************************************************************
- * WIN_ReleaseWinArray
- */
-void WIN_ReleaseWinArray(HWND *wndArray)
-{
- if (wndArray) HeapFree( GetProcessHeap(), 0, wndArray );
-}
/*******************************************************************
* EnumWindows (USER32.@)
@@ -2578,7 +2573,7 @@
/* unpleasant side-effects, for instance if the callback */
/* function changes the Z-order of the windows. */
- if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
+ if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return FALSE;
/* Now call the callback function for every window */
@@ -2590,7 +2585,7 @@
if (!(ret = lpEnumFunc( list[i], lParam ))) break;
}
WIN_RestoreWndsLock(iWndsLocks);
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
return ret;
}
@@ -2615,7 +2610,7 @@
HWND *list;
int i, iWndsLocks;
- if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
+ if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return FALSE;
/* Now call the callback function for every window */
@@ -2626,7 +2621,7 @@
if (!func( list[i], lParam )) break;
}
WIN_RestoreWndsLock(iWndsLocks);
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
return TRUE;
}
@@ -2648,14 +2643,14 @@
/* skip owned windows */
if (GetWindow( *list, GW_OWNER )) continue;
/* Build children list first */
- childList = WIN_BuildWinArray( *list );
+ childList = WIN_ListChildren( *list );
ret = func( *list, lParam );
if (childList)
{
if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
- WIN_ReleaseWinArray(childList);
+ HeapFree( GetProcessHeap(), 0, childList );
}
if (!ret) return FALSE;
}
@@ -2671,11 +2666,11 @@
HWND *list;
int iWndsLocks;
- if (!(list = WIN_BuildWinArray( parent ))) return FALSE;
+ if (!(list = WIN_ListChildren( parent ))) return FALSE;
iWndsLocks = WIN_SuspendWndsLock();
WIN_EnumChildWindows( list, func, lParam );
WIN_RestoreWndsLock(iWndsLocks);
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
return TRUE;
}
@@ -2696,7 +2691,7 @@
{
int i;
BOOL retvalue;
- HWND *list = WIN_BuildWinArray( GetDesktopWindow() );
+ HWND *list = WIN_ListChildren( GetDesktopWindow() );
if (!list) return FALSE;
for (i = 0; list[i]; i++)
@@ -2704,7 +2699,7 @@
if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
}
retvalue = (list[i] != 0);
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
return retvalue;
}
diff --git a/windows/winpos.c b/windows/winpos.c
index ed7843e..8a9be5e 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -553,7 +553,7 @@
GetClientRect( hwndParent, &rect );
if (!PtInRect( &rect, pt )) return 0;
- if (!(list = WIN_BuildWinArray( hwndParent ))) return 0;
+ if (!(list = WIN_ListChildren( hwndParent ))) return 0;
for (i = 0; list[i] && !retvalue; i++)
{
@@ -571,7 +571,7 @@
}
WIN_ReleaseWndPtr( wnd );
}
- WIN_ReleaseWinArray( list );
+ HeapFree( GetProcessHeap(), 0, list );
if (!retvalue) retvalue = hwndParent;
return retvalue;
}
@@ -1523,7 +1523,7 @@
DWORD old_thread = GetWindowThreadProcessId( hwndPrevActive, NULL );
DWORD new_thread = GetWindowThreadProcessId( hwndActive, NULL );
- if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
+ if ((list = WIN_ListChildren( GetDesktopWindow() )))
{
for (phwnd = list; *phwnd; phwnd++)
{
@@ -1531,12 +1531,12 @@
if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread)
SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread );
}
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
}
hActiveQueue = hNewActiveQueue;
- if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
+ if ((list = WIN_ListChildren( GetDesktopWindow() )))
{
for (phwnd = list; *phwnd; phwnd++)
{
@@ -1544,7 +1544,7 @@
if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread)
SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread );
}
- WIN_ReleaseWinArray(list);
+ HeapFree( GetProcessHeap(), 0, list );
}
if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
@@ -1625,6 +1625,7 @@
WND *pWnd;
HWND hwndActive = 0;
HWND hwndTo = 0;
+ HWND owner;
/* Get current active window from the active queue */
if ( hActiveQueue )
@@ -1648,10 +1649,11 @@
return 0;
}
- if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
- !WINPOS_CanActivate((hwndTo = GetAncestor( pWnd->owner->hwndSelf, GA_ROOT ))) )
+ owner = GetWindow( hwnd, GW_OWNER );
+ if( !(pWnd->dwStyle & WS_POPUP) || !owner ||
+ !WINPOS_CanActivate((hwndTo = GetAncestor( owner, GA_ROOT ))) )
{
- HWND tmp = GetAncestor( pWnd->hwndSelf, GA_ROOT );
+ HWND tmp = GetAncestor( hwnd, GA_ROOT );
hwndTo = hwndPrevActive;
while( !WINPOS_CanActivate(hwndTo) )