shell32: Move DoPaste() up.
And simplify the control flow a bit while we're at it.
This commit is contained in:
parent
0bc47920d3
commit
35f5997075
1 changed files with 134 additions and 141 deletions
|
@ -311,6 +311,138 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut)
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT paste_pidls(ContextMenu *menu, ITEMIDLIST **pidls, unsigned int count)
|
||||
{
|
||||
IShellFolder *desktop_folder;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (FAILED(hr = SHGetDesktopFolder(&desktop_folder)))
|
||||
return hr;
|
||||
|
||||
for (unsigned int i = 0; SUCCEEDED(hr) && i < count; i++)
|
||||
{
|
||||
IShellFolder *folder = NULL;
|
||||
ITEMIDLIST *pidl_dir;
|
||||
ITEMIDLIST *pidl_item;
|
||||
|
||||
pidl_dir = ILClone(pidls[i]);
|
||||
ILRemoveLastID(pidl_dir);
|
||||
pidl_item = ILFindLastID(pidls[i]);
|
||||
hr = IShellFolder_BindToObject(desktop_folder, pidl_dir, NULL, &IID_IShellFolder, (void **)&folder);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
|
||||
|
||||
hr = IShellFolder_QueryInterface(menu->parent, &IID_ISFHelper, (void **)&psfhlpdst);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IShellFolder_QueryInterface(folder, &IID_ISFHelper, (void **)&psfhlpsrc);
|
||||
|
||||
if (psfhlpdst && psfhlpsrc)
|
||||
{
|
||||
hr = ISFHelper_CopyItems(psfhlpdst, folder, 1, (LPCITEMIDLIST*)&pidl_item);
|
||||
/* FIXME handle move
|
||||
ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item);
|
||||
*/
|
||||
}
|
||||
if (psfhlpdst)
|
||||
ISFHelper_Release(psfhlpdst);
|
||||
if (psfhlpsrc)
|
||||
ISFHelper_Release(psfhlpsrc);
|
||||
IShellFolder_Release(folder);
|
||||
}
|
||||
ILFree(pidl_dir);
|
||||
}
|
||||
|
||||
IShellFolder_Release(desktop_folder);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT do_paste(ContextMenu *menu)
|
||||
{
|
||||
IDataObject *data;
|
||||
HRESULT hr;
|
||||
STGMEDIUM medium;
|
||||
FORMATETC formatetc;
|
||||
HRESULT format_hr;
|
||||
|
||||
if (FAILED(hr = OleGetClipboard(&data)))
|
||||
return hr;
|
||||
|
||||
InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
|
||||
format_hr = IDataObject_GetData(data, &formatetc, &medium);
|
||||
if (SUCCEEDED(format_hr))
|
||||
{
|
||||
CIDA *cida = GlobalLock(medium.hGlobal);
|
||||
ITEMIDLIST **pidls;
|
||||
ITEMIDLIST *pidl;
|
||||
|
||||
if (cida)
|
||||
{
|
||||
pidls = _ILCopyCidaToaPidl(&pidl, cida);
|
||||
if (pidls)
|
||||
{
|
||||
hr = paste_pidls(menu, pidls, cida->cidl);
|
||||
_ILFreeaPidl(pidls, cida->cidl);
|
||||
SHFree(pidl);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
ReleaseStgMedium(&medium);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitFormatEtc(formatetc, CF_HDROP, TYMED_HGLOBAL);
|
||||
format_hr = IDataObject_GetData(data, &formatetc, &medium);
|
||||
if (SUCCEEDED(format_hr))
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
ITEMIDLIST **pidls;
|
||||
UINT count;
|
||||
|
||||
count = DragQueryFileW(medium.hGlobal, -1, NULL, 0);
|
||||
pidls = SHAlloc(count * sizeof(ITEMIDLIST*));
|
||||
if (pidls)
|
||||
{
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path));
|
||||
if (!(pidls[i] = ILCreateFromPathW(path)))
|
||||
{
|
||||
hr = E_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
hr = paste_pidls(menu, pidls, count);
|
||||
_ILFreeaPidl(pidls, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
ReleaseStgMedium(&medium);
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(format_hr))
|
||||
{
|
||||
ERR("Cannot paste any clipboard formats.\n");
|
||||
hr = format_hr;
|
||||
}
|
||||
|
||||
IDataObject_Release(data);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Properties_AddPropSheetCallback
|
||||
*
|
||||
|
@ -1205,145 +1337,6 @@ static void DoNewFolder(ContextMenu *This, IShellView *view)
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT paste_pidls(ContextMenu *This, ITEMIDLIST **pidls, UINT count)
|
||||
{
|
||||
IShellFolder *psfDesktop;
|
||||
UINT i;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
/* bind to the source shellfolder */
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
for (i = 0; SUCCEEDED(hr) && i < count; i++) {
|
||||
ITEMIDLIST *pidl_dir = NULL;
|
||||
ITEMIDLIST *pidl_item;
|
||||
IShellFolder *psfFrom = NULL;
|
||||
|
||||
pidl_dir = ILClone(pidls[i]);
|
||||
ILRemoveLastID(pidl_dir);
|
||||
pidl_item = ILFindLastID(pidls[i]);
|
||||
hr = IShellFolder_BindToObject(psfDesktop, pidl_dir, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
|
||||
|
||||
if (psfFrom)
|
||||
{
|
||||
/* get source and destination shellfolder */
|
||||
ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
|
||||
hr = IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
|
||||
|
||||
/* do the copy/move */
|
||||
if (psfhlpdst && psfhlpsrc)
|
||||
{
|
||||
hr = ISFHelper_CopyItems(psfhlpdst, psfFrom, 1, (LPCITEMIDLIST*)&pidl_item);
|
||||
/* FIXME handle move
|
||||
ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item);
|
||||
*/
|
||||
}
|
||||
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
|
||||
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
|
||||
IShellFolder_Release(psfFrom);
|
||||
}
|
||||
ILFree(pidl_dir);
|
||||
}
|
||||
|
||||
IShellFolder_Release(psfDesktop);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT DoPaste(ContextMenu *This)
|
||||
{
|
||||
IDataObject * pda;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hr = OleGetClipboard(&pda);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
STGMEDIUM medium;
|
||||
FORMATETC formatetc;
|
||||
HRESULT format_hr;
|
||||
|
||||
TRACE("pda=%p\n", pda);
|
||||
|
||||
/* Set the FORMATETC structure*/
|
||||
InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
|
||||
|
||||
/* Get the pidls from IDataObject */
|
||||
format_hr = IDataObject_GetData(pda,&formatetc,&medium);
|
||||
if(SUCCEEDED(format_hr))
|
||||
{
|
||||
LPITEMIDLIST * apidl;
|
||||
LPITEMIDLIST pidl;
|
||||
|
||||
LPIDA lpcida = GlobalLock(medium.hGlobal);
|
||||
TRACE("cida=%p\n", lpcida);
|
||||
if(lpcida)
|
||||
{
|
||||
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
||||
if (apidl)
|
||||
{
|
||||
hr = paste_pidls(This, apidl, lpcida->cidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
SHFree(pidl);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
ReleaseStgMedium(&medium);
|
||||
}
|
||||
|
||||
if(FAILED(format_hr))
|
||||
{
|
||||
InitFormatEtc(formatetc, CF_HDROP, TYMED_HGLOBAL);
|
||||
format_hr = IDataObject_GetData(pda,&formatetc,&medium);
|
||||
if(SUCCEEDED(format_hr))
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
UINT i, count;
|
||||
ITEMIDLIST **pidls;
|
||||
|
||||
TRACE("CF_HDROP=%p\n", medium.hGlobal);
|
||||
count = DragQueryFileW(medium.hGlobal, -1, NULL, 0);
|
||||
pidls = SHAlloc(count*sizeof(ITEMIDLIST*));
|
||||
if (pidls)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path));
|
||||
if ((pidls[i] = ILCreateFromPathW(path)) == NULL)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
hr = paste_pidls(This, pidls, count);
|
||||
_ILFreeaPidl(pidls, count);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
ReleaseStgMedium(&medium);
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(format_hr))
|
||||
{
|
||||
ERR("there are no supported and retrievable clipboard formats\n");
|
||||
hr = format_hr;
|
||||
}
|
||||
|
||||
IDataObject_Release(pda);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BackgroundMenu_InvokeCommand(
|
||||
IContextMenu3 *iface,
|
||||
LPCMINVOKECOMMANDINFO lpcmi)
|
||||
|
@ -1380,7 +1373,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand(
|
|||
}
|
||||
else if (!strcmp(lpcmi->lpVerb, "paste"))
|
||||
{
|
||||
DoPaste(This);
|
||||
do_paste(This);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1400,7 +1393,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand(
|
|||
break;
|
||||
|
||||
case FCIDM_SHVIEW_INSERT:
|
||||
DoPaste(This);
|
||||
do_paste(This);
|
||||
break;
|
||||
|
||||
case FCIDM_SHVIEW_PROPERTIES:
|
||||
|
|
Loading…
Add table
Reference in a new issue