[PATCH v2 1/3] explorerframe: Implement ITaskbarList::AddTab() and ::DeleteTab().

Zebediah Figura zfigura at codeweavers.com
Thu Jul 13 15:48:22 CDT 2017


ITaskbarList is an interface which allows applications to manually
control which windows appear on the taskbar, as well as what state
they are in (e.g. activated, flashing, progress bar). It also exposes
a function to "redirect" activation to other windows in a process.

In particular, when using multiple documents in Excel 2010, the
application will delete the button for its main window, and redirect
activation of dummy windows to the child windows containing the
documents.

Version 2 of this patch: use an internal window message instead of
calling the graphics driver directly. This is necessary because the
interface allows modifying the buttons attached to other processes'
windows.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/explorerframe/taskbarlist.c | 23 +++++++++++++++++++++--
 dlls/user32/driver.c             | 13 +++++++++++++
 dlls/user32/message.c            |  2 ++
 dlls/user32/spy.c                |  1 +
 dlls/user32/user_private.h       |  4 +++-
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/dlls/explorerframe/taskbarlist.c b/dlls/explorerframe/taskbarlist.c
index 26a2c1a4872..c7bfbecc75b 100644
--- a/dlls/explorerframe/taskbarlist.c
+++ b/dlls/explorerframe/taskbarlist.c
@@ -24,6 +24,13 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(explorerframe);
 
+#define WM_WINE_SETTASKBARSTATE 0x80000001
+
+typedef enum {
+    TASKBAR_ADDED = 1,
+    TASKBAR_DELETED = 2,
+} taskbar_state;
+
 struct taskbar_list
 {
     ITaskbarList4 ITaskbarList4_iface;
@@ -95,14 +102,26 @@ static HRESULT STDMETHODCALLTYPE taskbar_list_HrInit(ITaskbarList4 *iface)
 
 static HRESULT STDMETHODCALLTYPE taskbar_list_AddTab(ITaskbarList4 *iface, HWND hwnd)
 {
-    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);
+    struct taskbar_list *This = impl_from_ITaskbarList4(iface);
+
+    TRACE("%p (%p)\n", This, hwnd);
+
+    if (!IsWindow(hwnd)) return E_HANDLE;
+
+    return SendMessageW(hwnd, WM_WINE_SETTASKBARSTATE, TASKBAR_ADDED, 0);
 
     return E_NOTIMPL;
 }
 
 static HRESULT STDMETHODCALLTYPE taskbar_list_DeleteTab(ITaskbarList4 *iface, HWND hwnd)
 {
-    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);
+    struct taskbar_list *This = impl_from_ITaskbarList4(iface);
+
+    TRACE("%p (%p)\n", This, hwnd);
+
+    if (!IsWindow(hwnd)) return E_HANDLE;
+
+    return SendMessageW(hwnd, WM_WINE_SETTASKBARSTATE, TASKBAR_DELETED, 0);
 
     return E_NOTIMPL;
 }
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index d59a2eacf5d..5281520dcc0 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -140,6 +140,7 @@ static const USER_DRIVER *load_driver(void)
         GET_USER_FUNC(SetFocus);
         GET_USER_FUNC(SetLayeredWindowAttributes);
         GET_USER_FUNC(SetParent);
+        GET_USER_FUNC(SetTaskbarState);
         GET_USER_FUNC(SetWindowRgn);
         GET_USER_FUNC(SetWindowIcon);
         GET_USER_FUNC(SetWindowStyle);
@@ -440,6 +441,11 @@ static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
 {
 }
 
+static HRESULT CDECL nulldrv_SetTaskbarState( HWND hwnd, UINT state )
+{
+    return S_OK;
+}
+
 static void CDECL nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
 {
 }
@@ -542,6 +548,7 @@ static USER_DRIVER null_driver =
     nulldrv_SetFocus,
     nulldrv_SetLayeredWindowAttributes,
     nulldrv_SetParent,
+    nulldrv_SetTaskbarState,
     nulldrv_SetWindowRgn,
     nulldrv_SetWindowIcon,
     nulldrv_SetWindowStyle,
@@ -709,6 +716,11 @@ static void CDECL loaderdrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key,
     load_driver()->pSetLayeredWindowAttributes( hwnd, key, alpha, flags );
 }
 
+static HRESULT CDECL loaderdrv_SetTaskbarState( HWND hwnd, UINT state )
+{
+    return load_driver()->pSetTaskbarState( hwnd, state );
+}
+
 static void CDECL loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
 {
     load_driver()->pSetWindowRgn( hwnd, hrgn, redraw );
@@ -763,6 +775,7 @@ static USER_DRIVER lazy_load_driver =
     nulldrv_SetFocus,
     loaderdrv_SetLayeredWindowAttributes,
     nulldrv_SetParent,
+    loaderdrv_SetTaskbarState,
     loaderdrv_SetWindowRgn,
     nulldrv_SetWindowIcon,
     nulldrv_SetWindowStyle,
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 61a154389ed..26fcd8f8b26 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -1856,6 +1856,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
     {
     case WM_WINE_DESTROYWINDOW:
         return WIN_DestroyWindow( hwnd );
+    case WM_WINE_SETTASKBARSTATE:
+        return USER_Driver->pSetTaskbarState( hwnd, wparam );
     case WM_WINE_SETWINDOWPOS:
         if (is_desktop_window( hwnd )) return 0;
         return USER_SetWindowPos( (WINDOWPOS *)lparam );
diff --git a/dlls/user32/spy.c b/dlls/user32/spy.c
index ff8005194dc..2aa5704ddb9 100644
--- a/dlls/user32/spy.c
+++ b/dlls/user32/spy.c
@@ -1132,6 +1132,7 @@ static const char * const CCMMessageTypeNames[SPY_MAX_CCMMSGNUM + 1] =
 static const char * const WINEMessageTypeNames[SPY_MAX_WINEMSGNUM + 1] =
 {
     "WM_WINE_DESTROYWINDOW",
+    "WM_WINE_SETTASKBARSTATE",
     "WM_WINE_SETWINDOWPOS",
     "WM_WINE_SHOWWINDOW",
     "WM_WINE_SETPARENT",
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 052fdd8f1ea..8257c893712 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -44,6 +44,7 @@ struct window_surface;
 enum wine_internal_message
 {
     WM_WINE_DESTROYWINDOW = 0x80000000,
+    WM_WINE_SETTASKBARSTATE = 0x80000001, /* shared with explorerframe.dll */
     WM_WINE_SETWINDOWPOS,
     WM_WINE_SHOWWINDOW,
     WM_WINE_SETPARENT,
@@ -54,7 +55,7 @@ enum wine_internal_message
     WM_WINE_MOUSE_LL_HOOK,
     WM_WINE_CLIPCURSOR,
     WM_WINE_FIRST_DRIVER_MSG = 0x80001000,  /* range of messages reserved for the USER driver */
-    WM_WINE_LAST_DRIVER_MSG = 0x80001fff
+    WM_WINE_LAST_DRIVER_MSG = 0x80001fff,
 };
 
 typedef struct tagUSER_DRIVER {
@@ -99,6 +100,7 @@ typedef struct tagUSER_DRIVER {
     void   (CDECL *pSetFocus)(HWND);
     void   (CDECL *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
     void   (CDECL *pSetParent)(HWND,HWND,HWND);
+    HRESULT (CDECL *pSetTaskbarState)(HWND,UINT);
     void   (CDECL *pSetWindowRgn)(HWND,HRGN,BOOL);
     void   (CDECL *pSetWindowIcon)(HWND,UINT,HICON);
     void   (CDECL *pSetWindowStyle)(HWND,INT,STYLESTRUCT*);
-- 
2.13.2




More information about the wine-patches mailing list