user32: Add support for a top-level message parent window in parallel to the desktop window.
This commit is contained in:
parent
c9370c44ba
commit
d71303e91c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -150,11 +150,18 @@ 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 ))
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue