From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/user32/user_main.c | 11 +++++-- dlls/user32/win.c | 56 ------------------------------------ dlls/user32/win.h | 1 - dlls/win32u/menu.c | 8 ++++++ dlls/win32u/ntuser_private.h | 5 ++-- dlls/win32u/sysparams.c | 5 ++-- dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 48 ++++++++++++++++++++++++++++++- include/ntuser.h | 2 +- 9 files changed, 72 insertions(+), 65 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 8e8c357bdcf..ff9b469dae6 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -140,9 +140,17 @@ static void CDECL notify_ime( HWND hwnd, UINT param ) if (ime_default) SendMessageW( ime_default, WM_IME_INTERNAL, param, HandleToUlong(hwnd) ); }
+static void CDECL free_win_ptr( WND *win ) +{ + HeapFree( GetProcessHeap(), 0, win->text ); + HeapFree( GetProcessHeap(), 0, win->pScroll ); + HeapFree( GetProcessHeap(), 0, win ); +} + static const struct user_callbacks user_funcs = { CopyImage, + DestroyMenu, HideCaret, PostMessageW, SendInput, @@ -152,6 +160,7 @@ static const struct user_callbacks user_funcs = ShowCaret, ShowWindow, WaitForInputIdle, + free_win_ptr, notify_ime, register_builtin_classes, MSG_SendInternalMessageTimeout, @@ -222,8 +231,6 @@ static void thread_detach(void) WDML_NotifyThreadDetach();
NtUserCallNoParam( NtUserThreadDetach ); - destroy_thread_windows(); - CloseHandle( thread_info->server_queue ); HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data ); HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index a21bdc62ed5..b57d6bd7566 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -820,62 +820,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) }
-/*********************************************************************** - * next_thread_window - */ -static WND *next_thread_window( HWND *hwnd ) -{ - return (WND *)NtUserCallOneParam( (UINT_PTR)hwnd, NtUserNextThreadWindow ); -} - - -/*********************************************************************** - * destroy_thread_windows - * - * Destroy all window owned by the current thread. - */ -void destroy_thread_windows(void) -{ - WND *win, *free_list = NULL, **free_list_ptr = &free_list; - HWND hwnd = 0; - - USER_Lock(); - while ((win = next_thread_window( &hwnd ))) - { - free_dce( win->dce, win->obj.handle ); - NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr ); - win->obj.handle = *free_list_ptr; - free_list_ptr = (WND **)&win->obj.handle; - } - if (free_list) - { - SERVER_START_REQ( destroy_window ) - { - req->handle = 0; /* destroy all thread windows */ - wine_server_call( req ); - } - SERVER_END_REQ; - } - USER_Unlock(); - - while ((win = free_list)) - { - free_list = win->obj.handle; - TRACE( "destroying %p\n", win ); - - if ((win->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD && win->wIDmenu) - DestroyMenu( UlongToHandle(win->wIDmenu) ); - if (win->hSysMenu) DestroyMenu( win->hSysMenu ); - if (win->surface) - { - register_window_surface( win->surface, NULL ); - window_surface_release( win->surface ); - } - HeapFree( GetProcessHeap(), 0, win ); - } -} - - /*********************************************************************** * WIN_FixCoordinates * diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 08bb16a0d4a..3e6885ab090 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -46,7 +46,6 @@ extern UINT win_set_flags( HWND hwnd, UINT set_mask, UINT clear_mask ) DECLSPEC_ 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 void destroy_thread_windows(void) 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; diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index abaca12047f..1e8410d347e 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -105,3 +105,11 @@ BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle ) free( accel ); return TRUE; } + +/********************************************************************** + * NtUserDestroyMenu (win32u.@) + */ +BOOL WINAPI NtUserDestroyMenu( HMENU menu ) +{ + return user_callbacks && user_callbacks->pDestroyMenu( menu ); +} diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index d6c3e681c2f..aa9b45b1542 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -26,10 +26,12 @@ #include "wine/list.h"
struct dce; +struct tagWND;
struct user_callbacks { HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); + BOOL (WINAPI *pDestroyMenu)( HMENU ); BOOL (WINAPI *pHideCaret)( HWND hwnd ); BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM ); UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size ); @@ -39,6 +41,7 @@ struct user_callbacks BOOL (WINAPI *pShowCaret)( HWND hwnd ); BOOL (WINAPI *pShowWindow)( HWND, INT ); DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD ); + void (CDECL *free_win_ptr)( struct tagWND *win ); 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 ); @@ -122,8 +125,6 @@ static inline BOOL is_broadcast( HWND hwnd ) return hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST; }
-WND *next_thread_window_ptr( HWND *hwnd ); - #define WM_IME_INTERNAL 0x287 #define IME_INTERNAL_ACTIVATE 0x17 #define IME_INTERNAL_DEACTIVATE 0x18 diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index f0ecb3b92bb..d9ddfe3400e 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4599,6 +4599,9 @@ static void thread_detach(void)
free( thread_info->key_state ); thread_info->key_state = 0; + + destroy_thread_windows(); + NtClose( thread_info->server_queue ); }
/*********************************************************************** @@ -4689,8 +4692,6 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) case 1: user_unlock(); return 0; default: user_check_not_lock(); return 0; } - case NtUserNextThreadWindow: - return (UINT_PTR)next_thread_window_ptr( (HWND *)arg ); case NtUserSetCallbacks: return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg ); default: diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 0c4e3b82f0f..516f4540315 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -343,6 +343,7 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN; /* window.c */ struct tagWND; extern HDWP begin_defer_window_pos( INT count ) DECLSPEC_HIDDEN; +extern void destroy_thread_windows(void) 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; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 079b4b0695f..a28b6ae9ebf 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -141,7 +141,7 @@ void *free_user_handle( HANDLE handle, unsigned int type ) /*********************************************************************** * next_thread_window */ -WND *next_thread_window_ptr( HWND *hwnd ) +static WND *next_thread_window_ptr( HWND *hwnd ) { struct user_object *ptr; WND *win; @@ -3259,6 +3259,52 @@ BOOL WINAPI NtUserFlashWindowEx( FLASHWINFO *info ) } }
+/*********************************************************************** + * destroy_thread_windows + * + * Destroy all window owned by the current thread. + */ +void destroy_thread_windows(void) +{ + WND *win, *free_list = NULL; + HWND hwnd = 0; + + user_lock(); + while ((win = next_thread_window_ptr( &hwnd ))) + { + free_dce( win->dce, win->obj.handle ); + set_user_handle_ptr( hwnd, NULL ); + win->obj.handle = free_list; + free_list = win; + } + if (free_list) + { + SERVER_START_REQ( destroy_window ) + { + req->handle = 0; /* destroy all thread windows */ + wine_server_call( req ); + } + SERVER_END_REQ; + } + user_unlock(); + + while ((win = free_list)) + { + free_list = win->obj.handle; + TRACE( "destroying %p\n", win ); + + if ((win->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD && win->wIDmenu) + NtUserDestroyMenu( UlongToHandle(win->wIDmenu) ); + if (win->hSysMenu) NtUserDestroyMenu( win->hSysMenu ); + if (win->surface) + { + register_window_surface( win->surface, NULL ); + window_surface_release( win->surface ); + } + if (user_callbacks) user_callbacks->free_win_ptr( win ); + } +} + /***************************************************************************** * NtUserCallHwnd (win32u.@) */ diff --git a/include/ntuser.h b/include/ntuser.h index 5e79083aa01..aeb3e9ae2cc 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -119,7 +119,6 @@ enum NtUserHandleInternalMessage, NtUserIncrementKeyStateCounter, NtUserLock, - NtUserNextThreadWindow, NtUserSetCallbacks, };
@@ -302,6 +301,7 @@ HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after, IN INT cx, INT cy, UINT flags, UINT unk1, UINT unk2 ); BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle ); BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg ); +BOOL WINAPI NtUserDestroyMenu( HMENU menu ); 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 );