mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 08:51:29 +00:00
[shell32]
- Implement cut and paste shortcut - Patch by Huw Campbell - CORE-7548 svn path=/trunk/; revision=61049
This commit is contained in:
parent
5fd4d650b5
commit
315db4c011
|
@ -159,7 +159,7 @@ HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMA
|
|||
*/
|
||||
|
||||
/* number of supported formats */
|
||||
#define MAX_FORMATS 4
|
||||
#define MAX_FORMATS 5
|
||||
|
||||
class IDataObjectImpl :
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
|
@ -169,11 +169,13 @@ private:
|
|||
LPITEMIDLIST pidl;
|
||||
LPITEMIDLIST * apidl;
|
||||
UINT cidl;
|
||||
DWORD dropeffect;
|
||||
|
||||
FORMATETC pFormatEtc[MAX_FORMATS];
|
||||
UINT cfShellIDList;
|
||||
UINT cfFileNameA;
|
||||
UINT cfFileNameW;
|
||||
UINT cfPreferredDropEffect;
|
||||
public:
|
||||
IDataObjectImpl();
|
||||
~IDataObjectImpl();
|
||||
|
@ -200,9 +202,11 @@ IDataObjectImpl::IDataObjectImpl()
|
|||
pidl = NULL;
|
||||
apidl = NULL;
|
||||
cidl = 0;
|
||||
dropeffect = 0;
|
||||
cfShellIDList = 0;
|
||||
cfFileNameA = 0;
|
||||
cfFileNameW = 0;
|
||||
cfPreferredDropEffect = 0;
|
||||
}
|
||||
|
||||
IDataObjectImpl::~IDataObjectImpl()
|
||||
|
@ -219,14 +223,17 @@ HRESULT WINAPI IDataObjectImpl::Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl
|
|||
if (pidl == NULL || apidl == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
cidl = cidlx;
|
||||
dropeffect = DROPEFFECT_COPY;
|
||||
|
||||
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
|
||||
cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
|
||||
cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
|
||||
cfPreferredDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW);
|
||||
InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL);
|
||||
InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
|
||||
InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL);
|
||||
InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL);
|
||||
InitFormatEtc(pFormatEtc[4], cfPreferredDropEffect, TYMED_HGLOBAL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -261,6 +268,10 @@ HRESULT WINAPI IDataObjectImpl::GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pme
|
|||
if (cidl < 1) return(E_UNEXPECTED);
|
||||
pmedium->hGlobal = RenderFILENAMEW(pidl, apidl, cidl);
|
||||
}
|
||||
else if (pformatetcIn->cfFormat == cfPreferredDropEffect)
|
||||
{
|
||||
pmedium->hGlobal = RenderPREFEREDDROPEFFECT(dropeffect);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("-- expected clipformat not implemented\n");
|
||||
|
@ -311,6 +322,19 @@ HRESULT WINAPI IDataObjectImpl::GetCanonicalFormatEtc(LPFORMATETC pformatectIn,
|
|||
|
||||
HRESULT WINAPI IDataObjectImpl::SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
|
||||
{
|
||||
if (pformatetc->cfFormat == cfPreferredDropEffect)
|
||||
{
|
||||
const DWORD *src = (const DWORD *)GlobalLock(pmedium->hGlobal);
|
||||
if (src != 0)
|
||||
{
|
||||
dropeffect = *src;
|
||||
GlobalUnlock(pmedium->hGlobal);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("Error setting data");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
FIXME("(%p)->()\n", this);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ class CDefaultContextMenu :
|
|||
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu);
|
||||
UINT BuildShellItemContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
|
||||
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi);
|
||||
HRESULT DoPasteLink(LPCMINVOKECOMMANDINFO lpcmi);
|
||||
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
|
||||
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
|
||||
HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi);
|
||||
|
@ -950,77 +951,70 @@ CDefaultContextMenu::DoPaste(
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
IDataObject *pda;
|
||||
if (OleGetClipboard(&pda) != S_OK)
|
||||
return E_FAIL;
|
||||
CComPtr<IDataObject> pda;
|
||||
hr = OleGetClipboard(&pda);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
STGMEDIUM medium;
|
||||
FORMATETC formatetc;
|
||||
InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
|
||||
hr = pda->GetData(&formatetc, &medium);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
pda->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
return hr;
|
||||
|
||||
/* lock the handle */
|
||||
LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
|
||||
if (!lpcida)
|
||||
{
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* convert the data into pidl */
|
||||
LPITEMIDLIST pidl;
|
||||
LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
||||
|
||||
if (!apidl)
|
||||
return E_FAIL;
|
||||
|
||||
IShellFolder *psfDesktop;
|
||||
if (FAILED(SHGetDesktopFolder(&psfDesktop)))
|
||||
{
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
CComPtr<IShellFolder> psfFrom = NULL;
|
||||
CComPtr<IShellFolder> psfTarget = NULL;
|
||||
CComPtr<ISFHelper> psfhlpdst;
|
||||
CComPtr<ISFHelper> psfhlpsrc;
|
||||
bool bCopy = TRUE;
|
||||
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
||||
/* Find source folder */
|
||||
IShellFolder *psfFrom = NULL;
|
||||
if (_ILIsDesktop(pidl))
|
||||
{
|
||||
/* use desktop shellfolder */
|
||||
psfFrom = psfDesktop;
|
||||
}
|
||||
else if (FAILED(psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom))))
|
||||
else
|
||||
{
|
||||
ERR("no IShellFolder\n");
|
||||
|
||||
psfDesktop->Release();
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
|
||||
return E_FAIL;
|
||||
hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("no IShellFolder\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find target folder */
|
||||
IShellFolder *psfTarget = NULL;
|
||||
if (m_Dcm.cidl)
|
||||
{
|
||||
psfDesktop->Release();
|
||||
hr = m_Dcm.psf->BindToObject(m_Dcm.apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfTarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
IPersistFolder2 *ppf2 = NULL;
|
||||
CComPtr<IPersistFolder2> ppf2 = NULL;
|
||||
LPITEMIDLIST pidl;
|
||||
|
||||
/* cidl is zero due to explorer view */
|
||||
|
@ -1028,7 +1022,6 @@ CDefaultContextMenu::DoPaste(
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ppf2->GetCurFolder(&pidl);
|
||||
ppf2->Release();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (_ILIsDesktop(pidl))
|
||||
|
@ -1041,7 +1034,7 @@ CDefaultContextMenu::DoPaste(
|
|||
/* retrieve target desktop folder */
|
||||
hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfTarget));
|
||||
}
|
||||
TRACE("psfTarget %x %p, Desktop %u\n", hr, psfTarget, _ILIsDesktop(pidl));
|
||||
TRACE("psfTarget %x %p, Desktop %u\n", hr, psfTarget.p, _ILIsDesktop(pidl));
|
||||
ILFree(pidl);
|
||||
}
|
||||
}
|
||||
|
@ -1050,72 +1043,53 @@ CDefaultContextMenu::DoPaste(
|
|||
if (FAILED(hr))
|
||||
{
|
||||
ERR("no IShellFolder\n");
|
||||
|
||||
psfFrom->Release();
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
|
||||
return E_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get source and destination shellfolder */
|
||||
ISFHelper *psfhlpdst;
|
||||
if (FAILED(psfTarget->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlpdst))))
|
||||
hr = psfTarget->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlpdst));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("no IID_ISFHelper for destination\n");
|
||||
|
||||
psfFrom->Release();
|
||||
psfTarget->Release();
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
|
||||
return E_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ISFHelper *psfhlpsrc;
|
||||
if (FAILED(psfFrom->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlpsrc))))
|
||||
hr = psfFrom->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlpsrc));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("no IID_ISFHelper for source\n");
|
||||
|
||||
psfhlpdst->Release();
|
||||
psfFrom->Release();
|
||||
psfTarget->Release();
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
return E_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* FIXXME
|
||||
* do we want to perform a copy or move ???
|
||||
*/
|
||||
hr = psfhlpdst->CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
|
||||
FORMATETC formatetc2;
|
||||
STGMEDIUM medium2;
|
||||
InitFormatEtc(formatetc2, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT), TYMED_HGLOBAL);
|
||||
|
||||
psfhlpdst->Release();
|
||||
psfhlpsrc->Release();
|
||||
psfFrom->Release();
|
||||
psfTarget->Release();
|
||||
if SUCCEEDED(pda->GetData(&formatetc2, &medium2))
|
||||
{
|
||||
DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
|
||||
if (pdwFlag)
|
||||
{
|
||||
TRACE("Current drop effect flag %i\n", *pdwFlag);
|
||||
if (*pdwFlag & DROPEFFECT_MOVE)
|
||||
bCopy = FALSE;
|
||||
}
|
||||
GlobalUnlock(medium2.hGlobal);
|
||||
}
|
||||
|
||||
hr = psfhlpdst->CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
|
||||
|
||||
NotifyShellViewWindow(lpcmi, TRUE);
|
||||
|
||||
cleanup:
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
pda->Release();
|
||||
|
||||
TRACE("CP result %x\n", hr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CDefaultContextMenu::DoOpenOrExplore(
|
||||
LPCMINVOKECOMMANDINFO lpcmi)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
BOOL
|
||||
GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
|
||||
{
|
||||
|
@ -1141,7 +1115,203 @@ GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CDefaultContextMenu::DoPasteLink(
|
||||
LPCMINVOKECOMMANDINFO lpcmi)
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR wszPath[MAX_PATH];
|
||||
WCHAR wszTarget[MAX_PATH];
|
||||
|
||||
CComPtr<IDataObject> pda;
|
||||
hr = OleGetClipboard(&pda);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
STGMEDIUM medium;
|
||||
FORMATETC formatetc;
|
||||
InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
|
||||
hr = pda->GetData(&formatetc, &medium);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
/* lock the handle */
|
||||
LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
|
||||
if (!lpcida)
|
||||
{
|
||||
ReleaseStgMedium(&medium);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* convert the clipboard data into pidl (pointer to id list) */
|
||||
LPITEMIDLIST pidl;
|
||||
LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
||||
if (!apidl)
|
||||
{
|
||||
ReleaseStgMedium(&medium);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
CComPtr<IPersistFolder2> ppf2 = NULL;
|
||||
CComPtr<IShellFolder> psfFrom = NULL;
|
||||
|
||||
/* Grab the desktop shell folder */
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("SHGetDesktopFolder failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Find source folder, this is where the clipboard data was copied from */
|
||||
if (_ILIsDesktop(pidl))
|
||||
{
|
||||
/* use desktop shell folder */
|
||||
psfFrom = psfDesktop;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID*)&psfFrom);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("no IShellFolder\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the target path, where we will be saving the new links (where the user right clicked) */
|
||||
STRRET strFile;
|
||||
WCHAR wszTargetPath[MAX_PATH];
|
||||
|
||||
LPITEMIDLIST targetpidl;
|
||||
|
||||
hr = m_Dcm.psf->QueryInterface(IID_IPersistFolder2, (LPVOID *) &ppf2);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ppf2->GetCurFolder(&targetpidl);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = psfDesktop->GetDisplayNameOf(targetpidl, SHGDN_FORPARSING, &strFile);
|
||||
ILFree(targetpidl);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = StrRetToBufW(&strFile, NULL, wszTargetPath, _countof(wszTargetPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Error obtaining target path");
|
||||
goto cleanup;
|
||||
}
|
||||
TRACE("target path = %s", debugstr_w(wszTargetPath));
|
||||
|
||||
/* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
|
||||
for (UINT i = 0; i < lpcida->cidl; i++)
|
||||
{
|
||||
//Find out which file we're copying
|
||||
STRRET strFile;
|
||||
hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strFile);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Error source obtaining path");
|
||||
break;
|
||||
}
|
||||
|
||||
hr = StrRetToBufW(&strFile, apidl[i], wszPath, _countof(wszPath));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Error putting source path into buffer");
|
||||
break;
|
||||
}
|
||||
TRACE("source path = %s", debugstr_w(wszPath));
|
||||
|
||||
// Creating a buffer to hold the combined path
|
||||
WCHAR buffer_1[MAX_PATH] = L"";
|
||||
WCHAR *lpStr1;
|
||||
lpStr1 = buffer_1;
|
||||
|
||||
LPWSTR pwszFileName = PathFindFileNameW(wszPath);
|
||||
LPWSTR pwszExt = PathFindExtensionW(wszPath);
|
||||
LPWSTR placementPath = PathCombineW(lpStr1, wszTargetPath, pwszFileName);
|
||||
CComPtr<IPersistFile> ppf;
|
||||
|
||||
//Check to see if it's already a link.
|
||||
if (!wcsicmp(pwszExt, L".lnk"))
|
||||
{
|
||||
//It's a link so, we create a new one which copies the old.
|
||||
if(!GetUniqueFileName(placementPath, pwszExt, wszTarget, TRUE))
|
||||
{
|
||||
ERR("Error getting unique file name");
|
||||
hr = E_FAIL;
|
||||
break;
|
||||
}
|
||||
hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, ILCombine(pidl, apidl[i]), (LPVOID*)&ppf);
|
||||
if (FAILED(hr)) {
|
||||
ERR("Error constructing link from file");
|
||||
break;
|
||||
}
|
||||
|
||||
hr = ppf->Save(wszTarget, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//It's not a link, so build a new link using the creator class and fill it in.
|
||||
//Create a file name for the link
|
||||
if (!GetUniqueFileName(placementPath, L".lnk", wszTarget, TRUE))
|
||||
{
|
||||
ERR("Error creating unique file name");
|
||||
hr = E_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
CComPtr<IShellLinkW> pLink;
|
||||
hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
|
||||
if (FAILED(hr)) {
|
||||
ERR("Error instantiating IShellLinkW");
|
||||
break;
|
||||
}
|
||||
|
||||
WCHAR szDirPath[MAX_PATH], *pwszFile;
|
||||
GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile);
|
||||
if (pwszFile) pwszFile[0] = 0;
|
||||
|
||||
hr = pLink->SetPath(wszPath);
|
||||
if(FAILED(hr))
|
||||
break;
|
||||
|
||||
hr = pLink->SetWorkingDirectory(szDirPath);
|
||||
if(FAILED(hr))
|
||||
break;
|
||||
|
||||
hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
|
||||
if(FAILED(hr))
|
||||
break;
|
||||
|
||||
hr = ppf->Save(wszTarget, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
NotifyShellViewWindow(lpcmi, TRUE);
|
||||
|
||||
cleanup:
|
||||
SHFree(pidl);
|
||||
_ILFreeaPidl(apidl, lpcida->cidl);
|
||||
ReleaseStgMedium(&medium);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CDefaultContextMenu::DoOpenOrExplore(
|
||||
LPCMINVOKECOMMANDINFO lpcmi)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
@ -1153,15 +1323,17 @@ CDefaultContextMenu::DoCreateLink(
|
|||
HRESULT hr;
|
||||
STRRET strFile;
|
||||
|
||||
if (m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK)
|
||||
hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
|
||||
return E_FAIL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
WCHAR wszPath[MAX_PATH];
|
||||
if (StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, _countof(wszPath)) != S_OK)
|
||||
return E_FAIL;
|
||||
hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, _countof(wszPath));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
LPWSTR pwszExt = PathFindExtensionW(wszPath);
|
||||
|
||||
|
@ -1170,8 +1342,17 @@ CDefaultContextMenu::DoCreateLink(
|
|||
if (!GetUniqueFileName(wszPath, pwszExt, wszTarget, TRUE))
|
||||
return E_FAIL;
|
||||
|
||||
hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, m_Dcm.apidl[0], (LPVOID*)&ppf);
|
||||
if (hr != S_OK)
|
||||
IPersistFolder2 *ppf2 = NULL;
|
||||
LPITEMIDLIST pidl;
|
||||
hr = m_Dcm.psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ppf2->GetCurFolder(&pidl);
|
||||
ppf2->Release();
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, ILCombine(pidl, m_Dcm.apidl[0]), (LPVOID*)&ppf);
|
||||
}
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = ppf->Save(wszTarget, FALSE);
|
||||
|
@ -1282,6 +1463,19 @@ CDefaultContextMenu::DoCopyOrCut(
|
|||
|
||||
if (SUCCEEDED(SHCreateDataObject(m_Dcm.pidlFolder, m_Dcm.cidl, m_Dcm.apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj))))
|
||||
{
|
||||
if (!bCopy)
|
||||
{
|
||||
FORMATETC formatetc;
|
||||
STGMEDIUM medium;
|
||||
InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT), TYMED_HGLOBAL);
|
||||
pDataObj->GetData(&formatetc, &medium);
|
||||
DWORD * pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
|
||||
if (pdwFlag)
|
||||
*pdwFlag = DROPEFFECT_MOVE;
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
pDataObj->SetData(&formatetc, &medium, TRUE);
|
||||
}
|
||||
|
||||
hr = OleSetClipboard(pDataObj);
|
||||
pDataObj->Release();
|
||||
return hr;
|
||||
|
@ -1649,8 +1843,9 @@ CDefaultContextMenu::InvokeCommand(
|
|||
case FCIDM_SHVIEW_REFRESH:
|
||||
return NotifyShellViewWindow(lpcmi, FALSE);
|
||||
case FCIDM_SHVIEW_INSERT:
|
||||
case FCIDM_SHVIEW_INSERTLINK:
|
||||
return DoPaste(lpcmi);
|
||||
case FCIDM_SHVIEW_INSERTLINK:
|
||||
return DoPasteLink(lpcmi);
|
||||
case FCIDM_SHVIEW_OPEN:
|
||||
case FCIDM_SHVIEW_EXPLORE:
|
||||
return DoOpenOrExplore(lpcmi);
|
||||
|
|
|
@ -1205,7 +1205,7 @@ HRESULT WINAPI CDesktopFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl)
|
||||
HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, bool bCopy)
|
||||
{
|
||||
CComPtr<IPersistFolder2> ppf2;
|
||||
WCHAR szSrcPath[MAX_PATH];
|
||||
|
@ -1291,7 +1291,7 @@ HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCIT
|
|||
op.fFlags = FOF_MULTIDESTFILES;
|
||||
}
|
||||
op.hwnd = GetActiveWindow();
|
||||
op.wFunc = FO_COPY;
|
||||
op.wFunc = bCopy ? FO_COPY : FO_MOVE;
|
||||
op.fFlags |= FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
|
||||
|
||||
res = SHFileOperationW(&op);
|
||||
|
|
|
@ -76,7 +76,7 @@ class CDesktopFolder :
|
|||
virtual HRESULT WINAPI GetUniqueName(LPWSTR pwszName, UINT uLen);
|
||||
virtual HRESULT WINAPI AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut);
|
||||
virtual HRESULT WINAPI DeleteItems(UINT cidl, LPCITEMIDLIST *apidl);
|
||||
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl);
|
||||
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, bool bCopy);
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLDESKTOP)
|
||||
DECLARE_NOT_AGGREGATABLE(CDesktopFolder)
|
||||
|
|
|
@ -1035,7 +1035,7 @@ HRESULT WINAPI CFSFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl)
|
|||
* copies items to this folder
|
||||
*/
|
||||
HRESULT WINAPI CFSFolder::CopyItems(IShellFolder * pSFFrom, UINT cidl,
|
||||
LPCITEMIDLIST * apidl)
|
||||
LPCITEMIDLIST * apidl, bool bCopy)
|
||||
{
|
||||
IPersistFolder2 *ppf2 = NULL;
|
||||
WCHAR szSrcPath[MAX_PATH];
|
||||
|
@ -1131,7 +1131,7 @@ HRESULT WINAPI CFSFolder::CopyItems(IShellFolder * pSFFrom, UINT cidl,
|
|||
op.fFlags = FOF_MULTIDESTFILES;
|
||||
}
|
||||
op.hwnd = GetActiveWindow();
|
||||
op.wFunc = FO_COPY;
|
||||
op.wFunc = bCopy ? FO_COPY : FO_MOVE;
|
||||
op.fFlags |= FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
|
||||
|
||||
res = SHFileOperationW(&op);
|
||||
|
|
|
@ -93,7 +93,7 @@ class CFSFolder :
|
|||
virtual HRESULT WINAPI GetUniqueName(LPWSTR pwszName, UINT uLen);
|
||||
virtual HRESULT WINAPI AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut);
|
||||
virtual HRESULT WINAPI DeleteItems(UINT cidl, LPCITEMIDLIST *apidl);
|
||||
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl);
|
||||
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, bool bCopy);
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLFSFOLDER)
|
||||
DECLARE_NOT_AGGREGATABLE(CFSFolder)
|
||||
|
|
|
@ -42,7 +42,7 @@ DECLARE_INTERFACE_(ISFHelper,IUnknown)
|
|||
STDMETHOD(GetUniqueName)(THIS_ LPWSTR lpName, UINT uLen) PURE;
|
||||
STDMETHOD(AddFolder)(THIS_ HWND hwnd, LPCWSTR lpName, LPITEMIDLIST * ppidlOut) PURE;
|
||||
STDMETHOD(DeleteItems)(THIS_ UINT cidl, LPCITEMIDLIST * apidl) PURE;
|
||||
STDMETHOD(CopyItems)(THIS_ IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) PURE;
|
||||
STDMETHOD(CopyItems)(THIS_ IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl, bool bCopy) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
|
|
Loading…
Reference in a new issue