ReactOS 0.4.15-dev-8434-g155a7c7
CFSDropTarget Class Reference

#include <CFSDropTarget.h>

Inheritance diagram for CFSDropTarget:
Collaboration diagram for CFSDropTarget:

Public Member Functions

 CFSDropTarget ()
 
 ~CFSDropTarget ()
 
HRESULT Initialize (LPWSTR PathTarget)
 
STDMETHOD() DragEnter (IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
 
STDMETHOD() DragOver (DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
 
STDMETHOD() DragLeave () override
 
STDMETHOD() Drop (IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
 
STDMETHOD() SetSite (IUnknown *pUnkSite) override
 
STDMETHOD() GetSite (REFIID riid, void **ppvSite) override
 
- Public Member Functions inherited from ATL::CComObjectRootEx< CComMultiThreadModelNoCS >
 ~CComObjectRootEx ()
 
ULONG InternalAddRef ()
 
ULONG InternalRelease ()
 
void Lock ()
 
void Unlock ()
 
HRESULT _AtlInitialConstruct ()
 
- Public Member Functions inherited from ATL::CComObjectRootBase
 CComObjectRootBase ()
 
 ~CComObjectRootBase ()
 
void SetVoid (void *)
 
HRESULT _AtlFinalConstruct ()
 
HRESULT FinalConstruct ()
 
void InternalFinalConstructAddRef ()
 
void InternalFinalConstructRelease ()
 
void FinalRelease ()
 
HRESULT DragEnter ([in, unique] IDataObject *pDataObj, [in] DWORD grfKeyState, [in] POINTL pt, [in, out] DWORD *pdwEffect)
 
HRESULT DragOver ([in] DWORD grfKeyState, [in] POINTL pt, [in, out] DWORD *pdwEffect)
 
HRESULT DragLeave ()
 
HRESULT Drop ([in, unique] IDataObject *pDataObj, [in] DWORD grfKeyState, [in] POINTL pt, [in, out] DWORD *pdwEffect)
 
- Public Member Functions inherited from IUnknown
HRESULT QueryInterface ([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
 
ULONG AddRef ()
 
ULONG Release ()
 
- Public Member Functions inherited from IObjectWithSite
HRESULT SetSite ([in] IUnknown *pUnkSite)
 
HRESULT GetSite ([in] REFIID riid, [out, iid_is(riid)] PVOID *ppvSite)
 

Private Member Functions

BOOL _QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect)
 
HRESULT _DoDrop (IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
 
HRESULT _CopyItems (IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy)
 
BOOL _GetUniqueFileName (LPCWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
 
HRESULT _GetEffectFromMenu (IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
 
HRESULT _RepositionItems (IShellFolderView *psfv, IDataObject *pDataObject, POINTL pt)
 

Static Private Member Functions

static DWORD WINAPI _DoDropThreadProc (LPVOID lpParameter)
 

Private Attributes

UINT m_cfShellIDList
 
BOOL m_fAcceptFmt
 
LPWSTR m_sPathTarget
 
HWND m_hwndSite
 
DWORD m_grfKeyState
 
DWORD m_dwDefaultEffect
 
CComPtr< IUnknownm_site
 

Additional Inherited Members

- Public Types inherited from IDropTarget
typedef IDropTargetLPDROPTARGET
 
- Public Types inherited from IUnknown
typedef IUnknownLPUNKNOWN
 
- Public Types inherited from IObjectWithSite
typedef IObjectWithSiteLPOBJECTWITHSITE
 
- Static Public Member Functions inherited from ATL::CComObjectRootBase
static void WINAPI ObjectMain (bool)
 
static const struct _ATL_CATMAP_ENTRYGetCategoryMap ()
 
static HRESULT WINAPI InternalQueryInterface (void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject)
 
- Public Attributes inherited from ATL::CComObjectRootBase
LONG m_dwRef
 
- Public Attributes inherited from IDropTarget
const DWORD MK_ALT = 0x20
 
const DWORD DROPEFFECT_NONE = 0
 
const DWORD DROPEFFECT_COPY = 1
 
const DWORD DROPEFFECT_MOVE = 2
 
const DWORD DROPEFFECT_LINK = 4
 
const DWORD DROPEFFECT_SCROLL = 0x80000000
 
const DWORD DD_DEFSCROLLINSET = 11
 
const DWORD DD_DEFSCROLLDELAY = 50
 
const DWORD DD_DEFSCROLLINTERVAL = 50
 
const DWORD DD_DEFDRAGDELAY = 200
 
const DWORD DD_DEFDRAGMINDIST = 2
 

Detailed Description

Definition at line 26 of file CFSDropTarget.h.

Constructor & Destructor Documentation

◆ CFSDropTarget()

CFSDropTarget::CFSDropTarget ( )

Definition at line 132 of file CFSDropTarget.cpp.

132 :
138{
139}
LPWSTR m_sPathTarget
Definition: CFSDropTarget.h:34
UINT m_cfShellIDList
Definition: CFSDropTarget.h:32
DWORD m_grfKeyState
Definition: CFSDropTarget.h:36
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117

◆ ~CFSDropTarget()

CFSDropTarget::~CFSDropTarget ( )

Definition at line 159 of file CFSDropTarget.cpp.

160{
162}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326

Member Function Documentation

◆ _CopyItems()

HRESULT CFSDropTarget::_CopyItems ( IShellFolder pSFFrom,
UINT  cidl,
LPCITEMIDLIST apidl,
BOOL  bCopy 
)
private

Definition at line 62 of file CFSDropTarget.cpp.

64{
66 WCHAR wszDstPath[MAX_PATH + 1] = {0};
67 PWCHAR pwszSrcPathsList = (PWCHAR) HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
68 if (!pwszSrcPathsList)
69 return E_OUTOFMEMORY;
70
71 PWCHAR pwszListPos = pwszSrcPathsList;
72 STRRET strretFrom;
74 BOOL bRenameOnCollision = FALSE;
75
76 /* Build a double null terminated list of C strings from source paths */
77 for (UINT i = 0; i < cidl; i++)
78 {
79 ret = pSFFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strretFrom);
80 if (FAILED(ret))
81 goto cleanup;
82
83 ret = StrRetToBufW(&strretFrom, NULL, pwszListPos, MAX_PATH);
84 if (FAILED(ret))
85 goto cleanup;
86
87 pwszListPos += lstrlenW(pwszListPos) + 1;
88 }
89 /* Append the final null. */
90 *pwszListPos = L'\0';
91
92 /* Build a double null terminated target (this path) */
94 if (FAILED(ret))
95 goto cleanup;
96
97 wszDstPath[lstrlenW(wszDstPath) + 1] = UNICODE_NULL;
98
99 /* Set bRenameOnCollision to TRUE if necesssary */
100 if (bCopy)
101 {
102 WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
103 GetFullPathNameW(pwszSrcPathsList, _countof(szPath1), szPath1, NULL);
104 GetFullPathNameW(wszDstPath, _countof(szPath2), szPath2, NULL);
105 PathRemoveFileSpecW(szPath1);
106 if (_wcsicmp(szPath1, szPath2) == 0)
107 bRenameOnCollision = TRUE;
108 }
109
110 ZeroMemory(&fop, sizeof(fop));
111 fop.hwnd = m_hwndSite;
112 fop.wFunc = bCopy ? FO_COPY : FO_MOVE;
113 fop.pFrom = pwszSrcPathsList;
114 fop.pTo = wszDstPath;
116 if (bRenameOnCollision)
118
119 ret = S_OK;
120
121 if (SHFileOperationW(&fop))
122 {
123 ERR("SHFileOperationW failed\n");
124 ret = E_FAIL;
125 }
126
127cleanup:
128 HeapFree(GetProcessHeap(), 0, pwszSrcPathsList);
129 return ret;
130}
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
unsigned int UINT
Definition: ndis.h:50
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define FOF_ALLOWUNDO
Definition: shellapi.h:147
#define FO_COPY
Definition: shellapi.h:137
#define FOF_RENAMEONCOLLISION
Definition: shellapi.h:144
#define FOF_NOCONFIRMMKDIR
Definition: shellapi.h:150
#define FO_MOVE
Definition: shellapi.h:136
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1987
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
LPCWSTR pFrom
Definition: shellapi.h:357
FILEOP_FLAGS fFlags
Definition: shellapi.h:359
uint16_t * PWCHAR
Definition: typedefs.h:56
int ret
#define ZeroMemory
Definition: winbase.h:1712
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by _DoDrop().

◆ _DoDrop()

HRESULT CFSDropTarget::_DoDrop ( IDataObject pDataObject,
DWORD  dwKeyState,
POINTL  pt,
DWORD pdwEffect 
)
private

Definition at line 499 of file CFSDropTarget.cpp.

501{
502 TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
503 FORMATETC fmt;
504 FORMATETC fmt2;
505 STGMEDIUM medium;
506
507 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
508 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
509
510 HRESULT hr;
511 bool bCopy = TRUE;
512 bool bLinking = FALSE;
513
514 /* Figure out what drop operation we're doing */
515 if (pdwEffect)
516 {
517 TRACE("Current drop effect flag %i\n", *pdwEffect);
518 if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
519 bCopy = FALSE;
520 if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
521 bLinking = TRUE;
522 }
523
524 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
525 {
526 hr = pDataObject->GetData(&fmt, &medium);
527 TRACE("CFSTR_SHELLIDLIST\n");
528 if (FAILED(hr))
529 {
530 ERR("CFSTR_SHELLIDLIST failed\n");
531 }
532 /* lock the handle */
533 LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
534 if (!lpcida)
535 {
536 ReleaseStgMedium(&medium);
537 return E_FAIL;
538 }
539
540 /* convert the data into pidl */
541 LPITEMIDLIST pidl;
542 LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
543 if (!apidl)
544 {
545 ReleaseStgMedium(&medium);
546 return E_FAIL;
547 }
548
549 CComPtr<IShellFolder> psfDesktop;
550 CComPtr<IShellFolder> psfFrom = NULL;
551
552 /* Grab the desktop shell folder */
553 hr = SHGetDesktopFolder(&psfDesktop);
554 if (FAILED(hr))
555 {
556 ERR("SHGetDesktopFolder failed\n");
557 SHFree(pidl);
558 _ILFreeaPidl(apidl, lpcida->cidl);
559 ReleaseStgMedium(&medium);
560 return E_FAIL;
561 }
562
563 /* Find source folder, this is where the clipboard data was copied from */
564 if (_ILIsDesktop(pidl))
565 {
566 /* use desktop shell folder */
567 psfFrom = psfDesktop;
568 }
569 else
570 {
571 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
572 if (FAILED(hr))
573 {
574 ERR("no IShellFolder\n");
575 SHFree(pidl);
576 _ILFreeaPidl(apidl, lpcida->cidl);
577 ReleaseStgMedium(&medium);
578 return E_FAIL;
579 }
580 }
581
582 if (bLinking)
583 {
584 WCHAR wszNewLnk[MAX_PATH];
585
586 TRACE("target path = %s\n", debugstr_w(m_sPathTarget));
587
588 /* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
589 for (UINT i = 0; i < lpcida->cidl; i++)
590 {
591 CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlFull;
592 hr = SHILCombine(pidl, apidl[i], &pidlFull);
593
594 WCHAR targetName[MAX_PATH];
595 if (SUCCEEDED(hr))
596 hr = Shell_DisplayNameOf(psfFrom, apidl[i], SHGDN_FOREDITING | SHGDN_INFOLDER, targetName, _countof(targetName));
598 {
599 SHELL_ErrorBox(m_hwndSite, hr);
600 break;
601 }
603
604 WCHAR wszCombined[MAX_PATH + _countof(targetName)];
605 PathCombineW(wszCombined, m_sPathTarget, targetName);
606
607 // Check to see if the source is a link
608 SFGAOF att = SHGetAttributes(psfFrom, apidl[i], SFGAO_FOLDER | SFGAO_STREAM | SFGAO_FILESYSTEM);
609 BOOL fSourceIsLink = FALSE;
610 if (!wcsicmp(PathFindExtensionW(targetName), L".lnk") && (att & (SFGAO_FOLDER | SFGAO_STREAM)) != SFGAO_FOLDER)
611 {
612 fSourceIsLink = TRUE;
613 PathRemoveExtensionW(wszCombined);
614 }
615
616 // Create a pathname to save the new link.
617 _GetUniqueFileName(wszCombined, L".lnk", wszNewLnk, TRUE);
618
619 CComPtr<IPersistFile> ppf;
620 if (fSourceIsLink)
621 {
622 PWSTR pwszTargetFull;
623 hr = SHGetNameFromIDList(pidlFull, SIGDN_DESKTOPABSOLUTEPARSING, &pwszTargetFull);
625 {
628 SHFree(pwszTargetFull);
629 }
630 }
631 else
632 {
633 CComPtr<IShellLinkW> pLink;
634 hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
636 {
637 hr = pLink->SetIDList(pidlFull);
639 hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
640
641 PWSTR pwszPath, pSep;
642 if ((att & SFGAO_FILESYSTEM) && SUCCEEDED(SHGetNameFromIDList(pidlFull, SIGDN_FILESYSPATH, &pwszPath)))
643 {
644 if ((pSep = PathFindFileNameW(pwszPath)) > pwszPath)
645 {
646 pSep[-1] = UNICODE_NULL;
647 pLink->SetWorkingDirectory(pwszPath);
648 }
649 SHFree(pwszPath);
650 }
651 }
652 }
653 if (SUCCEEDED(hr))
654 hr = ppf->Save(wszNewLnk, !fSourceIsLink);
656 {
657 SHELL_ErrorBox(m_hwndSite, hr);
658 break;
659 }
661 }
662 }
663 else
664 {
665 hr = _CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
666 }
667
668 SHFree(pidl);
669 _ILFreeaPidl(apidl, lpcida->cidl);
670 ReleaseStgMedium(&medium);
671 }
672 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
673 {
674 FORMATETC fmt2;
675 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
676 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
677 {
678 WCHAR wszTargetPath[MAX_PATH + 1];
679 LPWSTR pszSrcList;
680
681 wcscpy(wszTargetPath, m_sPathTarget);
682 //Double NULL terminate.
683 wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
684
685 LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
686 if (!lpdf)
687 {
688 ERR("Error locking global\n");
689 return E_FAIL;
690 }
691 pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
692 ERR("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath), bCopy);
693
695 ZeroMemory(&op, sizeof(op));
696 op.pFrom = pszSrcList;
697 op.pTo = wszTargetPath;
698 op.hwnd = m_hwndSite;
699 op.wFunc = bCopy ? FO_COPY : FO_MOVE;
701 int res = SHFileOperationW(&op);
702 if (res)
703 {
704 ERR("SHFileOperationW failed with 0x%x\n", res);
705 hr = E_FAIL;
706 }
707
708 return hr;
709 }
710 ERR("Error calling GetData\n");
711 hr = E_FAIL;
712 }
713 else
714 {
715 ERR("No viable drop format\n");
716 hr = E_FAIL;
717 }
718 return hr;
719}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
static void SHELL_StripIllegalFsNameCharacters(_Inout_ LPWSTR Buf)
#define CF_HDROP
Definition: constants.h:410
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
HRESULT _CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy)
BOOL _GetUniqueFileName(LPCWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
UINT op
Definition: effect.c:236
#define wcsicmp
Definition: compat.h:15
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HRESULT Shell_DisplayNameOf(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, _Out_ LPWSTR pszBuf, _In_ UINT cchBuf)
Definition: utils.cpp:230
DWORD SHGetAttributes(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwAttributes)
Definition: utils.cpp:246
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
GLuint res
Definition: glext.h:9613
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
HRESULT QueryGetData([in, unique] FORMATETC *pformatetc)
const DWORD DROPEFFECT_LINK
Definition: oleidl.idl:932
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_w
Definition: kernel32.h:32
#define PathCombineW
Definition: pathcch.h:317
LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST *pidl, const CIDA *cida)
Definition: pidl.c:2632
HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName)
Definition: pidl.c:1456
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2594
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
HRESULT hr
Definition: shlfolder.c:183
struct CIDA * LPIDA
#define SHCNE_CREATE
Definition: shlobj.h:1890
#define SHCNF_PATHW
Definition: shlobj.h:1924
struct _DROPFILES * LPDROPFILES
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
Definition: shlobj.h:572
UINT cidl
Definition: shlobj.h:572
Definition: dsound.c:943
uint16_t * PWSTR
Definition: typedefs.h:56
#define IID_PPV_ARG(Itype, ppType)
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by Drop().

◆ _DoDropThreadProc()

DWORD WINAPI CFSDropTarget::_DoDropThreadProc ( LPVOID  lpParameter)
staticprivate

Definition at line 721 of file CFSDropTarget.cpp.

722{
724 _DoDropData *data = static_cast<_DoDropData*>(lpParameter);
725 CComPtr<IDataObject> pDataObject;
727
728 if (SUCCEEDED(hr))
729 {
730 CComPtr<IAsyncOperation> pAsyncOperation;
731 hr = data->This->_DoDrop(pDataObject, data->dwKeyState, data->pt, &data->pdwEffect);
732 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
733 {
734 pAsyncOperation->EndOperation(hr, NULL, data->pdwEffect);
735 }
736 }
737 //Release the CFSFolder and data object holds in the copying thread.
738 data->This->Release();
739 //Release the parameter from the heap.
742 return 0;
743}
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid, LPVOID *ppv)
Definition: marshal.c:2144
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ULONG Release()

Referenced by Drop().

◆ _GetEffectFromMenu()

HRESULT CFSDropTarget::_GetEffectFromMenu ( IDataObject pDataObject,
POINTL  pt,
DWORD pdwEffect,
DWORD  dwAvailableEffects 
)
private

Definition at line 218 of file CFSDropTarget.cpp.

219{
221 if (!hmenu)
222 return E_OUTOFMEMORY;
223
225
226 SHELL_LimitDropEffectToItemAttributes(pDataObject, &dwAvailableEffects);
227 if ((dwAvailableEffects & DROPEFFECT_COPY) == 0)
229 if ((dwAvailableEffects & DROPEFFECT_MOVE) == 0)
231 if ((dwAvailableEffects & DROPEFFECT_LINK) == 0 && (dwAvailableEffects & (DROPEFFECT_COPY | DROPEFFECT_MOVE)))
233
235 if (*pdwEffect & dwAvailableEffects & DROPEFFECT_COPY)
237 else if (*pdwEffect & dwAvailableEffects & DROPEFFECT_MOVE)
239 else if (dwAvailableEffects & DROPEFFECT_LINK)
241
242 /* FIXME: We need to support shell extensions here */
243
244 /* We shouldn't use the site window here because the menu should work even when we don't have a site */
245 HWND hwndDummy = CreateWindowEx(0,
246 WC_STATIC,
247 NULL,
249 pt.x,
250 pt.y,
251 1,
252 1,
253 NULL,
254 NULL,
255 NULL,
256 NULL);
257
258 SetForegroundWindow(hwndDummy); // Required for aborting by pressing Esc when dragging from Explorer to desktop
259 UINT uCommand = TrackPopupMenu(hpopupmenu,
261 pt.x, pt.y, 0, hwndDummy, NULL);
262
263 DestroyWindow(hwndDummy);
264
265 if (uCommand == 0)
266 return S_FALSE;
267 else if (uCommand == IDM_COPYHERE)
268 *pdwEffect = DROPEFFECT_COPY;
269 else if (uCommand == IDM_MOVEHERE)
270 *pdwEffect = DROPEFFECT_MOVE;
271 else if (uCommand == IDM_LINKHERE)
272 *pdwEffect = DROPEFFECT_LINK;
273
274 return S_OK;
275}
static HRESULT SHELL_LimitDropEffectToItemAttributes(_In_ IDataObject *pDataObject, _Inout_ PDWORD pdwEffect)
static void GetDefaultCopyMoveEffect()
#define shell32_hInstance
#define pt(x, y)
Definition: drawing.c:79
const DWORD DROPEFFECT_COPY
Definition: oleidl.idl:930
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static HMENU hpopupmenu
Definition: msg.c:17339
#define WS_OVERLAPPED
Definition: pedump.c:615
#define WS_BORDER
Definition: pedump.c:625
#define WS_DISABLED
Definition: pedump.c:621
#define SS_LEFT
Definition: pedump.c:692
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WC_STATIC
Definition: commctrl.h:4682
#define IDM_DRAGFILE
Definition: shresdef.h:877
#define IDM_MOVEHERE
Definition: shresdef.h:879
#define IDM_LINKHERE
Definition: shresdef.h:880
#define IDM_COPYHERE
Definition: shresdef.h:878
static HMENU hmenu
Definition: win.c:66
#define S_FALSE
Definition: winerror.h:2357
#define CreateWindowEx
Definition: winuser.h:5764
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_RIGHTBUTTON
Definition: winuser.h:2380
BOOL WINAPI SetForegroundWindow(_In_ HWND)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_NONOTIFY
Definition: winuser.h:2386
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define TPM_LEFTALIGN
Definition: winuser.h:2377
#define TPM_LEFTBUTTON
Definition: winuser.h:2379
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HMENU WINAPI LoadMenuW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
#define TPM_RETURNCMD
Definition: winuser.h:2387
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by Drop().

◆ _GetUniqueFileName()

BOOL CFSDropTarget::_GetUniqueFileName ( LPCWSTR  pwszBasePath,
LPCWSTR  pwszExt,
LPWSTR  pwszTarget,
BOOL  bShortcut 
)
private

Definition at line 165 of file CFSDropTarget.cpp.

166{
167 WCHAR wszLink[40];
168
169 if (!bShortcut)
170 {
171 if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink)))
172 wszLink[0] = L'\0';
173 }
174
175 if (!bShortcut)
176 swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt);
177 else
178 swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt);
179
180 for (UINT i = 2; PathFileExistsW(pwszTarget); ++i)
181 {
182 if (!bShortcut)
183 swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt);
184 else
185 swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt);
186 }
187
188 return TRUE;
189}
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
#define swprintf
Definition: precomp.h:40
#define IDS_LNK_FILE
Definition: shresdef.h:180
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)

Referenced by _DoDrop().

◆ _QueryDrop()

BOOL CFSDropTarget::_QueryDrop ( DWORD  dwKeyState,
LPDWORD  pdwEffect 
)
private

Definition at line 194 of file CFSDropTarget.cpp.

195{
196 /* TODO Windows does different drop effects if dragging across drives.
197 i.e., it will copy instead of move if the directories are on different disks. */
199
200 DWORD dwEffect = m_dwDefaultEffect;
201
202 *pdwEffect = DROPEFFECT_NONE;
203
204 if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */
205 *pdwEffect = KeyStateToDropEffect (dwKeyState);
206
207 if (*pdwEffect == DROPEFFECT_NONE)
208 *pdwEffect = dwEffect;
209
210 /* ... matches the desired effect ? */
211 if (dwEffect & *pdwEffect) {
212 return TRUE;
213 }
214 }
215 return FALSE;
216}
DWORD m_dwDefaultEffect
Definition: CFSDropTarget.h:37
unsigned long DWORD
Definition: ntddk_ex.h:95
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
#define KeyStateToDropEffect(kst)
Definition: shell32_main.h:105

Referenced by DragOver(), and Drop().

◆ _RepositionItems()

HRESULT CFSDropTarget::_RepositionItems ( IShellFolderView *  psfv,
IDataObject pDataObject,
POINTL  pt 
)
private

Definition at line 277 of file CFSDropTarget.cpp.

278{
279 CComPtr<IFolderView> pfv;
280 POINT ptDrag;
283 return hr;
284
285 hr = psfv->GetDragPoint(&ptDrag);
287 return hr;
288
289 PIDLIST_ABSOLUTE pidlFolder;
290 PUITEMID_CHILD *apidl;
291 UINT cidl;
292 hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
294 return hr;
295
296 CComHeapPtr<POINT> apt;
297 if (!apt.Allocate(cidl))
298 {
299 SHFree(pidlFolder);
300 _ILFreeaPidl(apidl, cidl);
301 return E_OUTOFMEMORY;
302 }
303
304 for (UINT i = 0; i<cidl; i++)
305 {
306 pfv->GetItemPosition(apidl[i], &apt[i]);
307 apt[i].x += pt.x - ptDrag.x;
308 apt[i].y += pt.y - ptDrag.y;
309 }
310
311 pfv->SelectAndPositionItems(cidl, apidl, apt, SVSI_SELECT);
312
313 SHFree(pidlFolder);
314 _ILFreeaPidl(apidl, cidl);
315 return S_OK;
316}
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:368
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48

Referenced by Drop().

◆ DragEnter()

HRESULT WINAPI CFSDropTarget::DragEnter ( IDataObject pDataObject,
DWORD  dwKeyState,
POINTL  pt,
DWORD pdwEffect 
)
override

Implements IDropTarget.

Definition at line 318 of file CFSDropTarget.cpp.

320{
321 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
322
323 if (*pdwEffect == DROPEFFECT_NONE)
324 return S_OK;
325
326 FORMATETC fmt;
327 FORMATETC fmt2;
329
330 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
331 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
332
333 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
335 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
337
338 m_grfKeyState = dwKeyState;
339
340#define D_NONE DROPEFFECT_NONE
341#define D_COPY DROPEFFECT_COPY
342#define D_MOVE DROPEFFECT_MOVE
343#define D_LINK DROPEFFECT_LINK
344 m_dwDefaultEffect = *pdwEffect;
345 switch (*pdwEffect & (D_COPY | D_MOVE | D_LINK))
346 {
347 case D_COPY | D_MOVE:
348 if (dwKeyState & MK_CONTROL)
350 else
352 break;
353 case D_COPY | D_MOVE | D_LINK:
354 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
356 else if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == MK_CONTROL)
358 else
360 break;
361 case D_COPY | D_LINK:
362 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
364 else
366 break;
367 case D_MOVE | D_LINK:
368 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
370 else
372 break;
373 }
374
375 STGMEDIUM medium;
376 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)))
377 {
378 WCHAR wstrFirstFile[MAX_PATH];
379 if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, _countof(wstrFirstFile)))
380 {
381 /* Check if the drive letter is different */
382 if (wstrFirstFile[0] != m_sPathTarget[0])
383 {
385 }
386 }
387 ReleaseStgMedium(&medium);
388 }
389
390 if (!m_fAcceptFmt)
391 *pdwEffect = DROPEFFECT_NONE;
392 else
393 *pdwEffect = m_dwDefaultEffect;
394
395 return S_OK;
396}
#define D_COPY
#define D_MOVE
#define D_LINK
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:622
#define MK_SHIFT
Definition: winuser.h:2369
#define MK_CONTROL
Definition: winuser.h:2370

◆ DragLeave()

HRESULT WINAPI CFSDropTarget::DragLeave ( void  )
override

Implements IDropTarget.

Definition at line 413 of file CFSDropTarget.cpp.

414{
415 TRACE("(%p)\n", this);
416
418
419 return S_OK;
420}

◆ DragOver()

HRESULT WINAPI CFSDropTarget::DragOver ( DWORD  dwKeyState,
POINTL  pt,
DWORD pdwEffect 
)
override

Implements IDropTarget.

Definition at line 398 of file CFSDropTarget.cpp.

400{
401 TRACE("(%p)\n", this);
402
403 if (!pdwEffect)
404 return E_INVALIDARG;
405
406 m_grfKeyState = dwKeyState;
407
408 _QueryDrop(dwKeyState, pdwEffect);
409
410 return S_OK;
411}
BOOL _QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
#define E_INVALIDARG
Definition: ddrawi.h:101

◆ Drop()

HRESULT WINAPI CFSDropTarget::Drop ( IDataObject pDataObject,
DWORD  dwKeyState,
POINTL  pt,
DWORD pdwEffect 
)
override

Implements IDropTarget.

Definition at line 422 of file CFSDropTarget.cpp.

424{
425 TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
426
427 if (!pdwEffect)
428 return E_INVALIDARG;
429
431
432 DWORD dwAvailableEffects = *pdwEffect;
433
434 _QueryDrop(dwKeyState, pdwEffect);
435
436 TRACE("pdwEffect: 0x%x, m_dwDefaultEffect: 0x%x, dwAvailableEffects: 0x%x\n", *pdwEffect, m_dwDefaultEffect, dwAvailableEffects);
437
439 {
440 HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect, dwAvailableEffects);
441 if (FAILED_UNEXPECTEDLY(hr) || hr == S_FALSE)
442 return hr;
443 }
444
445 if (*pdwEffect == DROPEFFECT_MOVE && m_site)
446 {
447 CComPtr<IShellFolderView> psfv;
449 if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK)
450 {
451 _RepositionItems(psfv, pDataObject, pt);
452 return S_OK;
453 }
454 }
455
456 BOOL fIsOpAsync = FALSE;
457 CComPtr<IAsyncOperation> pAsyncOperation;
458
459 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
460 {
461 if (SUCCEEDED(pAsyncOperation->GetAsyncMode(&fIsOpAsync)) && fIsOpAsync)
462 {
463 _DoDropData *data = static_cast<_DoDropData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData)));
464 data->This = this;
465 // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder).
466 pDataObject->AddRef();
467 pAsyncOperation->StartOperation(NULL);
469 this->AddRef();
470 data->dwKeyState = dwKeyState;
471 data->pt = pt;
472 // Need to dereference as pdweffect gets freed.
473 data->pdwEffect = *pdwEffect;
475 return S_OK;
476 }
477 }
478 return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
479}
CComPtr< IUnknown > m_site
Definition: CFSDropTarget.h:38
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter)
HRESULT _GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
HRESULT _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
HRESULT _RepositionItems(IShellFolderView *psfv, IDataObject *pDataObject, POINTL pt)
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1332
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
ULONG AddRef()
const GUID IID_IDataObject
#define SID_IFolderView
DWORD dwKeyState
Definition: CFSDropTarget.h:77
CFSDropTarget * This
Definition: CFSDropTarget.h:75
#define MK_RBUTTON
Definition: winuser.h:2368

◆ GetSite()

HRESULT WINAPI CFSDropTarget::GetSite ( REFIID  riid,
void **  ppvSite 
)
override

Definition at line 491 of file CFSDropTarget.cpp.

492{
493 if (!m_site)
494 return E_FAIL;
495
496 return m_site->QueryInterface(riid, ppvSite);
497}
REFIID riid
Definition: atlbase.h:39

◆ Initialize()

HRESULT CFSDropTarget::Initialize ( LPWSTR  PathTarget)

Definition at line 141 of file CFSDropTarget.cpp.

142{
143 if (!PathTarget)
144 return E_UNEXPECTED;
145
147 if (!m_cfShellIDList)
148 return E_FAIL;
149
150 m_sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR));
151 if (!m_sPathTarget)
152 return E_OUTOFMEMORY;
153
154 wcscpy(m_sPathTarget, PathTarget);
155
156 return S_OK;
157}
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:550
#define E_UNEXPECTED
Definition: winerror.h:2456
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)

◆ SetSite()

HRESULT WINAPI CFSDropTarget::SetSite ( IUnknown pUnkSite)
override

Implements IObjectWithSite.

Definition at line 483 of file CFSDropTarget.cpp.

484{
485 m_site = pUnkSite;
486 return S_OK;
487}

Member Data Documentation

◆ m_cfShellIDList

UINT CFSDropTarget::m_cfShellIDList
private

Definition at line 32 of file CFSDropTarget.h.

Referenced by _DoDrop(), DragEnter(), and Initialize().

◆ m_dwDefaultEffect

DWORD CFSDropTarget::m_dwDefaultEffect
private

Definition at line 37 of file CFSDropTarget.h.

Referenced by _QueryDrop(), DragEnter(), and Drop().

◆ m_fAcceptFmt

BOOL CFSDropTarget::m_fAcceptFmt
private

Definition at line 33 of file CFSDropTarget.h.

Referenced by _QueryDrop(), DragEnter(), and DragLeave().

◆ m_grfKeyState

DWORD CFSDropTarget::m_grfKeyState
private

Definition at line 36 of file CFSDropTarget.h.

Referenced by DragEnter(), DragOver(), and Drop().

◆ m_hwndSite

HWND CFSDropTarget::m_hwndSite
private

Definition at line 35 of file CFSDropTarget.h.

Referenced by _CopyItems(), _DoDrop(), and Drop().

◆ m_site

CComPtr<IUnknown> CFSDropTarget::m_site
private

Definition at line 38 of file CFSDropTarget.h.

Referenced by Drop(), GetSite(), and SetSite().

◆ m_sPathTarget

LPWSTR CFSDropTarget::m_sPathTarget
private

Definition at line 34 of file CFSDropTarget.h.

Referenced by _CopyItems(), _DoDrop(), DragEnter(), Initialize(), and ~CFSDropTarget().


The documentation for this class was generated from the following files: