[SHELL32]

- Separate CDesktopFolder's IDropTarget out into its own class (since each caller needs its own instance)
CORE-9839

svn path=/trunk/; revision=68202
This commit is contained in:
Thomas Faber 2015-06-20 10:26:22 +00:00
parent 0c99435b9a
commit dddbfc03a0
2 changed files with 74 additions and 45 deletions

View file

@ -48,7 +48,32 @@ extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpsz
* Desktopfolder implementation * Desktopfolder implementation
*/ */
class CDesktopFolder; class CDesktopFolderDropTarget :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTarget
{
private:
CComPtr<IShellFolder> m_psf;
BOOL m_fAcceptFmt; /* flag for pending Drop */
UINT m_cfShellIDList; /* clipboardformat for IDropTarget */
void SF_RegisterClipFmt();
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
public:
CDesktopFolderDropTarget();
HRESULT WINAPI Initialize(IShellFolder *psf);
// 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);
BEGIN_COM_MAP(CDesktopFolderDropTarget)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};
class CDesktopFolderEnum : class CDesktopFolderEnum :
public CEnumIDListBase public CEnumIDListBase
@ -254,21 +279,10 @@ HRESULT WINAPI CDesktopFolderEnum::Initialize(CDesktopFolder *desktopFolder, HWN
return ret ? S_OK : E_FAIL; return ret ? S_OK : E_FAIL;
} }
void CDesktopFolder::SF_RegisterClipFmt() CDesktopFolder::CDesktopFolder() :
sPathTarget(NULL),
pidlRoot(NULL)
{ {
TRACE ("(%p)\n", this);
if (!cfShellIDList)
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
}
CDesktopFolder::CDesktopFolder()
{
pidlRoot = NULL;
sPathTarget = NULL;
cfShellIDList = 0;
SF_RegisterClipFmt();
fAcceptFmt = FALSE;
} }
CDesktopFolder::~CDesktopFolder() CDesktopFolder::~CDesktopFolder()
@ -491,7 +505,7 @@ HRESULT WINAPI CDesktopFolder::CreateViewObject(
if (IsEqualIID (riid, IID_IDropTarget)) if (IsEqualIID (riid, IID_IDropTarget))
{ {
hr = this->QueryInterface (IID_IDropTarget, ppvOut); hr = ShellObjectCreatorInit<CDesktopFolderDropTarget>(this, IID_IDropTarget, ppvOut);
} }
else if (IsEqualIID (riid, IID_IContextMenu)) else if (IsEqualIID (riid, IID_IContextMenu))
{ {
@ -1326,7 +1340,29 @@ HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCIT
* set sensible places for the icons to live. * set sensible places for the icons to live.
* *
*/ */
BOOL CDesktopFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect) void CDesktopFolderDropTarget::SF_RegisterClipFmt()
{
TRACE ("(%p)\n", this);
if (!m_cfShellIDList)
m_cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
}
CDesktopFolderDropTarget::CDesktopFolderDropTarget() :
m_psf(NULL),
m_fAcceptFmt(FALSE),
m_cfShellIDList(0)
{
}
HRESULT WINAPI CDesktopFolderDropTarget::Initialize(IShellFolder *psf)
{
m_psf = psf;
SF_RegisterClipFmt();
return S_OK;
}
BOOL CDesktopFolderDropTarget::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
{ {
/* TODO Windows does different drop effects if dragging across drives. /* 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. */ i.e., it will copy instead of move if the directories are on different disks. */
@ -1335,7 +1371,7 @@ BOOL CDesktopFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
*pdwEffect = DROPEFFECT_NONE; *pdwEffect = DROPEFFECT_NONE;
if (fAcceptFmt) { /* Does our interpretation of the keystate ... */ if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */
*pdwEffect = KeyStateToDropEffect (dwKeyState); *pdwEffect = KeyStateToDropEffect (dwKeyState);
if (*pdwEffect == DROPEFFECT_NONE) if (*pdwEffect == DROPEFFECT_NONE)
@ -1349,27 +1385,27 @@ BOOL CDesktopFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
return FALSE; return FALSE;
} }
HRESULT WINAPI CDesktopFolder::DragEnter(IDataObject *pDataObject, HRESULT WINAPI CDesktopFolderDropTarget::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{ {
TRACE("(%p)->(DataObject=%p)\n", this, pDataObject); TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
FORMATETC fmt; FORMATETC fmt;
FORMATETC fmt2; FORMATETC fmt2;
fAcceptFmt = FALSE; m_fAcceptFmt = FALSE;
InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL); InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL); InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
fAcceptFmt = TRUE; m_fAcceptFmt = TRUE;
else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2))) else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
fAcceptFmt = TRUE; m_fAcceptFmt = TRUE;
QueryDrop(dwKeyState, pdwEffect); QueryDrop(dwKeyState, pdwEffect);
return S_OK; return S_OK;
} }
HRESULT WINAPI CDesktopFolder::DragOver(DWORD dwKeyState, POINTL pt, HRESULT WINAPI CDesktopFolderDropTarget::DragOver(DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect) DWORD *pdwEffect)
{ {
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
@ -1382,14 +1418,14 @@ HRESULT WINAPI CDesktopFolder::DragOver(DWORD dwKeyState, POINTL pt,
return S_OK; return S_OK;
} }
HRESULT WINAPI CDesktopFolder::DragLeave() HRESULT WINAPI CDesktopFolderDropTarget::DragLeave()
{ {
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
fAcceptFmt = FALSE; m_fAcceptFmt = FALSE;
return S_OK; return S_OK;
} }
HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject, HRESULT WINAPI CDesktopFolderDropTarget::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{ {
TRACE("(%p) object dropped desktop\n", this); TRACE("(%p) object dropped desktop\n", this);
@ -1438,18 +1474,24 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
LPITEMIDLIST pidl = NULL; LPITEMIDLIST pidl = NULL;
WCHAR szPath[MAX_PATH]; WCHAR szPath[MAX_PATH];
STRRET strRet;
//LPWSTR pathPtr; //LPWSTR pathPtr;
/* build a complete path to create a simple pidl */ /* build a complete path to create a simple pidl */
lstrcpynW(szPath, sPathTarget, MAX_PATH); hr = m_psf->GetDisplayNameOf(NULL, SHGDN_NORMAL | SHGDN_FORPARSING, &strRet);
if (SUCCEEDED(hr))
{
hr = StrRetToBufW(&strRet, NULL, szPath, MAX_PATH);
ASSERT(SUCCEEDED(hr));
/*pathPtr = */PathAddBackslashW(szPath); /*pathPtr = */PathAddBackslashW(szPath);
//hr = _ILCreateFromPathW(szPath, &pidl); //hr = _ILCreateFromPathW(szPath, &pidl);
hr = this->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL); hr = m_psf->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
CComPtr<IDropTarget> pDT; CComPtr<IDropTarget> pDT;
hr = this->BindToObject(pidl, NULL, IID_PPV_ARG(IDropTarget, &pDT)); hr = m_psf->BindToObject(pidl, NULL, IID_PPV_ARG(IDropTarget, &pDT));
CoTaskMemFree(pidl); CoTaskMemFree(pidl);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
SHSimulateDrop(pDT, pDataObject, dwKeyState, NULL, pdwEffect); SHSimulateDrop(pDT, pDataObject, dwKeyState, NULL, pdwEffect);

View file

@ -28,7 +28,6 @@ class CDesktopFolder :
public CComObjectRootEx<CComMultiThreadModelNoCS>, public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2, public IShellFolder2,
public IPersistFolder2, public IPersistFolder2,
public IDropTarget,
public ISFHelper public ISFHelper
{ {
private: private:
@ -36,10 +35,6 @@ class CDesktopFolder :
LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */ LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
LPITEMIDLIST pidlRoot; /* absolute pidl */ LPITEMIDLIST pidlRoot; /* absolute pidl */
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
void SF_RegisterClipFmt();
virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut); virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
public: public:
@ -77,13 +72,6 @@ class CDesktopFolder :
// *** IPersistFolder2 methods *** // *** IPersistFolder2 methods ***
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl); virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
// 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);
// *** ISFHelper methods *** // *** ISFHelper methods ***
virtual HRESULT WINAPI GetUniqueName(LPWSTR pwszName, UINT uLen); virtual HRESULT WINAPI GetUniqueName(LPWSTR pwszName, UINT uLen);
virtual HRESULT WINAPI AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut); virtual HRESULT WINAPI AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut);
@ -101,7 +89,6 @@ class CDesktopFolder :
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
COM_INTERFACE_ENTRY_IID(IID_ISFHelper, ISFHelper) COM_INTERFACE_ENTRY_IID(IID_ISFHelper, ISFHelper)
END_COM_MAP() END_COM_MAP()
}; };