[SHELL32]

- Factor CFSDropTarget out of CFSFolder.
- For now their code is mixed (no code was moved), until we decide where exactly is should be kept.

svn path=/trunk/; revision=72047
This commit is contained in:
Giannis Adamopoulos 2016-07-29 12:56:06 +00:00
parent a57e61507d
commit 4d9d28fbd3
2 changed files with 98 additions and 118 deletions

View file

@ -62,25 +62,11 @@ HRESULT WINAPI CFileSysEnum::Initialize(LPWSTR sPathTarget, DWORD dwFlags)
return CreateFolderEnumList(sPathTarget, dwFlags);
}
/**************************************************************************
* registers clipboardformat once
*/
void CFSFolder::SF_RegisterClipFmt()
{
TRACE ("(%p)\n", this);
if (!cfShellIDList)
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
}
CFSFolder::CFSFolder()
{
pclsid = (CLSID *)&CLSID_ShellFSFolder;
sPathTarget = NULL;
pidlRoot = NULL;
cfShellIDList = 0;
SF_RegisterClipFmt();
fAcceptFmt = FALSE;
m_bGroupPolicyActive = 0;
}
@ -378,7 +364,7 @@ HRESULT WINAPI CFSFolder::CreateViewObject(HWND hwndOwner,
*ppvOut = NULL;
if (IsEqualIID (riid, IID_IDropTarget))
hr = this->QueryInterface (IID_IDropTarget, ppvOut);
hr = ShellObjectCreatorInit<CFSDropTarget>(sPathTarget, riid, ppvOut);
else if (IsEqualIID (riid, IID_IContextMenu))
{
FIXME ("IContextMenu not implemented\n");
@ -524,7 +510,7 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
if (cidl != 1 || FAILED(hr = this->_GetDropTarget(apidl[0], (LPVOID*) &pObj)))
{
IDropTarget * pDt = NULL;
hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
hr = ShellObjectCreatorInit<CFSDropTarget>(sPathTarget, riid, ppvOut);
pObj = pDt;
}
}
@ -871,11 +857,11 @@ BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
}
/****************************************************************************
* CFSFolder::CopyItems
* CFSDropTarget::CopyItems
*
* copies items to this folder
*/
HRESULT WINAPI CFSFolder::CopyItems(IShellFolder * pSFFrom, UINT cidl,
HRESULT WINAPI CFSDropTarget::CopyItems(IShellFolder * pSFFrom, UINT cidl,
LPCITEMIDLIST * apidl, BOOL bCopy)
{
CComPtr<IPersistFolder2> ppf2 = NULL;
@ -1136,8 +1122,34 @@ HRESULT WINAPI CFSFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO * ppfti
return E_NOTIMPL;
}
CFSDropTarget::CFSDropTarget():
cfShellIDList(0),
fAcceptFmt(FALSE),
sPathTarget(NULL)
{
}
HRESULT WINAPI CFSDropTarget::Initialize(LPWSTR PathTarget)
{
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
if (!cfShellIDList)
return E_FAIL;
sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR));
if (!sPathTarget)
return E_OUTOFMEMORY;
wcscpy(sPathTarget, PathTarget);
return S_OK;
}
CFSDropTarget::~CFSDropTarget()
{
SHFree(sPathTarget);
}
BOOL
CFSFolder::GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
CFSDropTarget::GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
{
WCHAR wszLink[40];
@ -1166,7 +1178,7 @@ CFSFolder::GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTa
/****************************************************************************
* IDropTarget implementation
*/
BOOL CFSFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
BOOL CFSDropTarget::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
{
/* TODO Windows does different drop effects if dragging across drives.
i.e., it will copy instead of move if the directories are on different disks. */
@ -1189,8 +1201,8 @@ BOOL CFSFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
return FALSE;
}
HRESULT WINAPI CFSFolder::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
HRESULT WINAPI CFSDropTarget::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
FORMATETC fmt;
@ -1209,8 +1221,8 @@ HRESULT WINAPI CFSFolder::DragEnter(IDataObject *pDataObject,
return S_OK;
}
HRESULT WINAPI CFSFolder::DragOver(DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect)
HRESULT WINAPI CFSDropTarget::DragOver(DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
@ -1222,7 +1234,7 @@ HRESULT WINAPI CFSFolder::DragOver(DWORD dwKeyState, POINTL pt,
return S_OK;
}
HRESULT WINAPI CFSFolder::DragLeave()
HRESULT WINAPI CFSDropTarget::DragLeave()
{
TRACE("(%p)\n", this);
@ -1231,8 +1243,8 @@ HRESULT WINAPI CFSFolder::DragLeave()
return S_OK;
}
HRESULT WINAPI CFSFolder::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
HRESULT WINAPI CFSDropTarget::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
@ -1259,15 +1271,15 @@ HRESULT WINAPI CFSFolder::Drop(IDataObject *pDataObject,
data->pt = pt;
// Need to dereference as pdweffect gets freed.
data->pdwEffect = *pdwEffect;
SHCreateThread(CFSFolder::_DoDropThreadProc, data, NULL, NULL);
SHCreateThread(CFSDropTarget::_DoDropThreadProc, data, NULL, NULL);
return S_OK;
}
}
return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
}
HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
HRESULT WINAPI CFSDropTarget::_DoDrop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
FORMATETC fmt;
@ -1315,17 +1327,6 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
CComPtr<IShellFolder> psfDesktop;
CComPtr<IShellFolder> psfFrom = NULL;
CComPtr<IShellFolder> psfTarget = NULL;
hr = this->QueryInterface(IID_PPV_ARG(IShellFolder, &psfTarget));
if (FAILED(hr))
{
ERR("psfTarget setting failed\n");
SHFree(pidl);
_ILFreeaPidl(apidl, lpcida->cidl);
ReleaseStgMedium(&medium);
return E_FAIL;
}
/* Grab the desktop shell folder */
hr = SHGetDesktopFolder(&psfDesktop);
@ -1359,32 +1360,11 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
if (bLinking)
{
CComPtr<IPersistFolder2> ppf2 = NULL;
STRRET strFile;
WCHAR wszTargetPath[MAX_PATH];
LPITEMIDLIST targetpidl;
WCHAR wszPath[MAX_PATH];
WCHAR wszTarget[MAX_PATH];
hr = this->QueryInterface(IID_PPV_ARG(IPersistFolder2, &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");
}
wcscpy(wszTargetPath, sPathTarget);
TRACE("target path = %s", debugstr_w(wszTargetPath));
@ -1415,7 +1395,7 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
LPWSTR pwszFileName = PathFindFileNameW(wszPath);
LPWSTR pwszExt = PathFindExtensionW(wszPath);
LPWSTR placementPath = PathCombineW(lpStr1, wszTargetPath, pwszFileName);
LPWSTR placementPath = PathCombineW(lpStr1, sPathTarget, pwszFileName);
CComPtr<IPersistFile> ppf;
//Check to see if it's already a link.
@ -1428,7 +1408,7 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
hr = E_FAIL;
break;
}
hr = IShellLink_ConstructFromFile(this, apidl[i], IID_PPV_ARG(IPersistFile, &ppf));
hr = IShellLink_ConstructFromPath(wszPath, IID_PPV_ARG(IPersistFile, &ppf));
if (FAILED(hr)) {
ERR("Error constructing link from file");
break;
@ -1495,41 +1475,13 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
{
CComPtr<IPersistFolder2> ppf2 = NULL;
STRRET strFile;
WCHAR wszTargetPath[MAX_PATH + 1];
LPWSTR pszSrcList;
LPITEMIDLIST targetpidl;
CComPtr<IShellFolder> psfDesktop = NULL;
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED(hr))
{
ERR("SHGetDesktopFolder failed\n");
return E_FAIL;
}
hr = this->QueryInterface(IID_PPV_ARG(IPersistFolder2, &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));
//Double NULL terminate.
wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
}
}
}
if (FAILED(hr))
{
ERR("Error obtaining target path");
return E_FAIL;
}
wcscpy(wszTargetPath, sPathTarget);
//Double NULL terminate.
wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
if (!lpdf)
{
@ -1561,7 +1513,8 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
return hr;
}
DWORD WINAPI CFSFolder::_DoDropThreadProc(LPVOID lpParameter) {
DWORD WINAPI CFSDropTarget::_DoDropThreadProc(LPVOID lpParameter)
{
CoInitialize(NULL);
_DoDropData *data = static_cast<_DoDropData*>(lpParameter);
CComPtr<IDataObject> pDataObject;
@ -1591,7 +1544,14 @@ HRESULT WINAPI CFSFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
TRACE("CFSFolder::_GetDropTarget entered\n");
if (_ILIsFolder (pidl))
return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
{
CComPtr<IShellFolder> psfChild;
hr = this->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return psfChild->CreateViewObject(NULL, IID_IDropTarget, ppvOut);
}
STRRET strFile;
hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);

View file

@ -29,8 +29,7 @@ class CFSFolder :
public CComCoClass<CFSFolder, &CLSID_ShellFSFolder>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder3,
public IDropTarget
public IPersistFolder3
{
private:
CLSID *pclsid;
@ -40,24 +39,15 @@ class CFSFolder :
LPITEMIDLIST pidlRoot; /* absolute pidl */
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
DWORD m_bGroupPolicyActive;
void SF_RegisterClipFmt();
BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut);
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
virtual HRESULT WINAPI _LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut);
virtual HRESULT WINAPI _LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut);
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy);
public:
CFSFolder();
~CFSFolder();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);
virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList);
@ -92,12 +82,6 @@ class CFSFolder :
virtual HRESULT WINAPI InitializeEx(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfti);
virtual HRESULT WINAPI GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti);
// IDropTarget
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLFSFOLDER)
DECLARE_NOT_AGGREGATABLE(CFSFolder)
@ -110,16 +94,52 @@ class CFSFolder :
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder3, IPersistFolder3)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};
struct _DoDropData {
CFSFolder *This;
CFSDropTarget *This;
IStream *pStream;
DWORD dwKeyState;
POINTL pt;
DWORD pdwEffect;
};
class CFSDropTarget :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTarget
{
private:
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
LPWSTR sPathTarget;
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy);
BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut);
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
public:
CFSDropTarget();
~CFSDropTarget();
HRESULT WINAPI Initialize(LPWSTR PathTarget);
// IDropTarget
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
DECLARE_NOT_AGGREGATABLE(CFSDropTarget)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CFSDropTarget)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};
#endif /* _CFSFOLDER_H_ */