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;
}
*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");
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;
}
}
}
/****************************************************************************
- * 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;
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];
/****************************************************************************
* 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. */
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;
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);
return S_OK;
}
-HRESULT WINAPI CFSFolder::DragLeave()
+HRESULT WINAPI CFSDropTarget::DragLeave()
{
TRACE("(%p)\n", this);
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);
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;
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);
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));
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.
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;
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)
{
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;
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);
public CComCoClass<CFSFolder, &CLSID_ShellFSFolder>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
- public IPersistFolder3,
- public IDropTarget
+ public IPersistFolder3
{
private:
CLSID *pclsid;
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);
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)
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_ */