David Hedberg : shell32: Implement SHCreateShellItemArrayFromDataObject.
Alexandre Julliard
julliard at winehq.org
Mon Jul 26 13:22:36 CDT 2010
Module: wine
Branch: master
Commit: fd6d9cd8f211602b680cf438b2c342f5af0998ab
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fd6d9cd8f211602b680cf438b2c342f5af0998ab
Author: David Hedberg <david.hedberg at gmail.com>
Date: Mon Jul 26 11:54:05 2010 +0200
shell32: Implement SHCreateShellItemArrayFromDataObject.
---
dlls/shell32/shell32.spec | 1 +
dlls/shell32/shellitem.c | 52 ++++++++++++++++++++++++
dlls/shell32/tests/shlfolder.c | 87 ++++++++++++++++++++++++++++++++++++++++
include/shobjidl.idl | 1 +
4 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index 41cfde3..da8944a 100644
--- a/dlls/shell32/shell32.spec
+++ b/dlls/shell32/shell32.spec
@@ -335,6 +335,7 @@
@ stub SHCreateProcessAsUserW
@ stdcall SHCreateShellItem(ptr ptr ptr ptr)
@ stdcall SHCreateShellItemArray(ptr ptr long ptr ptr)
+@ stdcall SHCreateShellItemArrayFromDataObject(ptr ptr ptr)
@ stdcall SHCreateShellItemArrayFromShellItem(ptr ptr ptr)
@ stdcall SHEmptyRecycleBinA(long str long)
@ stdcall SHEmptyRecycleBinW(long wstr long)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c
index 68cd32e..5b01262 100644
--- a/dlls/shell32/shellitem.c
+++ b/dlls/shell32/shellitem.c
@@ -857,3 +857,55 @@ HRESULT WINAPI SHCreateShellItemArrayFromShellItem(IShellItem *psi, REFIID riid,
return ret;
}
+
+HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv)
+{
+ IShellItemArray *psia;
+ FORMATETC fmt;
+ STGMEDIUM medium;
+ HRESULT ret;
+
+ TRACE("%p, %s, %p\n", pdo, shdebugstr_guid(riid), ppv);
+
+ if(!pdo)
+ return E_INVALIDARG;
+
+ *ppv = NULL;
+
+ fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_HGLOBAL;
+
+ ret = IDataObject_GetData(pdo, &fmt, &medium);
+ if(SUCCEEDED(ret))
+ {
+ LPIDA pida = GlobalLock(medium.u.hGlobal);
+ LPCITEMIDLIST parent_pidl;
+ LPCITEMIDLIST *children;
+ UINT i;
+ TRACE("Converting %d objects.\n", pida->cidl);
+
+ parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
+
+ children = HeapAlloc(GetProcessHeap(), 0, sizeof(LPCITEMIDLIST)*pida->cidl);
+ for(i = 0; i < pida->cidl; i++)
+ children[i] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i+1]);
+
+ ret = SHCreateShellItemArray(parent_pidl, NULL, pida->cidl, children, (IShellItemArray**)&psia);
+
+ HeapFree(GetProcessHeap(), 0, children);
+
+ GlobalUnlock(medium.u.hGlobal);
+ GlobalFree(medium.u.hGlobal);
+ }
+
+ if(SUCCEEDED(ret))
+ {
+ ret = IShellItemArray_QueryInterface(psia, riid, ppv);
+ IShellItemArray_Release(psia);
+ }
+
+ return ret;
+}
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index b8c5da6..c2305c8 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -59,6 +59,7 @@ static HRESULT (WINAPI *pSHCreateItemFromIDList)(PCIDLIST_ABSOLUTE pidl, REFIID
static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**);
static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
static HRESULT (WINAPI *pSHCreateShellItemArray)(LPCITEMIDLIST,IShellFolder*,UINT,LPCITEMIDLIST*,IShellItemArray**);
+static HRESULT (WINAPI *pSHCreateShellItemArrayFromDataObject)(IDataObject*, REFIID, void **);
static HRESULT (WINAPI *pSHCreateShellItemArrayFromShellItem)(IShellItem*, REFIID, void **);
static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
@@ -82,6 +83,7 @@ static void init_function_pointers(void)
MAKEFUNC(SHCreateItemFromParsingName);
MAKEFUNC(SHCreateShellItem);
MAKEFUNC(SHCreateShellItemArray);
+ MAKEFUNC(SHCreateShellItemArrayFromDataObject);
MAKEFUNC(SHCreateShellItemArrayFromShellItem);
MAKEFUNC(SHGetFolderPathA);
MAKEFUNC(SHGetFolderPathAndSubDirA);
@@ -3112,6 +3114,91 @@ static void test_SHCreateShellItemArray(void)
else
skip("No SHCreateShellItemArrayFromShellItem.\n");
+ if(pSHCreateShellItemArrayFromDataObject)
+ {
+ IShellView *psv;
+
+ if(0)
+ {
+ /* Crashes under Windows 7 */
+ hr = pSHCreateShellItemArrayFromDataObject(NULL, &IID_IShellItemArray, NULL);
+ }
+ hr = pSHCreateShellItemArrayFromDataObject(NULL, &IID_IShellItemArray, (void**)&psia);
+ ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr);
+
+ hr = IShellFolder_CreateViewObject(psf, NULL, &IID_IShellView, (void**)&psv);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ if(SUCCEEDED(hr))
+ {
+ IEnumIDList *peidl;
+ IDataObject *pdo;
+ SHCONTF enum_flags;
+
+ enum_flags = SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN;
+ hr = IShellFolder_EnumObjects(psf, NULL, enum_flags, &peidl);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ if(SUCCEEDED(hr))
+ {
+ LPITEMIDLIST apidl[5];
+ UINT count, i;
+
+ for(count = 0; count < 5; count++)
+ if(IEnumIDList_Next(peidl, 1, &apidl[count], NULL) != S_OK)
+ break;
+ ok(count == 5, "Got %d\n", count);
+
+ if(count)
+ {
+ hr = IShellFolder_GetUIObjectOf(psf, NULL, count, (LPCITEMIDLIST*)apidl,
+ &IID_IDataObject, NULL, (void**)&pdo);
+ ok(hr == S_OK, "Got 0x%08x\n", hr);
+ if(SUCCEEDED(hr))
+ {
+ hr = pSHCreateShellItemArrayFromDataObject(pdo, &IID_IShellItemArray,
+ (void**)&psia);
+ ok(hr == S_OK, "Got 0x%08x\n", hr);
+ if(SUCCEEDED(hr))
+ {
+ UINT count_sia, i;
+ hr = IShellItemArray_GetCount(psia, &count_sia);
+ ok(count_sia == count, "Counts differ (%d, %d)\n", count, count_sia);
+ for(i = 0; i < count_sia; i++)
+ {
+ LPITEMIDLIST pidl_abs = ILCombine(pidl_testdir, apidl[i]);
+ IShellItem *psi;
+ hr = IShellItemArray_GetItemAt(psia, i, &psi);
+ ok(hr == S_OK, "Got 0x%08x\n", hr);
+ if(SUCCEEDED(hr))
+ {
+ LPITEMIDLIST pidl;
+ hr = pSHGetIDListFromObject((IUnknown*)psi, &pidl);
+ ok(hr == S_OK, "Got 0x%08x\n", hr);
+ ok(pidl != NULL, "pidl as NULL.\n");
+ ok(ILIsEqual(pidl, pidl_abs), "pidls differ.\n");
+ pILFree(pidl);
+ IShellItem_Release(psi);
+ }
+ pILFree(pidl_abs);
+ }
+
+ IShellItemArray_Release(psia);
+ }
+
+ IDataObject_Release(pdo);
+ }
+ for(i = 0; i < count; i++)
+ pILFree(apidl[i]);
+ }
+ else
+ skip("No files found - skipping test.\n");
+
+ IEnumIDList_Release(peidl);
+ }
+ IShellView_Release(psv);
+ }
+ }
+ else
+ skip("No SHCreateShellItemArrayFromDataObject.\n");
IShellFolder_Release(psf);
pILFree(pidl_testdir);
diff --git a/include/shobjidl.idl b/include/shobjidl.idl
index f4defe0..82d8aaf 100644
--- a/include/shobjidl.idl
+++ b/include/shobjidl.idl
@@ -519,6 +519,7 @@ cpp_quote("HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE
cpp_quote("HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv);")
cpp_quote("HRESULT WINAPI SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent, IShellFolder* psf, UINT cidl, PCUITEMID_CHILD_ARRAY ppidl, IShellItemArray **ppsiItemArray);")
cpp_quote("HRESULT WINAPI SHCreateShellItemArrayFromShellItem(IShellItem *psi, REFIID riid, void **ppv);")
+cpp_quote("HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv);")
/*****************************************************************************
* IShellItemFilter interface
More information about the wine-cvs
mailing list