Authors: Gerard Patel <g.patel@wanadoo.fr>, Marcus Meissner <marcus@jet.franken.de>

Move focus recalculation out of the window destroy recursion
so we do not send WM_SETFOCUS to already destroyed windows.
This commit is contained in:
Alexandre Julliard 2000-11-02 20:08:59 +00:00
parent d5e15d3be1
commit 1f029ea6f5

View file

@ -1215,23 +1215,11 @@ HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, TRUE, TRUE ); return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, TRUE, TRUE );
} }
/***********************************************************************
* WIN_CheckFocus
*/
static void WIN_CheckFocus( WND* pWnd )
{
if( GetFocus16() == pWnd->hwndSelf )
SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
}
/*********************************************************************** /***********************************************************************
* WIN_SendDestroyMsg * WIN_SendDestroyMsg
*/ */
static void WIN_SendDestroyMsg( WND* pWnd ) static void WIN_SendDestroyMsg( WND* pWnd )
{ {
WIN_CheckFocus(pWnd);
if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret(); if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
USER_Driver.pResetSelectionOwner( pWnd, TRUE ); USER_Driver.pResetSelectionOwner( pWnd, TRUE );
@ -1312,7 +1300,6 @@ static void WIN_SendDestroyMsg( WND* pWnd )
* Cleanup * Cleanup
*/ */
HeapFree(GetProcessHeap(), 0, pWndArray); HeapFree(GetProcessHeap(), 0, pWndArray);
WIN_CheckFocus(pWnd);
} }
else else
WARN("\tdestroyed itself while in WM_DESTROY!\n"); WARN("\tdestroyed itself while in WM_DESTROY!\n");
@ -1335,10 +1322,12 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
{ {
WND * wndPtr; WND * wndPtr;
BOOL retvalue; BOOL retvalue;
HWND h;
BOOL bFocusSet = FALSE;
TRACE("(%04x)\n", hwnd); TRACE("(%04x)\n", hwnd);
/* Initialization */ /* Initialization */
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (wndPtr == pWndDesktop) if (wndPtr == pWndDesktop)
@ -1347,6 +1336,29 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
goto end; goto end;
} }
/* Look whether the focus is within the tree of windows we will
* be destroying.
*/
h = GetFocus16();
while (h && (GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
{
if (h == hwnd)
{
SetFocus(GetWindowLongA(hwnd,GWL_HWNDPARENT));
bFocusSet = TRUE;
break;
}
h = GetWindowLongA(h,GWL_HWNDPARENT);
}
/* 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);
}
/* Call hooks */ /* Call hooks */
if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) ) if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )