From d71303e91c13db58480ee56e75ea856e3f07cc39 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 25 Jun 2008 14:26:06 +0200 Subject: [PATCH] user32: Add support for a top-level message parent window in parallel to the desktop window. --- dlls/user32/user_main.c | 9 ++++++--- dlls/user32/user_private.h | 5 +++-- dlls/user32/win.c | 33 ++++++++++++++++++++++----------- dlls/user32/winstation.c | 7 ++++++- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 77913a8cf09..1d9e1933291 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -312,13 +312,16 @@ BOOL USER_IsExitingThread( DWORD tid ) */ static void thread_detach(void) { + struct user_thread_info *thread_info = get_user_thread_info(); + exiting_thread_id = GetCurrentThreadId(); WDML_NotifyThreadDetach(); - WIN_DestroyThreadWindows( get_user_thread_info()->desktop ); - CloseHandle( get_user_thread_info()->server_queue ); - HeapFree( GetProcessHeap(), 0, get_user_thread_info()->wmchar_data ); + if (thread_info->top_window) WIN_DestroyThreadWindows( thread_info->top_window ); + if (thread_info->msg_window) WIN_DestroyThreadWindows( thread_info->msg_window ); + CloseHandle( thread_info->server_queue ); + HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data ); exiting_thread_id = 0; } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 9ffdb21a155..8bb1ef9a5f3 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -204,9 +204,10 @@ struct user_thread_info HCURSOR cursor; /* Current cursor */ INT cursor_count; /* Cursor show count */ UINT active_hooks; /* Bitmap of active hooks */ - HWND desktop; /* Desktop window */ + HWND top_window; /* Desktop window */ + HWND msg_window; /* HWND_MESSAGE parent window */ - ULONG pad[10]; /* Available for more data */ + ULONG pad[9]; /* Available for more data */ }; struct hook_extra_info diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 1824a52b346..5252ceadd24 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -150,10 +150,17 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, { struct user_thread_info *thread_info = get_user_thread_info(); - if (!thread_info->desktop) thread_info->desktop = full_parent ? full_parent : handle; - else assert( full_parent == thread_info->desktop ); - if (full_parent && !USER_Driver->pCreateDesktopWindow( thread_info->desktop )) - ERR( "failed to create desktop window\n" ); + if (name == (LPCWSTR)DESKTOP_CLASS_ATOM) + { + if (!thread_info->top_window) thread_info->top_window = full_parent ? full_parent : handle; + else assert( full_parent == thread_info->top_window ); + if (full_parent && !USER_Driver->pCreateDesktopWindow( thread_info->top_window )) + ERR( "failed to create desktop window\n" ); + } + else /* HWND_MESSAGE parent */ + { + if (!thread_info->msg_window && !full_parent) thread_info->msg_window = handle; + } } USER_Lock(); @@ -978,13 +985,17 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags } else { + static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0}; + if ((cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) { WARN("No parent for child window\n" ); SetLastError(ERROR_TLW_WITH_WSCHILD); return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ } - if (className != (LPCWSTR)DESKTOP_CLASS_ATOM) /* are we creating the desktop itself? */ + /* are we creating the desktop or HWND_MESSAGE parent itself? */ + if (className != (LPCWSTR)DESKTOP_CLASS_ATOM && + (IS_INTRESOURCE(className) || strcmpiW( className, messageW ))) parent = GetDesktopWindow(); } @@ -1620,16 +1631,16 @@ HWND WINAPI GetDesktopWindow(void) { struct user_thread_info *thread_info = get_user_thread_info(); - if (thread_info->desktop) return thread_info->desktop; + if (thread_info->top_window) return thread_info->top_window; SERVER_START_REQ( get_desktop_window ) { req->force = 0; - if (!wine_server_call( req )) thread_info->desktop = reply->handle; + if (!wine_server_call( req )) thread_info->top_window = reply->handle; } SERVER_END_REQ; - if (!thread_info->desktop) + if (!thread_info->top_window) { USEROBJECTFLAGS flags; if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_FLAGS, &flags, @@ -1664,15 +1675,15 @@ HWND WINAPI GetDesktopWindow(void) SERVER_START_REQ( get_desktop_window ) { req->force = 1; - if (!wine_server_call( req )) thread_info->desktop = reply->handle; + if (!wine_server_call( req )) thread_info->top_window = reply->handle; } SERVER_END_REQ; } - if (!thread_info->desktop || !USER_Driver->pCreateDesktopWindow( thread_info->desktop )) + if (!thread_info->top_window || !USER_Driver->pCreateDesktopWindow( thread_info->top_window )) ERR( "failed to create desktop window\n" ); - return thread_info->desktop; + return thread_info->top_window; } diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index abee28656dc..57ce952f034 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -395,7 +395,12 @@ BOOL WINAPI SetThreadDesktop( HDESK handle ) ret = !wine_server_call_err( req ); } SERVER_END_REQ; - if (ret) get_user_thread_info()->desktop = 0; /* reset the desktop window */ + if (ret) /* reset the desktop windows */ + { + struct user_thread_info *thread_info = get_user_thread_info(); + thread_info->top_window = 0; + thread_info->msg_window = 0; + } return ret; } -- 2.11.4.GIT