shell32: Implement SHCreateShellItemArrayFromDataObject.

This commit is contained in:
David Hedberg 2010-07-26 11:54:05 +02:00 committed by Alexandre Julliard
parent bf1b56be10
commit fd6d9cd8f2
4 changed files with 141 additions and 0 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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