Implementation of Get/SetShellWindow()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Changelog:
* Implement SetShellWindow(), SetShellWindowEx() and GetShellWindow()
   to make taskbar of explorer work in desktop mode

-- 
Martin Fuchs
martin-fuchs@gmx.net


Index: dlls/user/focus.c
===================================================================
RCS file: /home/wine/wine/dlls/user/focus.c,v
retrieving revision 1.5
diff -u -r1.5 focus.c
--- dlls/user/focus.c	5 Sep 2003 23:08:29 -0000	1.5
+++ dlls/user/focus.c	28 Sep 2003 09:08:47 -0000
@@ -84,6 +84,12 @@
         return TRUE;
     }
 
+    if (hwnd == GetShellWindow())
+    {
+	TRACE("set_active_window(%#x): ignored for shell window\n", hwnd);
+	return TRUE;
+    }
+
     /* call CBT hook chain */
     cbt.fMouse     = mouse;
     cbt.hWndActive = previous;
@@ -344,3 +350,65 @@
     SERVER_END_REQ;
     return ret;
 }
+
+
+/***********************************************************************
+*		SetShellWindowEx (USER32.@)
+* hwndShell =    Progman[Program Manager]
+*                |-> SHELLDLL_DefView
+* hwndListView = |   |-> SysListView32
+*                |   |   |-> tooltips_class32
+*                |   |
+*                |   |-> SysHeader32
+*                |
+*                |-> ProxyTarget
+*/
+BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
+{
+    BOOL ret;
+
+    SERVER_START_REQ(set_shell_windows)
+    {
+	req->shell_window = hwndShell;
+	req->shell_listview = hwndListView;
+
+	ret = !wine_server_call_err(req);
+    }
+    SERVER_END_REQ;
+
+    if (ret)
+    {
+	if (hwndListView && hwndListView!=hwndShell)
+	    SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+
+	SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+    }
+
+    return ret;
+}
+
+/*******************************************************************
+*		SetShellWindow (USER32.@)
+*/
+BOOL WINAPI SetShellWindow(HWND hwndShell)
+{  
+    return SetShellWindowEx(hwndShell, hwndShell);
+}
+
+/*******************************************************************
+*		GetShellWindow (USER32.@)
+*/
+HWND WINAPI GetShellWindow()
+{
+    HWND hwndShell = 0;
+
+    SERVER_START_REQ(get_shell_windows)
+    {
+	if (!wine_server_call_err(req))
+	    hwndShell = reply->shell_window;
+    }
+    SERVER_END_REQ;
+
+    return hwndShell;
+}
+
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.83
diff -u -r1.83 server_protocol.h
--- include/wine/server_protocol.h	16 Sep 2003 01:07:22 -0000	1.83
+++ include/wine/server_protocol.h	28 Sep 2003 09:08:49 -0000
@@ -3115,6 +3115,32 @@
 #define OPEN_TOKEN_AS_SELF  2
 
 
+
+struct set_shell_windows_request
+{
+    struct request_header __header;
+    user_handle_t	shell_window;
+    user_handle_t	shell_listview;
+};
+struct set_shell_windows_reply
+{
+    struct reply_header __header;
+};
+
+
+struct get_shell_windows_request
+{
+    struct request_header __header;
+};
+struct get_shell_windows_reply
+{
+    struct reply_header __header;
+    user_handle_t	shell_window;
+	user_handle_t	shell_listview;
+};
+
+
+
 enum request
 {
     REQ_new_process,
@@ -3295,6 +3321,8 @@
     REQ_get_next_hook,
     REQ_set_clipboard_info,
     REQ_open_token,
+    REQ_set_shell_windows,
+    REQ_get_shell_windows,
     REQ_NB_REQUESTS
 };
 
@@ -3480,6 +3508,8 @@
     struct get_next_hook_request get_next_hook_request;
     struct set_clipboard_info_request set_clipboard_info_request;
     struct open_token_request open_token_request;
+    struct set_shell_windows_request set_shell_windows_request;
+    struct get_shell_windows_request get_shell_windows_request;
 };
 union generic_reply
 {
@@ -3663,6 +3693,8 @@
     struct get_next_hook_reply get_next_hook_reply;
     struct set_clipboard_info_reply set_clipboard_info_reply;
     struct open_token_reply open_token_reply;
+    struct set_shell_windows_reply set_shell_windows_reply;
+    struct get_shell_windows_reply get_shell_windows_reply;
 };
 
 #define SERVER_PROTOCOL_VERSION 121
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.82
diff -u -r1.82 protocol.def
--- server/protocol.def	16 Sep 2003 01:07:21 -0000	1.82
+++ server/protocol.def	28 Sep 2003 09:08:52 -0000
@@ -2182,3 +2182,18 @@
 @END
 #define OPEN_TOKEN_THREAD   1
 #define OPEN_TOKEN_AS_SELF  2
+
+
+/* Set the shell windows */
+@REQ(set_shell_windows)
+    user_handle_t	shell_window;	/* handle to the new shell window */
+    user_handle_t	shell_listview;	/* handle to the new shell listview window */
+@END
+
+/* Get the shell windows */
+@REQ(get_shell_windows)
+@REPLY
+    user_handle_t	shell_window;	/* handle to the shell window */
+	user_handle_t	shell_listview;	/* handle to the shell listview window */
+@END
+
Index: server/request.h
===================================================================
RCS file: /home/wine/wine/server/request.h,v
retrieving revision 1.88
diff -u -r1.88 request.h
--- server/request.h	19 Aug 2003 03:08:17 -0000	1.88
+++ server/request.h	28 Sep 2003 09:08:53 -0000
@@ -281,6 +281,8 @@
 DECL_HANDLER(get_next_hook);
 DECL_HANDLER(set_clipboard_info);
 DECL_HANDLER(open_token);
+DECL_HANDLER(set_shell_windows);
+DECL_HANDLER(get_shell_windows);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -465,6 +467,8 @@
     (req_handler)req_get_next_hook,
     (req_handler)req_set_clipboard_info,
     (req_handler)req_open_token,
+    (req_handler)req_set_shell_windows,
+    (req_handler)req_get_shell_windows,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
Index: server/trace.c
===================================================================
RCS file: /home/wine/wine/server/trace.c,v
retrieving revision 1.179
diff -u -r1.179 trace.c
--- server/trace.c	16 Sep 2003 01:07:21 -0000	1.179
+++ server/trace.c	28 Sep 2003 09:08:54 -0000
@@ -2504,6 +2504,22 @@
     fprintf( stderr, " token=%p", req->token );
 }
 
+static void dump_set_shell_windows_request( const struct set_shell_windows_request *req )
+{
+    fprintf( stderr, " shell_window=%p,", req->shell_window );
+    fprintf( stderr, " shell_listview=%p", req->shell_listview );
+}
+
+static void dump_get_shell_windows_request( const struct get_shell_windows_request *req )
+{
+}
+
+static void dump_get_shell_windows_reply( const struct get_shell_windows_reply *req )
+{
+    fprintf( stderr, " shell_window=%p,", req->shell_window );
+    fprintf( stderr, " shell_listview=%p", req->shell_listview );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -2683,6 +2699,8 @@
     (dump_func)dump_get_next_hook_request,
     (dump_func)dump_set_clipboard_info_request,
     (dump_func)dump_open_token_request,
+    (dump_func)dump_set_shell_windows_request,
+    (dump_func)dump_get_shell_windows_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -2864,6 +2882,8 @@
     (dump_func)dump_get_next_hook_reply,
     (dump_func)dump_set_clipboard_info_reply,
     (dump_func)dump_open_token_reply,
+    (dump_func)0,
+    (dump_func)dump_get_shell_windows_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -3045,6 +3065,8 @@
     "get_next_hook",
     "set_clipboard_info",
     "open_token",
+    "set_shell_windows",
+    "get_shell_windows",
 };
 
 /* ### make_requests end ### */
Index: server/window.c
===================================================================
RCS file: /home/wine/wine/server/window.c,v
retrieving revision 1.23
diff -u -r1.23 window.c
--- server/window.c	5 Sep 2003 23:15:41 -0000	1.23
+++ server/window.c	28 Sep 2003 09:08:55 -0000
@@ -82,6 +82,15 @@
 static struct window *top_window;  /* top-level (desktop) window */
 
 
+/* globally stored shell window pointers */
+
+static struct window* shell_window = 0;
+static struct window* shell_listview = 0;
+
+/* process, which currently owns the shell window */
+static struct process* shell_window_owner = 0;
+
+
 /* retrieve a pointer to a window from its handle */
 inline static struct window *get_window( user_handle_t handle )
 {
@@ -245,6 +254,23 @@
         if (win->paint_count) inc_queue_paint_count( win->thread, -win->paint_count );
         queue_cleanup_window( win->thread, win->handle );
     }
+
+	/* reset shell window pointers, if the corresponding window is destroyed */
+	if (win == shell_window)
+	{
+		shell_window = 0;
+
+		/* release the shell window owner pointer */
+		if (shell_window_owner)
+		{
+			release_object(shell_window_owner);
+			shell_window_owner = 0;
+		}
+	}
+
+	if (win == shell_listview)
+		shell_listview = 0;
+
     free_user_handle( win->handle );
     destroy_properties( win );
     unlink_window( win );
@@ -454,9 +480,10 @@
 
         if (!(parent = get_window( req->parent ))) return;
         if (req->owner && !(owner = get_window( req->owner ))) return;
-        if (owner == top_window) owner = NULL;
-        else if (owner && parent != top_window)
-        {
+
+	if (owner == top_window) owner = NULL;
+	else if (owner && parent != top_window)
+	{
             /* an owned window must be created as top-level */
             set_error( STATUS_ACCESS_DENIED );
             return;
@@ -499,6 +526,7 @@
             }
         }
     }
+
     link_window( win, parent, previous );
 }
 
@@ -819,4 +847,37 @@
         data++;
         count--;
     }
+}
+
+
+/* set the shell windows */
+DECL_HANDLER(set_shell_windows)
+{
+    /* test if we are permitted to change the shell window */
+    if (shell_window_owner && current->process!=shell_window_owner)
+    {
+	set_error(STATUS_ACCESS_DENIED);
+    }
+    else
+    {
+	shell_window = req->shell_window? get_window(req->shell_window): 0;
+	shell_listview = req->shell_listview? get_window(req->shell_listview): 0;
+    
+	/* We only have to set shell_window_owner if there was none previously.
+	It can't be the case, that we have to owerwrite the owner with
+	another process, since we already checked for this case above. */
+	if (shell_window && !shell_window_owner)
+	{
+	    /* request shell window for the calling process */
+	    shell_window_owner = (struct process*)grab_object(current->process);
+	}
+    }
+}
+
+
+/* get the shell windows */
+DECL_HANDLER(get_shell_windows)
+{
+    reply->shell_window = shell_window? shell_window->handle: 0;
+    reply->shell_listview = shell_listview? shell_listview->handle: 0;
 }
Index: windows/winpos.c
===================================================================
RCS file: /home/wine/wine/windows/winpos.c,v
retrieving revision 1.146
diff -u -r1.146 winpos.c
--- windows/winpos.c	5 Sep 2003 23:15:39 -0000	1.146
+++ windows/winpos.c	28 Sep 2003 09:08:57 -0000
@@ -67,7 +67,6 @@
 
 /* ----- internal variables ----- */
 
-static HWND hGlobalShellWindow=0; /*the shell*/
 static HWND hGlobalTaskmanWindow=0;
 static HWND hGlobalProgmanWindow=0;
 
@@ -632,27 +631,6 @@
 }
 
 
-/*******************************************************************
- *		SetShellWindow (USER32.@)
- */
-HWND WINAPI SetShellWindow(HWND hwndshell)
-{   WARN("(hWnd=%p) semi stub\n",hwndshell );
-
-    hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
-    return hGlobalShellWindow;
-}
-
-
-/*******************************************************************
- *		GetShellWindow (USER32.@)
- */
-HWND WINAPI GetShellWindow(void)
-{   WARN("(hWnd=%p) semi stub\n",hGlobalShellWindow );
-
-    return hGlobalShellWindow;
-}
-
-
 /***********************************************************************
  *		BringWindowToTop (USER32.@)
  */
@@ -1049,7 +1027,9 @@
     style = GetWindowLongW( hwnd, GWL_STYLE );
     if (!(style & WS_VISIBLE)) return FALSE;
     if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
-    return !(style & WS_DISABLED);
+    if (style & WS_DISABLED) return FALSE;
+    if (hwnd == GetShellWindow()) return FALSE;
+    return TRUE;
 }
 
 
@@ -1362,25 +1342,6 @@
 HWND WINAPI GetProgmanWindow(void)
 {
 	return hGlobalProgmanWindow;
-}
-
-/***********************************************************************
- *		SetShellWindowEx (USER32.@)
- * hwndProgman =  Progman[Program Manager]
- *                |-> SHELLDLL_DefView
- * hwndListView = |   |-> SysListView32
- *                |   |   |-> tooltips_class32
- *                |   |
- *                |   |-> SysHeader32
- *                |
- *                |-> ProxyTarget
- */
-HWND WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
-{
-	FIXME("%p %p stub\n",hwndProgman ,hwndListView );
-	hGlobalShellWindow = hwndProgman;
-	return hGlobalShellWindow;
-
 }
 
 /***********************************************************************

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux