win32u: Move NtUserDestroyWindow implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7a7d999d4a
commit
6a5ddbeedc
|
@ -616,29 +616,6 @@ static HANDLE render_synthesized_format( UINT format, UINT from )
|
|||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CLIPBOARD_ReleaseOwner
|
||||
*/
|
||||
void CLIPBOARD_ReleaseOwner( HWND hwnd )
|
||||
{
|
||||
HWND viewer = 0, owner = 0;
|
||||
|
||||
SendMessageW( hwnd, WM_RENDERALLFORMATS, 0, 0 );
|
||||
|
||||
SERVER_START_REQ( release_clipboard )
|
||||
{
|
||||
req->owner = wine_server_user_handle( hwnd );
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
viewer = wine_server_ptr_handle( reply->viewer );
|
||||
owner = wine_server_ptr_handle( reply->owner );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (viewer) SendNotifyMessageW( viewer, WM_DRAWCLIPBOARD, (WPARAM)owner, 0 );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* RegisterClipboardFormatW (USER32.@)
|
||||
|
|
|
@ -173,7 +173,7 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
|
|||
TRACE("[%p]: freeing storage\n", lphc->self);
|
||||
|
||||
if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
|
||||
DestroyWindow( lphc->hWndLBox );
|
||||
NtUserDestroyWindow( lphc->hWndLBox );
|
||||
|
||||
SetWindowLongPtrW( lphc->self, 0, 0 );
|
||||
HeapFree( GetProcessHeap(), 0, lphc );
|
||||
|
|
|
@ -1158,7 +1158,7 @@ BOOL WINAPI DdeUninitialize(DWORD idInst)
|
|||
*/
|
||||
WDML_FreeAllHSZ(pInstance);
|
||||
|
||||
DestroyWindow(pInstance->hwndEvent);
|
||||
NtUserDestroyWindow( pInstance->hwndEvent );
|
||||
|
||||
/* OK now delete the instance handle itself */
|
||||
|
||||
|
@ -1711,7 +1711,7 @@ void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic)
|
|||
pPrev->next = pServer->next;
|
||||
}
|
||||
|
||||
DestroyWindow(pServer->hwndServer);
|
||||
NtUserDestroyWindow(pServer->hwndServer);
|
||||
WDML_DecHSZ(pInstance, pServer->hszServiceSpec);
|
||||
WDML_DecHSZ(pInstance, pServer->hszService);
|
||||
|
||||
|
@ -2105,7 +2105,7 @@ void WDML_RemoveConv(WDML_CONV* pRef, WDML_SIDE side)
|
|||
hWnd = (side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer;
|
||||
SetWindowLongPtrW(hWnd, GWL_WDML_CONVERSATION, 0);
|
||||
|
||||
DestroyWindow((side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer);
|
||||
NtUserDestroyWindow((side == WDML_CLIENT_SIDE) ? pRef->hwndClient : pRef->hwndServer);
|
||||
|
||||
WDML_DecHSZ(pRef->instance, pRef->hszService);
|
||||
WDML_DecHSZ(pRef->instance, pRef->hszTopic);
|
||||
|
|
|
@ -360,7 +360,7 @@ static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClien
|
|||
}
|
||||
else
|
||||
{
|
||||
DestroyWindow(hwndServerConv);
|
||||
NtUserDestroyWindow(hwndServerConv);
|
||||
}
|
||||
return pConv;
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
|
|||
return 0;
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow( hwnd );
|
||||
NtUserDestroyWindow( hwnd );
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEACTIVATE:
|
||||
|
|
|
@ -707,7 +707,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
|
|||
return hwnd;
|
||||
}
|
||||
if (disabled_owner) EnableWindow( disabled_owner, TRUE );
|
||||
if( IsWindow(hwnd) ) DestroyWindow( hwnd );
|
||||
if (IsWindow(hwnd)) NtUserDestroyWindow( hwnd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -827,7 +827,7 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
|
|||
}
|
||||
}
|
||||
retval = dlgInfo->idResult;
|
||||
DestroyWindow( hwnd );
|
||||
NtUserDestroyWindow( hwnd );
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,10 +79,6 @@ static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void CDECL nulldrv_DestroyWindow( HWND hwnd )
|
||||
{
|
||||
}
|
||||
|
||||
static DWORD CDECL nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
|
||||
DWORD mask, DWORD flags )
|
||||
{
|
||||
|
@ -174,7 +170,7 @@ static struct user_driver_funcs lazy_load_driver =
|
|||
/* windowing functions */
|
||||
NULL,
|
||||
loaderdrv_CreateWindow,
|
||||
nulldrv_DestroyWindow,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
nulldrv_MsgWaitForMultipleObjectsEx,
|
||||
|
@ -223,7 +219,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
|
|||
SET_USER_FUNC(SetCursorPos);
|
||||
SET_USER_FUNC(UpdateClipboard);
|
||||
SET_USER_FUNC(CreateWindow);
|
||||
SET_USER_FUNC(DestroyWindow);
|
||||
SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
|
||||
SET_USER_FUNC(SetWindowIcon);
|
||||
SET_USER_FUNC(SetWindowText);
|
||||
|
|
|
@ -580,7 +580,7 @@ static LRESULT MDIDestroyChild( HWND client, MDICLIENTINFO *ci,
|
|||
{
|
||||
SendMessageW(client, WM_MDIREFRESHMENU, 0, 0);
|
||||
MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
|
||||
DestroyWindow(child);
|
||||
NtUserDestroyWindow(child);
|
||||
}
|
||||
|
||||
TRACE("child destroyed - %p\n", child);
|
||||
|
|
|
@ -2333,7 +2333,7 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
|
|||
if (!(submenu = MENU_GetMenu( hsubmenu ))) return;
|
||||
MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE, wFlags );
|
||||
MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
|
||||
DestroyWindow( submenu->hWnd );
|
||||
NtUserDestroyWindow( submenu->hWnd );
|
||||
submenu->hWnd = 0;
|
||||
|
||||
if (!(wFlags & TPM_NONOTIFY))
|
||||
|
@ -3319,7 +3319,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
|
|||
|
||||
if (menu && (menu->wFlags & MF_POPUP))
|
||||
{
|
||||
DestroyWindow( menu->hWnd );
|
||||
NtUserDestroyWindow( menu->hWnd );
|
||||
menu->hWnd = 0;
|
||||
|
||||
if (!(wFlags & TPM_NONOTIFY))
|
||||
|
@ -3531,7 +3531,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
|
|||
|
||||
if (menu->hWnd)
|
||||
{
|
||||
DestroyWindow( menu->hWnd );
|
||||
NtUserDestroyWindow( menu->hWnd );
|
||||
menu->hWnd = 0;
|
||||
|
||||
if (!(wFlags & TPM_NONOTIFY))
|
||||
|
@ -4269,7 +4269,7 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
|
|||
/* DestroyMenu should not destroy system menu popup owner */
|
||||
if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd)
|
||||
{
|
||||
DestroyWindow( lppop->hWnd );
|
||||
NtUserDestroyWindow( lppop->hWnd );
|
||||
lppop->hWnd = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1859,8 +1859,6 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
|||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_WINE_DESTROYWINDOW:
|
||||
return WIN_DestroyWindow( hwnd );
|
||||
case WM_WINE_SHOWWINDOW:
|
||||
if (is_desktop_window( hwnd )) return 0;
|
||||
return ShowWindow( hwnd, wparam );
|
||||
|
|
|
@ -116,57 +116,57 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
|
|||
hItem = 0;
|
||||
switch(lpmb->dwStyle & MB_TYPEMASK) {
|
||||
case MB_OK:
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
/* fall through */
|
||||
case MB_OKCANCEL:
|
||||
hItem = GetDlgItem(hwnd, IDOK);
|
||||
DestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
break;
|
||||
case MB_ABORTRETRYIGNORE:
|
||||
hItem = GetDlgItem(hwnd, IDABORT);
|
||||
DestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
break;
|
||||
case MB_YESNO:
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCANCEL));
|
||||
/* fall through */
|
||||
case MB_YESNOCANCEL:
|
||||
hItem = GetDlgItem(hwnd, IDYES);
|
||||
DestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
break;
|
||||
case MB_RETRYCANCEL:
|
||||
hItem = GetDlgItem(hwnd, IDRETRY);
|
||||
DestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
|
||||
break;
|
||||
case MB_CANCELTRYCONTINUE:
|
||||
hItem = GetDlgItem(hwnd, IDCANCEL);
|
||||
DestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDOK));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDABORT));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDIGNORE));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDYES));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDNO));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDRETRY));
|
||||
}
|
||||
|
||||
if (hItem) SetWindowLongW(hItem, GWL_STYLE, GetWindowLongW(hItem, GWL_STYLE) | WS_GROUP);
|
||||
|
@ -202,7 +202,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
|
|||
|
||||
/* Remove Help button unless MB_HELP supplied */
|
||||
if (!(lpmb->dwStyle & MB_HELP)) {
|
||||
DestroyWindow(GetDlgItem(hwnd, IDHELP));
|
||||
NtUserDestroyWindow(GetDlgItem(hwnd, IDHELP));
|
||||
}
|
||||
|
||||
/* Position everything */
|
||||
|
|
|
@ -35,18 +35,6 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* free_dce
|
||||
*
|
||||
* Free a class or window DCE.
|
||||
*/
|
||||
void free_dce( struct dce *dce, HWND hwnd )
|
||||
{
|
||||
/* FIXME: move callers to win32u */
|
||||
NtUserCallTwoParam( (UINT_PTR)dce, HandleToUlong(hwnd), NtUserFreeDCE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* invalidate_dce
|
||||
*
|
||||
|
|
|
@ -161,7 +161,7 @@
|
|||
@ stdcall DestroyIcon(long)
|
||||
@ stdcall DestroyMenu(long)
|
||||
# @ stub DestroyReasons
|
||||
@ stdcall DestroyWindow(long)
|
||||
@ stdcall DestroyWindow(long) NtUserDestroyWindow
|
||||
# @ stub DeviceEventWorker
|
||||
@ stdcall DialogBoxIndirectParamA(long ptr long ptr long)
|
||||
@ stdcall DialogBoxIndirectParamAorW(long ptr long ptr long long)
|
||||
|
|
|
@ -140,6 +140,11 @@ static void CDECL notify_ime( HWND hwnd, UINT param )
|
|||
if (ime_default) SendMessageW( ime_default, WM_IME_INTERNAL, param, HandleToUlong(hwnd) );
|
||||
}
|
||||
|
||||
void WINAPI unregister_imm( HWND hwnd )
|
||||
{
|
||||
imm_unregister_window( hwnd );
|
||||
}
|
||||
|
||||
static void CDECL free_win_ptr( WND *win )
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, win->text );
|
||||
|
@ -150,7 +155,9 @@ static void CDECL free_win_ptr( WND *win )
|
|||
static const struct user_callbacks user_funcs =
|
||||
{
|
||||
CopyImage,
|
||||
DestroyCaret,
|
||||
DestroyMenu,
|
||||
EndMenu,
|
||||
HideCaret,
|
||||
PostMessageW,
|
||||
SendInput,
|
||||
|
@ -161,12 +168,14 @@ static const struct user_callbacks user_funcs =
|
|||
ShowWindow,
|
||||
WaitForInputIdle,
|
||||
free_win_ptr,
|
||||
MENU_IsMenuActive,
|
||||
notify_ime,
|
||||
register_builtin_classes,
|
||||
MSG_SendInternalMessageTimeout,
|
||||
SCROLL_SetStandardScrollPainted,
|
||||
(void *)__wine_set_user_driver,
|
||||
set_window_pos,
|
||||
unregister_imm,
|
||||
};
|
||||
|
||||
static void WINAPI User32CallFreeIcon( ULONG *param, ULONG size )
|
||||
|
@ -227,6 +236,7 @@ static void thread_detach(void)
|
|||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
|
||||
exiting_thread_id = GetCurrentThreadId();
|
||||
NtUserCallNoParam( NtUserExitingThread );
|
||||
|
||||
WDML_NotifyThreadDetach();
|
||||
|
||||
|
|
|
@ -558,38 +558,6 @@ HWND WIN_GetFullHandle( HWND hwnd )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_SetOwner
|
||||
*
|
||||
* Change the owner of a window.
|
||||
*/
|
||||
static HWND WIN_SetOwner( HWND hwnd, HWND owner )
|
||||
{
|
||||
WND *win = WIN_GetPtr( hwnd );
|
||||
HWND ret = 0;
|
||||
|
||||
if (!win || win == WND_DESKTOP) return 0;
|
||||
if (win == WND_OTHER_PROCESS)
|
||||
{
|
||||
if (IsWindow(hwnd)) ERR( "cannot set owner %p on other process window %p\n", owner, hwnd );
|
||||
return 0;
|
||||
}
|
||||
SERVER_START_REQ( set_window_owner )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
req->owner = wine_server_user_handle( owner );
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
win->owner = wine_server_ptr_handle( reply->full_owner );
|
||||
ret = wine_server_ptr_handle( reply->prev_owner );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
WIN_ReleasePtr( win );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_SetStyle
|
||||
*
|
||||
|
@ -739,87 +707,6 @@ other_process:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_DestroyWindow
|
||||
*
|
||||
* Destroy storage associated to a window. "Internals" p.358
|
||||
*/
|
||||
LRESULT WIN_DestroyWindow( HWND hwnd )
|
||||
{
|
||||
WND *wndPtr;
|
||||
HWND *list;
|
||||
HMENU menu = 0, sys_menu;
|
||||
struct window_surface *surface;
|
||||
|
||||
TRACE("%p\n", hwnd );
|
||||
|
||||
/* destroy default IME window */
|
||||
if (win_set_flags( hwnd, 0, WIN_HAS_IME_WIN ) & WIN_HAS_IME_WIN)
|
||||
{
|
||||
TRACE("unregister IME window for %p\n", hwnd);
|
||||
imm_unregister_window( hwnd );
|
||||
}
|
||||
|
||||
/* free child windows */
|
||||
if ((list = WIN_ListChildren( hwnd )))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
if (WIN_IsCurrentThread( list[i] )) WIN_DestroyWindow( list[i] );
|
||||
else SendNotifyMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
|
||||
/* Unlink now so we won't bother with the children later on */
|
||||
SERVER_START_REQ( set_parent )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
req->parent = 0;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
/*
|
||||
* Send the WM_NCDESTROY to the window being destroyed.
|
||||
*/
|
||||
SendMessageW( hwnd, WM_NCDESTROY, 0, 0 );
|
||||
|
||||
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
|
||||
|
||||
/* free resources associated with the window */
|
||||
|
||||
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
|
||||
if ((wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
|
||||
menu = (HMENU)wndPtr->wIDmenu;
|
||||
sys_menu = wndPtr->hSysMenu;
|
||||
free_dce( wndPtr->dce, hwnd );
|
||||
wndPtr->dce = NULL;
|
||||
HeapFree( GetProcessHeap(), 0, wndPtr->text );
|
||||
wndPtr->text = NULL;
|
||||
HeapFree( GetProcessHeap(), 0, wndPtr->pScroll );
|
||||
wndPtr->pScroll = NULL;
|
||||
DestroyIcon( wndPtr->hIconSmall2 );
|
||||
surface = wndPtr->surface;
|
||||
wndPtr->surface = NULL;
|
||||
WIN_ReleasePtr( wndPtr );
|
||||
|
||||
if (menu) DestroyMenu( menu );
|
||||
if (sys_menu) DestroyMenu( sys_menu );
|
||||
if (surface)
|
||||
{
|
||||
register_window_surface( surface, NULL );
|
||||
window_surface_release( surface );
|
||||
}
|
||||
|
||||
USER_Driver->pDestroyWindow( hwnd );
|
||||
|
||||
free_window_handle( hwnd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_FixCoordinates
|
||||
*
|
||||
|
@ -1435,7 +1322,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
|
|||
return hwnd;
|
||||
|
||||
failed:
|
||||
WIN_DestroyWindow( hwnd );
|
||||
NtUserCallHwnd( hwnd, NtUserDestroyWindowHandle );
|
||||
SetThreadDpiAwarenessContext( context );
|
||||
return 0;
|
||||
}
|
||||
|
@ -1506,139 +1393,6 @@ HWND WINAPI DECLSPEC_HOTPATCH CreateWindowExW( DWORD exStyle, LPCWSTR className,
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* WIN_SendDestroyMsg
|
||||
*/
|
||||
static void WIN_SendDestroyMsg( HWND hwnd )
|
||||
{
|
||||
GUITHREADINFO info;
|
||||
|
||||
info.cbSize = sizeof(info);
|
||||
if (NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ))
|
||||
{
|
||||
if (hwnd == info.hwndCaret) DestroyCaret();
|
||||
if (hwnd == info.hwndActive) WINPOS_ActivateOtherWindow( hwnd );
|
||||
}
|
||||
|
||||
if (hwnd == NtUserGetClipboardOwner()) CLIPBOARD_ReleaseOwner( hwnd );
|
||||
|
||||
/*
|
||||
* Send the WM_DESTROY to the window.
|
||||
*/
|
||||
SendMessageW( 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(hwnd))
|
||||
{
|
||||
HWND* pWndArray;
|
||||
int i;
|
||||
|
||||
if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
|
||||
|
||||
for (i = 0; pWndArray[i]; i++)
|
||||
{
|
||||
if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, pWndArray );
|
||||
}
|
||||
else
|
||||
WARN("\tdestroyed itself while in WM_DESTROY!\n");
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DestroyWindow (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI DestroyWindow( HWND hwnd )
|
||||
{
|
||||
BOOL is_child;
|
||||
|
||||
if (!(hwnd = WIN_IsCurrentThread( hwnd )) || is_desktop_window( hwnd ))
|
||||
{
|
||||
SetLastError( ERROR_ACCESS_DENIED );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE("(%p)\n", hwnd);
|
||||
|
||||
/* Call hooks */
|
||||
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE;
|
||||
|
||||
if (MENU_IsMenuActive() == hwnd)
|
||||
EndMenu();
|
||||
|
||||
is_child = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) != 0;
|
||||
|
||||
if (is_child)
|
||||
{
|
||||
if (!USER_IsExitingThread( GetCurrentThreadId() ))
|
||||
send_parent_notify( hwnd, WM_DESTROY );
|
||||
}
|
||||
else if (!GetWindow( hwnd, GW_OWNER ))
|
||||
{
|
||||
HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
|
||||
/* FIXME: clean up palette - see "Internals" p.352 */
|
||||
}
|
||||
|
||||
if (!IsWindow(hwnd)) return TRUE;
|
||||
|
||||
/* Hide the window */
|
||||
if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)
|
||||
{
|
||||
/* Only child windows receive WM_SHOWWINDOW in DestroyWindow() */
|
||||
if (is_child)
|
||||
ShowWindow( hwnd, SW_HIDE );
|
||||
else
|
||||
NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW );
|
||||
}
|
||||
|
||||
if (!IsWindow(hwnd)) return TRUE;
|
||||
|
||||
/* Recursively destroy owned windows */
|
||||
|
||||
if (!is_child)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int i;
|
||||
BOOL got_one = FALSE;
|
||||
HWND *list = WIN_ListChildren( GetDesktopWindow() );
|
||||
if (list)
|
||||
{
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
if (GetWindow( list[i], GW_OWNER ) != hwnd) continue;
|
||||
if (WIN_IsCurrentThread( list[i] ))
|
||||
{
|
||||
DestroyWindow( list[i] );
|
||||
got_one = TRUE;
|
||||
continue;
|
||||
}
|
||||
WIN_SetOwner( list[i], 0 );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, list );
|
||||
}
|
||||
if (!got_one) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send destroy messages */
|
||||
|
||||
WIN_SendDestroyMsg( hwnd );
|
||||
if (!IsWindow( hwnd )) return TRUE;
|
||||
|
||||
/* Destroy the window storage */
|
||||
|
||||
WIN_DestroyWindow( hwnd );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CloseWindow (USER32.@)
|
||||
*/
|
||||
|
|
|
@ -45,7 +45,6 @@ extern HWND WIN_IsCurrentThread( HWND hwnd ) DECLSPEC_HIDDEN;
|
|||
extern UINT win_set_flags( HWND hwnd, UINT set_mask, UINT clear_mask ) DECLSPEC_HIDDEN;
|
||||
extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ) DECLSPEC_HIDDEN;
|
||||
extern BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWindow, RECT *rectClient ) DECLSPEC_HIDDEN;
|
||||
extern LRESULT WIN_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) DECLSPEC_HIDDEN;
|
||||
extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ) DECLSPEC_HIDDEN;
|
||||
extern HWND *WIN_ListChildren( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -288,3 +288,28 @@ BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd )
|
|||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* release_clipboard_owner
|
||||
*/
|
||||
void release_clipboard_owner( HWND hwnd )
|
||||
{
|
||||
HWND viewer = 0, owner = 0;
|
||||
|
||||
send_message( hwnd, WM_RENDERALLFORMATS, 0, 0 );
|
||||
|
||||
SERVER_START_REQ( release_clipboard )
|
||||
{
|
||||
req->owner = wine_server_user_handle( hwnd );
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
viewer = wine_server_ptr_handle( reply->viewer );
|
||||
owner = wine_server_ptr_handle( reply->owner );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (viewer)
|
||||
NtUserMessageCall( viewer, WM_DRAWCLIPBOARD, (WPARAM)owner, 0,
|
||||
0, FNID_SENDNOTIFYMESSAGE, FALSE );
|
||||
}
|
||||
|
|
|
@ -1190,6 +1190,7 @@ static const struct user_driver_funcs lazy_load_driver =
|
|||
.pUpdateDisplayDevices = loaderdrv_UpdateDisplayDevices,
|
||||
/* windowing functions */
|
||||
.pCreateDesktopWindow = loaderdrv_CreateDesktopWindow,
|
||||
.pDestroyWindow = nulldrv_DestroyWindow,
|
||||
.pFlashWindowEx = loaderdrv_FlashWindowEx,
|
||||
.pGetDC = loaderdrv_GetDC,
|
||||
.pSetCapture = nulldrv_SetCapture,
|
||||
|
|
|
@ -1162,6 +1162,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserCountClipboardFormats,
|
||||
NtUserDeferWindowPosAndBand,
|
||||
NtUserDestroyCursor,
|
||||
NtUserDestroyWindow,
|
||||
NtUserDrawIconEx,
|
||||
NtUserEndDeferWindowPosEx,
|
||||
NtUserEndPaint,
|
||||
|
|
|
@ -41,6 +41,8 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
|||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_WINE_DESTROYWINDOW:
|
||||
return destroy_window( hwnd );
|
||||
case WM_WINE_SETWINDOWPOS:
|
||||
if (is_desktop_window( hwnd )) return 0;
|
||||
return set_window_pos( (WINDOWPOS *)lparam, 0, 0 );
|
||||
|
|
|
@ -31,7 +31,9 @@ struct tagWND;
|
|||
struct user_callbacks
|
||||
{
|
||||
HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT );
|
||||
BOOL (WINAPI *pDestroyCaret)(void);
|
||||
BOOL (WINAPI *pDestroyMenu)( HMENU );
|
||||
BOOL (WINAPI *pEndMenu)(void);
|
||||
BOOL (WINAPI *pHideCaret)( HWND hwnd );
|
||||
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
|
||||
UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size );
|
||||
|
@ -42,6 +44,7 @@ struct user_callbacks
|
|||
BOOL (WINAPI *pShowWindow)( HWND, INT );
|
||||
DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD );
|
||||
void (CDECL *free_win_ptr)( struct tagWND *win );
|
||||
HWND (CDECL *is_menu_active)(void);
|
||||
void (CDECL *notify_ime)( HWND hwnd, UINT param );
|
||||
void (CDECL *register_builtin_classes)(void);
|
||||
LRESULT (WINAPI *send_ll_message)( DWORD, DWORD, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
|
||||
|
@ -50,6 +53,7 @@ struct user_callbacks
|
|||
BOOL (CDECL *set_window_pos)( HWND hwnd, HWND insert_after, UINT swp_flags,
|
||||
const RECT *window_rect, const RECT *client_rect,
|
||||
const RECT *valid_rects );
|
||||
void (WINAPI *unregister_imm)( HWND hwnd );
|
||||
};
|
||||
|
||||
#define WM_SYSTIMER 0x0118
|
||||
|
|
|
@ -4591,6 +4591,16 @@ static BOOL message_beep( UINT i )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static DWORD exiting_thread_id;
|
||||
|
||||
/**********************************************************************
|
||||
* is_exiting_thread
|
||||
*/
|
||||
BOOL is_exiting_thread( DWORD tid )
|
||||
{
|
||||
return tid == exiting_thread_id;
|
||||
}
|
||||
|
||||
static void thread_detach(void)
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
|
@ -4602,6 +4612,8 @@ static void thread_detach(void)
|
|||
|
||||
destroy_thread_windows();
|
||||
NtClose( thread_info->server_queue );
|
||||
|
||||
exiting_thread_id = 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -4618,6 +4630,9 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code )
|
|||
case NtUserReleaseCapture:
|
||||
return release_capture();
|
||||
/* temporary exports */
|
||||
case NtUserExitingThread:
|
||||
exiting_thread_id = GetCurrentThreadId();
|
||||
return 0;
|
||||
case NtUserThreadDetach:
|
||||
thread_detach();
|
||||
return 0;
|
||||
|
@ -4724,9 +4739,6 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
|
|||
return HandleToUlong( alloc_user_handle( (struct user_object *)arg1, arg2 ));
|
||||
case NtUserAllocWinProc:
|
||||
return (UINT_PTR)alloc_winproc( (WNDPROC)arg1, arg2 );
|
||||
case NtUserFreeDCE:
|
||||
free_dce( (struct dce *)arg1, UlongToHandle(arg2) );
|
||||
return 0;
|
||||
case NtUserFreeHandle:
|
||||
return (UINT_PTR)free_user_handle( UlongToHandle(arg1), arg2 );
|
||||
case NtUserGetHandlePtr:
|
||||
|
|
|
@ -834,7 +834,7 @@
|
|||
@ stub NtUserDestroyInputContext
|
||||
@ stub NtUserDestroyMenu
|
||||
@ stub NtUserDestroyPalmRejectionDelayZone
|
||||
@ stub NtUserDestroyWindow
|
||||
@ stdcall NtUserDestroyWindow(long)
|
||||
@ stub NtUserDisableImmersiveOwner
|
||||
@ stub NtUserDisableProcessWindowFiltering
|
||||
@ stub NtUserDisableThreadIme
|
||||
|
|
|
@ -199,6 +199,7 @@ struct unix_funcs
|
|||
INT x, INT y, INT cx, INT cy,
|
||||
UINT flags, UINT unk1, UINT unk2 );
|
||||
BOOL (WINAPI *pNtUserDestroyCursor)( HCURSOR cursor, ULONG arg );
|
||||
BOOL (WINAPI *pNtUserDestroyWindow)( HWND hwnd );
|
||||
BOOL (WINAPI *pNtUserDrawIconEx)( HDC hdc, INT x0, INT y0, HICON icon, INT width,
|
||||
INT height, UINT istep, HBRUSH hbr, UINT flags );
|
||||
BOOL (WINAPI *pNtUserEndDeferWindowPosEx)( HDWP hdwp, BOOL async );
|
||||
|
@ -286,6 +287,9 @@ struct unix_funcs
|
|||
struct window_surface *surface );
|
||||
};
|
||||
|
||||
/* clipboard.c */
|
||||
extern void release_clipboard_owner( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* cursoricon.c */
|
||||
extern HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_clip_cursor( RECT *rect ) DECLSPEC_HIDDEN;
|
||||
|
@ -327,6 +331,7 @@ extern UINT get_system_dpi(void) DECLSPEC_HIDDEN;
|
|||
extern int get_system_metrics( int index ) DECLSPEC_HIDDEN;
|
||||
extern UINT get_thread_dpi(void) DECLSPEC_HIDDEN;
|
||||
extern RECT get_virtual_screen_rect( UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_exiting_thread( DWORD tid ) DECLSPEC_HIDDEN;
|
||||
extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN;
|
||||
extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN;
|
||||
extern HMONITOR monitor_from_point( POINT pt, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
|
@ -344,6 +349,7 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN;
|
|||
struct tagWND;
|
||||
extern HDWP begin_defer_window_pos( INT count ) DECLSPEC_HIDDEN;
|
||||
extern void destroy_thread_windows(void) DECLSPEC_HIDDEN;
|
||||
extern LRESULT destroy_window( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern HWND get_desktop_window(void) DECLSPEC_HIDDEN;
|
||||
extern UINT get_dpi_for_window( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern HWND get_full_window_handle( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -3174,6 +3174,99 @@ BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* win_set_flags
|
||||
*
|
||||
* Set the flags of a window and return the previous value.
|
||||
*/
|
||||
static UINT win_set_flags( HWND hwnd, UINT set_mask, UINT clear_mask )
|
||||
{
|
||||
WND *win = get_win_ptr( hwnd );
|
||||
UINT ret;
|
||||
|
||||
if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return 0;
|
||||
ret = win->flags;
|
||||
win->flags = (ret & ~clear_mask) | set_mask;
|
||||
release_win_ptr( win );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* can_activate_window
|
||||
*
|
||||
* Check if we can activate the specified window.
|
||||
*/
|
||||
static BOOL can_activate_window( HWND hwnd )
|
||||
{
|
||||
LONG style;
|
||||
|
||||
if (!hwnd) return FALSE;
|
||||
style = get_window_long( hwnd, GWL_STYLE );
|
||||
if (!(style & WS_VISIBLE)) return FALSE;
|
||||
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
|
||||
return !(style & WS_DISABLED);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* activate_other_window
|
||||
*
|
||||
* Activates window other than hwnd.
|
||||
*/
|
||||
static void activate_other_window( HWND hwnd )
|
||||
{
|
||||
HWND hwnd_to, fg;
|
||||
|
||||
if ((get_window_long( hwnd, GWL_STYLE ) & WS_POPUP) &&
|
||||
(hwnd_to = get_window_relative( hwnd, GW_OWNER )))
|
||||
{
|
||||
hwnd_to = NtUserGetAncestor( hwnd_to, GA_ROOT );
|
||||
if (can_activate_window( hwnd_to )) goto done;
|
||||
}
|
||||
|
||||
hwnd_to = hwnd;
|
||||
for (;;)
|
||||
{
|
||||
if (!(hwnd_to = get_window_relative( hwnd_to, GW_HWNDNEXT ))) break;
|
||||
if (can_activate_window( hwnd_to )) goto done;
|
||||
}
|
||||
|
||||
hwnd_to = get_window_relative( get_desktop_window(), GW_CHILD );
|
||||
for (;;)
|
||||
{
|
||||
if (hwnd_to == hwnd)
|
||||
{
|
||||
hwnd_to = 0;
|
||||
break;
|
||||
}
|
||||
if (can_activate_window( hwnd_to )) goto done;
|
||||
if (!(hwnd_to = get_window_relative( hwnd_to, GW_HWNDNEXT ))) break;
|
||||
}
|
||||
|
||||
done:
|
||||
fg = NtUserGetForegroundWindow();
|
||||
TRACE( "win = %p fg = %p\n", hwnd_to, fg );
|
||||
if (!fg || hwnd == fg)
|
||||
{
|
||||
if (set_foreground_window( hwnd_to, FALSE )) return;
|
||||
}
|
||||
if (NtUserSetActiveWindow( hwnd_to )) NtUserSetActiveWindow( 0 );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* send_parent_notify
|
||||
*/
|
||||
static void send_parent_notify( HWND hwnd, UINT msg )
|
||||
{
|
||||
if ((get_window_long( hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
|
||||
!(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY))
|
||||
{
|
||||
HWND parent = get_parent( hwnd );
|
||||
if (parent && parent != get_desktop_window())
|
||||
send_message( parent, WM_PARENTNOTIFY,
|
||||
MAKEWPARAM( msg, get_window_long( hwnd, GWLP_ID )), (LPARAM)hwnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* update_window_state
|
||||
*
|
||||
|
@ -3260,6 +3353,226 @@ BOOL WINAPI NtUserFlashWindowEx( FLASHWINFO *info )
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* send_destroy_message
|
||||
*/
|
||||
static void send_destroy_message( HWND hwnd )
|
||||
{
|
||||
GUITHREADINFO info;
|
||||
|
||||
info.cbSize = sizeof(info);
|
||||
if (NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ))
|
||||
{
|
||||
if (hwnd == info.hwndCaret && user_callbacks) user_callbacks->pDestroyCaret();
|
||||
if (hwnd == info.hwndActive) activate_other_window( hwnd );
|
||||
}
|
||||
|
||||
if (hwnd == NtUserGetClipboardOwner()) release_clipboard_owner( hwnd );
|
||||
|
||||
send_message( 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 (is_window(hwnd))
|
||||
{
|
||||
HWND *children;
|
||||
int i;
|
||||
|
||||
if (!(children = list_window_children( 0, hwnd, NULL, 0 ))) return;
|
||||
|
||||
for (i = 0; children[i]; i++)
|
||||
{
|
||||
if (is_window( children[i] )) send_destroy_message( children[i] );
|
||||
}
|
||||
free( children );
|
||||
}
|
||||
else
|
||||
WARN( "\tdestroyed itself while in WM_DESTROY!\n" );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* free_window_handle
|
||||
*
|
||||
* Free a window handle.
|
||||
*/
|
||||
static void free_window_handle( HWND hwnd )
|
||||
{
|
||||
WND *win;
|
||||
|
||||
TRACE( "\n" );
|
||||
|
||||
if ((win = get_user_handle_ptr( hwnd, NTUSER_OBJ_WINDOW )) && win != OBJ_OTHER_PROCESS)
|
||||
{
|
||||
SERVER_START_REQ( destroy_window )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
wine_server_call( req );
|
||||
set_user_handle_ptr( hwnd, NULL );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
user_unlock();
|
||||
if (user_callbacks) user_callbacks->free_win_ptr( win );
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* destroy_window
|
||||
*/
|
||||
LRESULT destroy_window( HWND hwnd )
|
||||
{
|
||||
struct window_surface *surface;
|
||||
HMENU menu = 0, sys_menu;
|
||||
WND *win;
|
||||
HWND *children;
|
||||
|
||||
TRACE( "%p\n", hwnd );
|
||||
|
||||
/* destroy default IME window */
|
||||
if (win_set_flags( hwnd, 0, WIN_HAS_IME_WIN ) & WIN_HAS_IME_WIN)
|
||||
{
|
||||
TRACE("unregister IME window for %p\n", hwnd);
|
||||
if (user_callbacks) user_callbacks->unregister_imm( hwnd );
|
||||
}
|
||||
|
||||
/* free child windows */
|
||||
if ((children = list_window_children( 0, hwnd, NULL, 0 )))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; children[i]; i++)
|
||||
{
|
||||
if (is_current_thread_window( children[i] ))
|
||||
destroy_window( children[i] );
|
||||
else
|
||||
NtUserMessageCall( children[i], WM_WINE_DESTROYWINDOW, 0, 0,
|
||||
0, FNID_SENDNOTIFYMESSAGE, FALSE );
|
||||
}
|
||||
free( children );
|
||||
}
|
||||
|
||||
/* Unlink now so we won't bother with the children later on */
|
||||
SERVER_START_REQ( set_parent )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
req->parent = 0;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
send_message( hwnd, WM_NCDESTROY, 0, 0 );
|
||||
|
||||
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
|
||||
|
||||
/* free resources associated with the window */
|
||||
|
||||
if (!(win = get_win_ptr( hwnd )) || win == WND_OTHER_PROCESS) return 0;
|
||||
if ((win->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
|
||||
menu = (HMENU)win->wIDmenu;
|
||||
sys_menu = win->hSysMenu;
|
||||
free_dce( win->dce, hwnd );
|
||||
win->dce = NULL;
|
||||
NtUserDestroyCursor( win->hIconSmall2, 0 );
|
||||
surface = win->surface;
|
||||
win->surface = NULL;
|
||||
release_win_ptr( win );
|
||||
|
||||
NtUserDestroyMenu( menu );
|
||||
NtUserDestroyMenu( sys_menu );
|
||||
if (surface)
|
||||
{
|
||||
register_window_surface( surface, NULL );
|
||||
window_surface_release( surface );
|
||||
}
|
||||
|
||||
user_driver->pDestroyWindow( hwnd );
|
||||
|
||||
free_window_handle( hwnd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserDestroyWindow (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
|
||||
{
|
||||
BOOL is_child;
|
||||
|
||||
if (!(hwnd = is_current_thread_window( hwnd )) || is_desktop_window( hwnd ))
|
||||
{
|
||||
SetLastError( ERROR_ACCESS_DENIED );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "(%p)\n", hwnd );
|
||||
|
||||
if (call_hooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE;
|
||||
|
||||
if (user_callbacks && user_callbacks->is_menu_active() == hwnd)
|
||||
user_callbacks->pEndMenu();
|
||||
|
||||
is_child = (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) != 0;
|
||||
|
||||
if (is_child)
|
||||
{
|
||||
if (!is_exiting_thread( GetCurrentThreadId() ))
|
||||
send_parent_notify( hwnd, WM_DESTROY );
|
||||
}
|
||||
else if (!get_window_relative( hwnd, GW_OWNER ))
|
||||
{
|
||||
call_hooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
|
||||
/* FIXME: clean up palette - see "Internals" p.352 */
|
||||
}
|
||||
|
||||
if (!is_window( hwnd )) return TRUE;
|
||||
|
||||
/* Hide the window */
|
||||
if (get_window_long( hwnd, GWL_STYLE ) & WS_VISIBLE)
|
||||
{
|
||||
/* Only child windows receive WM_SHOWWINDOW in DestroyWindow() */
|
||||
if (is_child)
|
||||
NtUserShowWindow( hwnd, SW_HIDE );
|
||||
else
|
||||
NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW );
|
||||
}
|
||||
|
||||
if (!is_window( hwnd )) return TRUE;
|
||||
|
||||
/* Recursively destroy child windows */
|
||||
if (!is_child)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
BOOL got_one = FALSE;
|
||||
HWND *children;
|
||||
unsigned int i;
|
||||
|
||||
if (!(children = list_window_children( 0, get_desktop_window(), NULL, 0 ))) break;
|
||||
|
||||
for (i = 0; children[i]; i++)
|
||||
{
|
||||
if (get_window_relative( children[i], GW_OWNER ) != hwnd) continue;
|
||||
if (is_current_thread_window( children[i] ))
|
||||
{
|
||||
NtUserDestroyWindow( children[i] );
|
||||
got_one = TRUE;
|
||||
continue;
|
||||
}
|
||||
set_window_owner( children[i], 0 );
|
||||
}
|
||||
free( children );
|
||||
if (!got_one) break;
|
||||
}
|
||||
}
|
||||
|
||||
send_destroy_message( hwnd );
|
||||
if (!is_window( hwnd )) return TRUE;
|
||||
|
||||
destroy_window( hwnd );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* destroy_thread_windows
|
||||
*
|
||||
* Destroy all window owned by the current thread.
|
||||
|
@ -3329,6 +3642,8 @@ ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
|
|||
/* temporary exports */
|
||||
case NtUserCreateDesktopWindow:
|
||||
return user_driver->pCreateDesktopWindow( hwnd );
|
||||
case NtUserDestroyWindowHandle:
|
||||
return destroy_window( hwnd );
|
||||
case NtUserGetDummySurface:
|
||||
return (UINT_PTR)&dummy_surface;
|
||||
default:
|
||||
|
|
|
@ -783,6 +783,12 @@ BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg )
|
|||
return unix_funcs->pNtUserDestroyCursor( cursor, arg );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
return unix_funcs->pNtUserDestroyWindow( hwnd );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
|
||||
INT height, UINT istep, HBRUSH hbr, UINT flags )
|
||||
{
|
||||
|
|
|
@ -91,6 +91,7 @@ enum
|
|||
NtUserGetInputState,
|
||||
NtUserReleaseCapture,
|
||||
/* temporary exports */
|
||||
NtUserExitingThread,
|
||||
NtUserThreadDetach,
|
||||
};
|
||||
|
||||
|
@ -134,7 +135,6 @@ enum
|
|||
/* temporary exports */
|
||||
NtUserAllocHandle,
|
||||
NtUserAllocWinProc,
|
||||
NtUserFreeDCE,
|
||||
NtUserFreeHandle,
|
||||
NtUserGetHandlePtr,
|
||||
NtUserInvalidateDCE,
|
||||
|
@ -154,6 +154,7 @@ enum
|
|||
NtUserIsWindowVisible,
|
||||
/* temporary exports */
|
||||
NtUserCreateDesktopWindow,
|
||||
NtUserDestroyWindowHandle,
|
||||
NtUserGetDummySurface,
|
||||
};
|
||||
|
||||
|
@ -302,6 +303,7 @@ HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after, IN
|
|||
BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle );
|
||||
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg );
|
||||
BOOL WINAPI NtUserDestroyMenu( HMENU menu );
|
||||
BOOL WINAPI NtUserDestroyWindow( HWND hwnd );
|
||||
BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
|
||||
INT height, UINT istep, HBRUSH hbr, UINT flags );
|
||||
BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async );
|
||||
|
|
Loading…
Reference in New Issue