shell32: Fix pasting from the shellview context menu.
Pasting from the shellview context menu is completely broken, as the desktop folder's BindToObject() always fails since the CIDA parent folder PIDL is an empty PIDL. The desktop shell folder doesn't support the ISFHelper interface either. Rather bind to each item's immediate parent, and copy each item individually. Also try get error handling to work a little better. Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
566454b9dc
commit
19379007e5
|
@ -1136,7 +1136,7 @@ static void DoNewFolder(ContextMenu *This, IShellView *view)
|
||||||
|
|
||||||
static BOOL DoPaste(ContextMenu *This)
|
static BOOL DoPaste(ContextMenu *This)
|
||||||
{
|
{
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = TRUE;
|
||||||
IDataObject * pda;
|
IDataObject * pda;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -1157,38 +1157,53 @@ static BOOL DoPaste(ContextMenu *This)
|
||||||
LPITEMIDLIST * apidl;
|
LPITEMIDLIST * apidl;
|
||||||
LPITEMIDLIST pidl;
|
LPITEMIDLIST pidl;
|
||||||
IShellFolder *psfFrom = NULL, *psfDesktop;
|
IShellFolder *psfFrom = NULL, *psfDesktop;
|
||||||
|
int i;
|
||||||
|
|
||||||
LPIDA lpcida = GlobalLock(medium.u.hGlobal);
|
LPIDA lpcida = GlobalLock(medium.u.hGlobal);
|
||||||
TRACE("cida=%p\n", lpcida);
|
TRACE("cida=%p\n", lpcida);
|
||||||
|
|
||||||
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
||||||
|
|
||||||
/* bind to the source shellfolder */
|
for (i = 0; bSuccess && i < lpcida->cidl; i++) {
|
||||||
SHGetDesktopFolder(&psfDesktop);
|
ITEMIDLIST *apidl_dir = NULL;
|
||||||
if(psfDesktop)
|
ITEMIDLIST *apidl_item;
|
||||||
{
|
|
||||||
IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
|
|
||||||
IShellFolder_Release(psfDesktop);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (psfFrom)
|
psfFrom = NULL;
|
||||||
{
|
/* bind to the source shellfolder */
|
||||||
/* get source and destination shellfolder */
|
SHGetDesktopFolder(&psfDesktop);
|
||||||
ISFHelper *psfhlpdst, *psfhlpsrc;
|
if(psfDesktop)
|
||||||
IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
|
|
||||||
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
|
|
||||||
|
|
||||||
/* do the copy/move */
|
|
||||||
if (psfhlpdst && psfhlpsrc)
|
|
||||||
{
|
{
|
||||||
ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
|
apidl_dir = ILClone(apidl[i]);
|
||||||
/* FIXME handle move
|
ILRemoveLastID(apidl_dir);
|
||||||
ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
|
apidl_item = ILFindLastID(apidl[i]);
|
||||||
*/
|
IShellFolder_BindToObject(psfDesktop, apidl_dir, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
|
||||||
|
IShellFolder_Release(psfDesktop);
|
||||||
}
|
}
|
||||||
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
|
|
||||||
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
|
if (psfFrom)
|
||||||
IShellFolder_Release(psfFrom);
|
{
|
||||||
|
/* get source and destination shellfolder */
|
||||||
|
ISFHelper *psfhlpdst, *psfhlpsrc;
|
||||||
|
IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
|
||||||
|
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
|
||||||
|
|
||||||
|
/* do the copy/move */
|
||||||
|
if (psfhlpdst && psfhlpsrc)
|
||||||
|
{
|
||||||
|
HRESULT hr = ISFHelper_CopyItems(psfhlpdst, psfFrom, 1, (LPCITEMIDLIST*)&apidl_item);
|
||||||
|
if (FAILED(hr))
|
||||||
|
bSuccess = FALSE;
|
||||||
|
/* FIXME handle move
|
||||||
|
ISFHelper_DeleteItems(psfhlpsrc, 1, &apidl_item);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
|
||||||
|
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
|
||||||
|
IShellFolder_Release(psfFrom);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bSuccess = FALSE;
|
||||||
|
SHFree(apidl_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||||
|
@ -1197,8 +1212,12 @@ static BOOL DoPaste(ContextMenu *This)
|
||||||
/* release the medium*/
|
/* release the medium*/
|
||||||
ReleaseStgMedium(&medium);
|
ReleaseStgMedium(&medium);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
bSuccess = FALSE;
|
||||||
IDataObject_Release(pda);
|
IDataObject_Release(pda);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
bSuccess = FALSE;
|
||||||
#if 0
|
#if 0
|
||||||
HGLOBAL hMem;
|
HGLOBAL hMem;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue