From: Zebediah Figura zfigura@codeweavers.com
And simplify the control flow a bit while we're at it. --- dlls/shell32/shlview_cmenu.c | 275 +++++++++++++++++------------------ 1 file changed, 134 insertions(+), 141 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index eef089f4812..e00306ee2a9 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -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: