Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/shell32/shell32_main.c | 112 +++++++++++++++++++++++++++++++++++-
dlls/shell32/tests/appbar.c | 32 +++++++++++
2 files changed, 143 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 99ee110b3d..034805f6fb 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -691,13 +691,123 @@ VOID WINAPI Printers_UnregisterWindow(HANDLE hClassPidl, HWND hwnd)
FIXME("(%p, %p) stub!\n", hClassPidl, hwnd);
}
+struct window_prop_store
+{
+ IPropertyStore IPropertyStore_iface;
+ LONG ref;
+};
+
+static inline struct window_prop_store *impl_from_IPropertyStore(IPropertyStore *iface)
+{
+ return CONTAINING_RECORD(iface, struct window_prop_store, IPropertyStore_iface);
+}
+
+static ULONG WINAPI window_prop_store_AddRef(IPropertyStore *iface)
+{
+ struct window_prop_store *store = impl_from_IPropertyStore(iface);
+ LONG ref = InterlockedIncrement(&store->ref);
+ TRACE("returning %d\n", ref);
+ return ref;
+}
+
+static ULONG WINAPI window_prop_store_Release(IPropertyStore *iface)
+{
+ struct window_prop_store *store = impl_from_IPropertyStore(iface);
+ LONG ref = InterlockedDecrement(&store->ref);
+ if (!ref) heap_free(store);
+ TRACE("returning %d\n", ref);
+ return ref;
+}
+
+static HRESULT WINAPI window_prop_store_QueryInterface(IPropertyStore *iface, REFIID iid, void **obj)
+{
+ struct window_prop_store *store = impl_from_IPropertyStore(iface);
+ TRACE("%p, %s, %p\n", iface, debugstr_guid(iid), obj);
+
+ if (!obj) return E_POINTER;
+ if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IPropertyStore))
+ {
+ *obj = &store->IPropertyStore_iface;
+ }
+ else
+ {
+ FIXME("no interface for %s\n", debugstr_guid(iid));
+ *obj = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown *)*obj);
+ return S_OK;
+}
+
+static HRESULT WINAPI window_prop_store_GetCount(IPropertyStore *iface, DWORD *count)
+{
+ FIXME("%p, %p\n", iface, count);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI window_prop_store_GetAt(IPropertyStore *iface, DWORD prop, PROPERTYKEY *key)
+{
+ FIXME("%p, %u,%p\n", iface, prop, key);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI window_prop_store_GetValue(IPropertyStore *iface, const PROPERTYKEY *key, PROPVARIANT *var)
+{
+ FIXME("%p, {%s,%u}, %p\n", iface, debugstr_guid(&key->fmtid), key->pid, var);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI window_prop_store_SetValue(IPropertyStore *iface, const PROPERTYKEY *key, const PROPVARIANT *var)
+{
+ FIXME("%p, {%s,%u}, %p\n", iface, debugstr_guid(&key->fmtid), key->pid, var);
+ return S_OK;
+}
+
+static HRESULT WINAPI window_prop_store_Commit(IPropertyStore *iface)
+{
+ FIXME("%p\n", iface);
+ return S_OK;
+}
+
+static const IPropertyStoreVtbl window_prop_store_vtbl =
+{
+ window_prop_store_QueryInterface,
+ window_prop_store_AddRef,
+ window_prop_store_Release,
+ window_prop_store_GetCount,
+ window_prop_store_GetAt,
+ window_prop_store_GetValue,
+ window_prop_store_SetValue,
+ window_prop_store_Commit
+};
+
+static HRESULT create_window_prop_store(IPropertyStore **obj)
+{
+ struct window_prop_store *store;
+
+ if (!(store = heap_alloc(sizeof(*store)))) return E_OUTOFMEMORY;
+ store->IPropertyStore_iface.lpVtbl = &window_prop_store_vtbl;
+ store->ref = 1;
+
+ *obj = &store->IPropertyStore_iface;
+ return S_OK;
+}
+
/*************************************************************************
* SHGetPropertyStoreForWindow [SHELL32.@]
*/
HRESULT WINAPI SHGetPropertyStoreForWindow(HWND hwnd, REFIID riid, void **ppv)
{
+ IPropertyStore *store;
+ HRESULT hr;
+
FIXME("(%p %p %p) stub!\n", hwnd, riid, ppv);
- return E_NOTIMPL;
+
+ if ((hr = create_window_prop_store( &store )) != S_OK) return hr;
+ hr = IPropertyStore_QueryInterface( store, riid, ppv );
+ IPropertyStore_Release( store );
+ return hr;
}
/*************************************************************************/
diff --git a/dlls/shell32/tests/appbar.c b/dlls/shell32/tests/appbar.c
index 1505a40aeb..229d616c6f 100644
--- a/dlls/shell32/tests/appbar.c
+++ b/dlls/shell32/tests/appbar.c
@@ -21,6 +21,8 @@
#include <windows.h>
#include "shellapi.h"
+#define COBJMACROS
+#include "propsys.h"
#include "wine/test.h"
@@ -30,6 +32,7 @@ static const CHAR testwindow_class[] = "testwindow";
static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD);
static HRESULT (WINAPI *pGetCurrentProcessExplicitAppUserModelID)(PWSTR*);
+static HRESULT (WINAPI *pSHGetPropertyStoreForWindow)(HWND, REFIID, void **);
typedef BOOL (*boolean_function)(void);
@@ -433,6 +436,33 @@ todo_wine
ok(appid == NULL, "got %p\n", appid);
}
+static void test_SHGetPropertyStoreForWindow(void)
+{
+ HRESULT hr;
+ IUnknown *unk;
+ IPropertyStore *store = NULL;
+
+ if (!pSHGetPropertyStoreForWindow)
+ {
+ win_skip("SHGetPropertyStoreForWindow() is not supported.\n");
+ return;
+ }
+
+ unk = (IUnknown *)0xdeadbeef;
+ hr = pSHGetPropertyStoreForWindow(GetDesktopWindow(), &IID_IDispatch, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+ ok(unk == NULL, "got %p\n", unk);
+
+ hr = pSHGetPropertyStoreForWindow(GetDesktopWindow(), &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IPropertyStore, (void **)&store);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ if (store) IPropertyStore_Release(store);
+ if (unk) IUnknown_Release(unk);
+}
+
START_TEST(appbar)
{
HMODULE huser32, hshell32;
@@ -441,10 +471,12 @@ START_TEST(appbar)
hshell32 = GetModuleHandleA("shell32.dll");
pMonitorFromWindow = (void*)GetProcAddress(huser32, "MonitorFromWindow");
pGetCurrentProcessExplicitAppUserModelID = (void*)GetProcAddress(hshell32, "GetCurrentProcessExplicitAppUserModelID");
+ pSHGetPropertyStoreForWindow = (void*)GetProcAddress(hshell32, "SHGetPropertyStoreForWindow");
register_testwindow_class();
test_setpos();
test_appbarget();
test_GetCurrentProcessExplicitAppUserModelID();
+ test_SHGetPropertyStoreForWindow();
}
--
2.20.1