Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes v2 -> v3: use lowercase letters for uuid(<hex>)
include/shobjidl.idl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/include/shobjidl.idl b/include/shobjidl.idl index c1a36ab5e93..b654d78c9cd 100644 --- a/include/shobjidl.idl +++ b/include/shobjidl.idl @@ -471,6 +471,36 @@ interface IShellItem2 : IShellItem [out] BOOL *pf); }
+/***************************************************************************** + * IShellItemImageFactory interface + */ +[ + object, + uuid(bcc18b79-ba16-442f-80c4-8a59c30c463b), + pointer_default(unique) +] +interface IShellItemImageFactory : IUnknown +{ + [v1_enum] enum _SIIGBF { + SIIGBF_RESIZETOFIT = 0x00000000, + SIIGBF_BIGGERSIZEOK = 0x00000001, + SIIGBF_MEMORYONLY = 0x00000002, + SIIGBF_ICONONLY = 0x00000004, + SIIGBF_THUMBNAILONLY = 0x00000008, + SIIGBF_INCACHEONLY = 0x00000010, + SIIGBF_CROPTOSQUARE = 0x00000020, + SIIGBF_WIDETHUMBNAILS = 0x00000040, + SIIGBF_ICONBACKGROUND = 0x00000080, + SIIGBF_SCALEUP = 0x00000100, + }; + typedef DWORD SIIGBF; + + HRESULT GetImage( + [in] SIZE size, + [in] SIIGBF flags, + [out] HBITMAP *phbm); +} + typedef [v1_enum] enum tagNWMF { NWMF_UNLOADING = 0x00000001, NWMF_USERINITED = 0x00000002,
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: mark test broken on Windows 7 v2 -> v3: remove erroneous todo_wine
dlls/shell32/tests/shlfolder.c | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 7b81ef98110..e26db317f0a 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -4482,6 +4482,51 @@ static void test_GetUIObject(void) Cleanup(); }
+static void test_IShellItemImageFactory(void) +{ + HRESULT ret; + IShellItem *shellitem; + LPITEMIDLIST pidl_desktop = NULL; + + if (!pSHCreateShellItem) + { + win_skip("SHCreateShellItem isn't available\n"); + return; + } + + ret = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl_desktop); + ok(ret == S_OK, "Got 0x%08lx\n", ret); + if (SUCCEEDED(ret)) + { + ret = pSHCreateShellItem(NULL, NULL, pidl_desktop, &shellitem); + ok(SUCCEEDED(ret), "SHCreateShellItem returned %lx\n", ret); + if (SUCCEEDED(ret)) + { + IShellItemImageFactory *siif; + ret = IShellItem_QueryInterface(shellitem, &IID_IShellItemImageFactory, (void **)&siif); + todo_wine ok(ret == S_OK, "QueryInterface returned %lx\n", ret); + if (SUCCEEDED(ret)) + { + HBITMAP hbm = NULL; + SIZE size = {32, 32}; + + ret = IShellItemImageFactory_GetImage(siif, size, SIIGBF_BIGGERSIZEOK, &hbm); + todo_wine ok(ret == S_OK || broken(ret == E_PENDING /* win7 */), "GetImage returned %lx\n", ret); + ok(FAILED(ret) == !hbm, "result = %lx but bitmap = %p\n", ret, hbm); + if (SUCCEEDED(ret) && hbm) + { + DWORD objtype = GetObjectType(hbm); + ok(objtype == OBJ_BITMAP, "Expected type OBJ_BITMAP, got %lu\n", objtype); + DeleteObject(hbm); + } + IShellItemImageFactory_Release(siif); + } + IShellItem_Release(shellitem); + } + ILFree(pidl_desktop); + } +} + static void test_CreateViewObject_contextmenu(void) { IShellFolder *desktop; @@ -5387,6 +5432,7 @@ START_TEST(shlfolder) test_ShellItemArrayEnumItems(); test_desktop_IPersist(); test_GetUIObject(); + test_IShellItemImageFactory(); test_CreateViewObject_contextmenu(); test_SHSimpleIDListFromPath(); test_ParseDisplayNamePBC();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110750
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w7u_adm (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w1064v1809 (32 bit report) ===
shell32: shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8)
=== w1064_tsign (32 bit report) ===
shell32: shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2)
=== w10pro64 (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10)
=== w1064v1809 (64 bit report) ===
shell32: shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2)
=== w1064 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w1064_tsign (64 bit report) ===
shell32: shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 4000000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4965: Test failed: Expected PIDL to be NULL shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_ar (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_he (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 4000000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4965: Test failed: Expected PIDL to be NULL shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_ja (64 bit report) ===
shell32: shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 4000000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4965: Test failed: Expected PIDL to be NULL shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_zh_CN (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes v2 -> v3: change iface lpVtbl initialization order to match struct order
dlls/shell32/shellitem.c | 50 ++++++++++++++++++++++++++++++++++ dlls/shell32/tests/shlfolder.c | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c index 0a3a76cbd6a..1a0bed55c1e 100644 --- a/dlls/shell32/shellitem.c +++ b/dlls/shell32/shellitem.c @@ -39,6 +39,7 @@ typedef struct _ShellItem { LONG ref; LPITEMIDLIST pidl; IPersistIDList IPersistIDList_iface; + IShellItemImageFactory IShellItemImageFactory_iface; } ShellItem;
typedef struct _CustomDestinationList { @@ -56,6 +57,11 @@ static inline ShellItem *impl_from_IPersistIDList( IPersistIDList *iface ) return CONTAINING_RECORD(iface, ShellItem, IPersistIDList_iface); }
+static inline ShellItem *impl_from_IShellItemImageFactory( IShellItemImageFactory *iface ) +{ + return CONTAINING_RECORD(iface, ShellItem, IShellItemImageFactory_iface); +} + static inline CustomDestinationList *impl_from_ICustomDestinationList( ICustomDestinationList *iface ) { return CONTAINING_RECORD(iface, CustomDestinationList, ICustomDestinationList_iface); @@ -79,6 +85,10 @@ static HRESULT WINAPI ShellItem_QueryInterface(IShellItem2 *iface, REFIID riid, { *ppv = &This->IPersistIDList_iface; } + else if (IsEqualIID(&IID_IShellItemImageFactory, riid)) + { + *ppv = &This->IShellItemImageFactory_iface; + } else { FIXME("not implemented for %s\n", shdebugstr_guid(riid)); *ppv = NULL; @@ -536,6 +546,45 @@ static const IPersistIDListVtbl ShellItem_IPersistIDList_Vtbl = { ShellItem_IPersistIDList_GetIDList };
+static HRESULT WINAPI ShellItem_IShellItemImageFactory_QueryInterface(IShellItemImageFactory *iface, + REFIID riid, void **ppv) +{ + ShellItem *This = impl_from_IShellItemImageFactory(iface); + return IShellItem2_QueryInterface(&This->IShellItem2_iface, riid, ppv); +} + +static ULONG WINAPI ShellItem_IShellItemImageFactory_AddRef(IShellItemImageFactory *iface) +{ + ShellItem *This = impl_from_IShellItemImageFactory(iface); + return IShellItem2_AddRef(&This->IShellItem2_iface); +} + +static ULONG WINAPI ShellItem_IShellItemImageFactory_Release(IShellItemImageFactory *iface) +{ + ShellItem *This = impl_from_IShellItemImageFactory(iface); + return IShellItem2_Release(&This->IShellItem2_iface); +} + +static HRESULT WINAPI ShellItem_IShellItemImageFactory_GetImage(IShellItemImageFactory *iface, + SIZE size, SIIGBF flags, HBITMAP *phbm) +{ + ShellItem *This = impl_from_IShellItemImageFactory(iface); + static int once; + + if (!once++) + FIXME("%p ({%lu, %lu} %lu %p): stub\n", This, size.cx, size.cy, flags, phbm); + + *phbm = NULL; + return E_NOTIMPL; +} + +static const IShellItemImageFactoryVtbl ShellItem_IShellItemImageFactory_Vtbl = { + ShellItem_IShellItemImageFactory_QueryInterface, + ShellItem_IShellItemImageFactory_AddRef, + ShellItem_IShellItemImageFactory_Release, + ShellItem_IShellItemImageFactory_GetImage, +}; +
HRESULT WINAPI IShellItem_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) { @@ -553,6 +602,7 @@ HRESULT WINAPI IShellItem_Constructor(IUnknown *pUnkOuter, REFIID riid, void **p This->ref = 1; This->pidl = NULL; This->IPersistIDList_iface.lpVtbl = &ShellItem_IPersistIDList_Vtbl; + This->IShellItemImageFactory_iface.lpVtbl = &ShellItem_IShellItemImageFactory_Vtbl;
ret = IShellItem2_QueryInterface(&This->IShellItem2_iface, riid, ppv); IShellItem2_Release(&This->IShellItem2_iface); diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index e26db317f0a..093e0add653 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -4504,7 +4504,7 @@ static void test_IShellItemImageFactory(void) { IShellItemImageFactory *siif; ret = IShellItem_QueryInterface(shellitem, &IID_IShellItemImageFactory, (void **)&siif); - todo_wine ok(ret == S_OK, "QueryInterface returned %lx\n", ret); + ok(ret == S_OK, "QueryInterface returned %lx\n", ret); if (SUCCEEDED(ret)) { HBITMAP hbm = NULL;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110751
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w7u_adm (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w1064v1809 (32 bit report) ===
shell32: shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8)
=== w1064_tsign (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64 (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w1064v1809 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w1064 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w1064_tsign (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_ar (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_he (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_ja (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 4000000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4965: Test failed: Expected PIDL to be NULL shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_zh_CN (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes
dlls/shell32/shellitem.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c index 1a0bed55c1e..6318636cf23 100644 --- a/dlls/shell32/shellitem.c +++ b/dlls/shell32/shellitem.c @@ -198,6 +198,27 @@ static HRESULT ShellItem_get_shellfolder(ShellItem *This, IBindCtx *pbc, IShellF return ret; }
+static HRESULT ShellItem_get_uiobject(ShellItem *This, REFIID riid, void **ppvOut) +{ + IShellFolder *psf_parent; + HRESULT ret; + + if (_ILIsDesktop(This->pidl)) + ret = SHGetDesktopFolder(&psf_parent); + else + ret = ShellItem_get_parent_shellfolder(This, &psf_parent); + + if (SUCCEEDED(ret)) + { + LPCITEMIDLIST pidl = ILFindLastID(This->pidl); + ret = IShellFolder_GetUIObjectOf(psf_parent, NULL, 1, &pidl, riid, NULL, ppvOut); + IShellFolder_Release(psf_parent); + } + else *ppvOut = NULL; + + return ret; +} + static HRESULT WINAPI ShellItem_BindToHandler(IShellItem2 *iface, IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut) { @@ -219,19 +240,7 @@ static HRESULT WINAPI ShellItem_BindToHandler(IShellItem2 *iface, IBindCtx *pbc, } else if (IsEqualGUID(rbhid, &BHID_SFUIObject)) { - IShellFolder *psf_parent; - if (_ILIsDesktop(This->pidl)) - ret = SHGetDesktopFolder(&psf_parent); - else - ret = ShellItem_get_parent_shellfolder(This, &psf_parent); - - if (SUCCEEDED(ret)) - { - LPCITEMIDLIST pidl = ILFindLastID(This->pidl); - ret = IShellFolder_GetUIObjectOf(psf_parent, NULL, 1, &pidl, riid, NULL, ppvOut); - IShellFolder_Release(psf_parent); - } - return ret; + return ShellItem_get_uiobject(This, riid, ppvOut); } else if (IsEqualGUID(rbhid, &BHID_DataObject)) {
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52673 Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes
dlls/shell32/Makefile.in | 4 +- dlls/shell32/shellitem.c | 179 ++++++++++++++++++++++++++++++++- dlls/shell32/tests/shlfolder.c | 2 +- 3 files changed, 179 insertions(+), 6 deletions(-)
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in index eeb6cd63d60..1ed28a761fa 100644 --- a/dlls/shell32/Makefile.in +++ b/dlls/shell32/Makefile.in @@ -1,8 +1,8 @@ EXTRADEFS = -D_SHELL32_ MODULE = shell32.dll IMPORTLIB = shell32 -IMPORTS = uuid shlwapi user32 gdi32 advapi32 -DELAYIMPORTS = ole32 oleaut32 shdocvw version comctl32 gdiplus +IMPORTS = uuid shlwapi user32 gdi32 advapi32 win32u +DELAYIMPORTS = ole32 oleaut32 shdocvw version comctl32 gdiplus windowscodecs
C_SRCS = \ appbar.c \ diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c index 6318636cf23..61edad6227c 100644 --- a/dlls/shell32/shellitem.c +++ b/dlls/shell32/shellitem.c @@ -31,9 +31,13 @@ #include "pidl.h" #include "shell32_main.h" #include "debughlp.h" +#include "ntuser.h" +#include "wincodec.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); + typedef struct _ShellItem { IShellItem2 IShellItem2_iface; LONG ref; @@ -574,17 +578,186 @@ static ULONG WINAPI ShellItem_IShellItemImageFactory_Release(IShellItemImageFact return IShellItem2_Release(&This->IShellItem2_iface); }
+static HRESULT ShellItem_get_icons(ShellItem *This, SIZE size, HICON *big_icon, HICON *small_icon) +{ + HRESULT hr; + IExtractIconW *ei; + WCHAR icon_file[MAX_PATH]; + INT source_index; + UINT gil_in_flags = 0, gil_out_flags; + INT iconsize; + + iconsize = min(size.cx, size.cy); + if (iconsize <= 0 || iconsize > 0x7fff) + iconsize = 0x7fff; + + hr = ShellItem_get_uiobject(This, &IID_IExtractIconW, (void **)&ei); + if (FAILED(hr)) goto done; + + hr = IExtractIconW_GetIconLocation(ei, gil_in_flags, icon_file, MAX_PATH, &source_index, &gil_out_flags); + if (FAILED(hr)) goto free_ei; + + if (!(gil_out_flags & GIL_NOTFILENAME)) + { + UINT ei_res; + + if (source_index == -1) + source_index = 0; /* special case for some control panel applications */ + + FIXME("%s %d\n", debugstr_w(icon_file), source_index); + ei_res = ExtractIconExW(icon_file, source_index, big_icon, small_icon, 1); + if (!ei_res || ei_res == (UINT)-1) + { + WARN("Failed to extract icon.\n"); + hr = E_FAIL; + } + } + else + { + hr = IExtractIconW_Extract(ei, icon_file, source_index, big_icon, small_icon, MAKELONG(iconsize, iconsize)); + } + +free_ei: + IExtractIconW_Release(ei); +done: + return hr; +} + +static HICON choose_best_icon(HICON *icons, UINT count, SIZE size_limit, SIZE *out_size) +{ + HICON best_icon = NULL; + SIZE best_size = {0, 0}; + UINT i; + + for (i = 0; i < count; i++) + { + SIZE size; + + if (!icons[i] || !NtUserGetIconSize(icons[i], 0, &size.cx, &size.cy)) continue; + size.cy /= 2; + + if (!best_icon || (best_size.cx < size.cx && size.cx <= size_limit.cx && + best_size.cy < size.cy && size.cy <= size_limit.cy)) + { + best_icon = icons[i]; + best_size = size; + } + } + + *out_size = best_size; + return best_icon; +} + +static HRESULT ShellItem_get_icon_bitmap(ShellItem *This, IWICImagingFactory *imgfactory, + SIZE size, SIIGBF flags, IWICBitmap **bitmap) +{ + HRESULT hr; + HICON icons[2] = { NULL, NULL }, best_icon; + SIZE best_icon_size; + UINT i; + + *bitmap = NULL; + + hr = ShellItem_get_icons(This, size, &icons[0], &icons[1]); + if (FAILED(hr)) return hr; + + best_icon = choose_best_icon(icons, ARRAY_SIZE(icons), size, &best_icon_size); + for (i = 0; i < ARRAY_SIZE(icons); i++) + if (icons[i] && icons[i] != best_icon) DeleteObject(icons[i]); + + if (!best_icon) return E_FAIL; + + hr = IWICImagingFactory_CreateBitmapFromHICON(imgfactory, best_icon, bitmap); + DeleteObject(best_icon); + return hr; +} + +static HRESULT convert_wicbitmapsource_to_gdi(IWICImagingFactory *imgfactory, IWICBitmapSource *bitmapsource, HBITMAP *gdibitmap) +{ + BITMAPINFOHEADER bmi; + HRESULT hr; + UINT width, height; + IWICBitmapSource *newsrc; + HDC dc; + HBITMAP bm; + void *bits; + + *gdibitmap = NULL; + + hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, bitmapsource, &newsrc); + if (FAILED(hr)) goto done; + + hr = IWICBitmapSource_GetSize(newsrc, &width, &height); + if (FAILED(hr)) goto free_newsrc; + + dc = GetDC(NULL); + if (!dc) + { + hr = E_FAIL; + goto free_newsrc; + } + + memset(&bmi, 0, sizeof(bmi)); + bmi.biSize = sizeof(bmi); + bmi.biWidth = width; + bmi.biHeight = -height; + bmi.biPlanes = 1; + bmi.biBitCount = 32; + bmi.biCompression = BI_RGB; + bmi.biSizeImage = width * height * 4; + + bm = CreateDIBSection(dc, (const BITMAPINFO *)&bmi, DIB_RGB_COLORS, &bits, NULL, 0); + ReleaseDC(NULL, dc); + if (!bm) + { + WARN("Cannot create bitmap.\n"); + hr = E_FAIL; + goto free_newsrc; + } + + hr = IWICBitmapSource_CopyPixels(newsrc, NULL, bmi.biWidth * 4, bmi.biSizeImage, bits); + if (FAILED(hr)) + { + DeleteObject(bm); + goto free_newsrc; + } + + hr = S_OK; + *gdibitmap = bm; + +free_newsrc: + IWICBitmapSource_Release(newsrc); +done: + return hr; +} + static HRESULT WINAPI ShellItem_IShellItemImageFactory_GetImage(IShellItemImageFactory *iface, SIZE size, SIIGBF flags, HBITMAP *phbm) { ShellItem *This = impl_from_IShellItemImageFactory(iface); + HRESULT hr; + IWICImagingFactory *imgfactory; + IWICBitmap *bitmap = NULL; static int once;
if (!once++) - FIXME("%p ({%lu, %lu} %lu %p): stub\n", This, size.cx, size.cy, flags, phbm); + FIXME("%p ({%lu, %lu} %lu %p): partial stub\n", This, size.cx, size.cy, flags, phbm);
- *phbm = NULL; - return E_NOTIMPL; + if (flags != SIIGBF_BIGGERSIZEOK) return E_NOTIMPL; + + hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &imgfactory); + if (SUCCEEDED(hr)) + { + hr = ShellItem_get_icon_bitmap(This, imgfactory, size, flags, &bitmap); + if (SUCCEEDED(hr)) + { + hr = convert_wicbitmapsource_to_gdi(imgfactory, (IWICBitmapSource *)bitmap, phbm); + IWICBitmap_Release(bitmap); + } + IWICImagingFactory_Release(imgfactory); + } + + return hr; }
static const IShellItemImageFactoryVtbl ShellItem_IShellItemImageFactory_Vtbl = { diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 093e0add653..1a36a7b1bd1 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -4511,7 +4511,7 @@ static void test_IShellItemImageFactory(void) SIZE size = {32, 32};
ret = IShellItemImageFactory_GetImage(siif, size, SIIGBF_BIGGERSIZEOK, &hbm); - todo_wine ok(ret == S_OK || broken(ret == E_PENDING /* win7 */), "GetImage returned %lx\n", ret); + ok(ret == S_OK || broken(ret == E_PENDING /* win7 */), "GetImage returned %lx\n", ret); ok(FAILED(ret) == !hbm, "result = %lx but bitmap = %p\n", ret, hbm); if (SUCCEEDED(ret) && hbm) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110753
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w7u_adm (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w7u_el (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8000)
=== w1064v1809 (32 bit report) ===
shell32: shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 8)
=== w1064_tsign (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10)
=== w10pro64 (32 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w1064v1809 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w1064 (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w1064_2qxl (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w1064_tsign (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000)
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2)
=== w10pro64_ar (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_he (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 2) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_ja (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 40000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: CREATE: expected notification type 2, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== w10pro64_zh_CN (64 bit report) ===
shell32: shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 4000000) shlfolder.c:4957: Test failed: RMDIR: expected notification type 10, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 10) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4957: Test failed: MKDIR: expected notification type 8, got: 40000 shlfolder.c:4964: Test failed: GetDisplayNameOf failed: 0x80070057 shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3) shlfolder.c:4974: Test failed: Didn't expect a WM_USER_NOTIFY message (event: 3)
=== debian11 (64 bit WoW report) ===
shell32: shelllink.c:815: Test failed: failed to delete link 'C:\users\winetest\Temp\test.lnk' (32)