Module: wine Branch: master Commit: fd6d9cd8f211602b680cf438b2c342f5af0998ab URL: http://source.winehq.org/git/wine.git/?a=commit;h=fd6d9cd8f211602b680cf438b2...
Author: David Hedberg david.hedberg@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