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

Zebediah Figura zfigura at codeweavers.com
Thu Jul 13 13:14:32 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.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/explorerframe/Makefile.in   |  2 +-
 dlls/explorerframe/taskbarlist.c | 79 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/dlls/explorerframe/Makefile.in b/dlls/explorerframe/Makefile.in
index 18d054c7fad..9f683f9c229 100644
--- a/dlls/explorerframe/Makefile.in
+++ b/dlls/explorerframe/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = explorerframe.dll
-IMPORTS   = uuid ole32 comctl32 shell32 user32
+IMPORTS   = uuid ole32 comctl32 shell32 user32 advapi32
 
 C_SRCS = \
 	explorerframe_main.c \
diff --git a/dlls/explorerframe/taskbarlist.c b/dlls/explorerframe/taskbarlist.c
index 26a2c1a4872..9e4edb8ed41 100644
--- a/dlls/explorerframe/taskbarlist.c
+++ b/dlls/explorerframe/taskbarlist.c
@@ -18,12 +18,56 @@
  *
  */
 
-#include "explorerframe_main.h"
-
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "explorerframe_main.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(explorerframe);
 
+typedef enum {
+    TASKBAR_ADDED = 1,
+    TASKBAR_DELETED = 2,
+} taskbar_state;
+
+static HRESULT (*pSetTaskbarState)(HWND hwnd, taskbar_state state);
+
+static HMODULE load_graphics_driver(void)
+{
+    static const WCHAR display_device_guid_propW[] = {
+        '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
+        'd','e','v','i','c','e','_','g','u','i','d',0 };
+    static const WCHAR key_pathW[] = {
+        'S','y','s','t','e','m','\\',
+        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+        'C','o','n','t','r','o','l','\\',
+        'V','i','d','e','o','\\','{',0};
+    static const WCHAR displayW[] = {'}','\\','0','0','0','0',0};
+    static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
+
+    HMODULE ret = 0;
+    HKEY hkey;
+    DWORD size;
+    WCHAR path[MAX_PATH];
+    WCHAR key[(sizeof(key_pathW) + sizeof(displayW)) / sizeof(WCHAR) + 40];
+    UINT guid_atom = HandleToULong( GetPropW( GetDesktopWindow(), display_device_guid_propW ));
+
+    if (!guid_atom) return 0;
+    memcpy( key, key_pathW, sizeof(key_pathW) );
+    if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0;
+    strcatW( key, displayW );
+    if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
+    size = sizeof(path);
+    if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) ret = LoadLibraryW( path );
+    RegCloseKey( hkey );
+    TRACE( "%s %p\n", debugstr_w(path), ret );
+    return ret;
+}
+
 struct taskbar_list
 {
     ITaskbarList4 ITaskbarList4_iface;
@@ -95,14 +139,28 @@ 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;
+
+    if (pSetTaskbarState)
+        return pSetTaskbarState(hwnd, TASKBAR_ADDED);
 
     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;
+
+    if (pSetTaskbarState)
+        return pSetTaskbarState(hwnd, TASKBAR_DELETED);
 
     return E_NOTIMPL;
 }
@@ -293,6 +351,7 @@ HRESULT TaskbarList_Constructor(IUnknown *outer, REFIID riid, void **taskbar_lis
 {
     struct taskbar_list *object;
     HRESULT hres;
+    HMODULE driver;
 
     TRACE("outer %p, riid %s, taskbar_list %p\n", outer, debugstr_guid(riid), taskbar_list);
 
@@ -317,6 +376,18 @@ HRESULT TaskbarList_Constructor(IUnknown *outer, REFIID riid, void **taskbar_lis
 
     TRACE("Created ITaskbarList4 %p\n", object);
 
+    if (!pSetTaskbarState)
+    {
+        driver = load_graphics_driver();
+        if (driver)
+        {
+            pSetTaskbarState = (void *)GetProcAddress(driver, "SetTaskbarState");
+            FreeModule(driver);
+        }
+        else
+            ERR("Failed to load graphics driver\n");
+    }
+
     hres = ITaskbarList4_QueryInterface(&object->ITaskbarList4_iface, riid, taskbar_list);
     ITaskbarList4_Release(&object->ITaskbarList4_iface);
     return hres;
-- 
2.13.2




More information about the wine-patches mailing list