Alexandre Julliard : user32: Add support for a top-level message parent window in parallel to the desktop window .
Alexandre Julliard
julliard at winehq.org
Wed Jun 25 16:43:37 CDT 2008
Module: wine
Branch: master
Commit: d71303e91c13db58480ee56e75ea856e3f07cc39
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d71303e91c13db58480ee56e75ea856e3f07cc39
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jun 25 14:26:06 2008 +0200
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 77913a8..1d9e193 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 9ffdb21..8bb1ef9 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 1824a52..5252cea 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 abee286..57ce952 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;
}
More information about the wine-cvs
mailing list