ReactOS 0.4.15-dev-5893-g1bb4167
CFSDropTarget Class Reference

#include <CFSDropTarget.h>

Inheritance diagram for CFSDropTarget:
Collaboration diagram for CFSDropTarget:

Public Member Functions

 CFSDropTarget ()
 
 ~CFSDropTarget ()
 
HRESULT Initialize (LPWSTR PathTarget)
 
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)
 
virtual HRESULT STDMETHODCALLTYPE SetSite (IUnknown *pUnkSite)
 
virtual HRESULT STDMETHODCALLTYPE GetSite (REFIID riid, void **ppvSite)
 
- 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 105 of file CFSDropTarget.cpp.

105 :
111{
112}
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 132 of file CFSDropTarget.cpp.

133{
135}
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{
65 LPWSTR pszSrcList;
66 HRESULT hr;
67 WCHAR wszTargetPath[MAX_PATH + 1];
68
69 wcscpy(wszTargetPath, m_sPathTarget);
70 //Double NULL terminate.
71 wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
72
73 TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
74
75 STRRET strretFrom;
76 hr = pSFFrom->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strretFrom);
78 return hr;
79
80 pszSrcList = BuildPathsList(strretFrom.pOleStr, cidl, apidl);
81 TRACE("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(m_sPathTarget), bCopy);
82 CoTaskMemFree(strretFrom.pOleStr);
83 if (!pszSrcList)
84 return E_OUTOFMEMORY;
85
86 SHFILEOPSTRUCTW op = {0};
87 op.pFrom = pszSrcList;
88 op.pTo = wszTargetPath;
89 op.hwnd = m_hwndSite;
90 op.wFunc = bCopy ? FO_COPY : FO_MOVE;
92
93 int res = SHFileOperationW(&op);
94
95 HeapFree(GetProcessHeap(), 0, pszSrcList);
96
97 if (res)
98 {
99 ERR("SHFileOperationW failed with 0x%x\n", res);
100 return E_FAIL;
101 }
102 return S_OK;
103}
static WCHAR * BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
#define ERR(fmt,...)
Definition: debug.h:110
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
UINT op
Definition: effect.c:236
#define GetProcessHeap()
Definition: compat.h:736
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
GLuint res
Definition: glext.h:9613
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
#define S_OK
Definition: intsafe.h:52
#define debugstr_w
Definition: kernel32.h:32
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define FOF_ALLOWUNDO
Definition: shellapi.h:144
#define FO_COPY
Definition: shellapi.h:134
#define FOF_NOCONFIRMMKDIR
Definition: shellapi.h:147
#define FO_MOVE
Definition: shellapi.h:133
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1982
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR pOleStr
Definition: shtypes.idl:96
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by _DoDrop().

◆ _DoDrop()

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

Definition at line 468 of file CFSDropTarget.cpp.

470{
471 TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
472 FORMATETC fmt;
473 FORMATETC fmt2;
474 STGMEDIUM medium;
475
476 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
477 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
478
479 HRESULT hr;
480 bool bCopy = TRUE;
481 bool bLinking = FALSE;
482
483 /* Figure out what drop operation we're doing */
484 if (pdwEffect)
485 {
486 TRACE("Current drop effect flag %i\n", *pdwEffect);
487 if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
488 bCopy = FALSE;
489 if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
490 bLinking = TRUE;
491 }
492
493 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
494 {
495 hr = pDataObject->GetData(&fmt, &medium);
496 TRACE("CFSTR_SHELLIDLIST.\n");
497 if (FAILED(hr))
498 {
499 ERR("CFSTR_SHELLIDLIST failed\n");
500 }
501 /* lock the handle */
502 LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
503 if (!lpcida)
504 {
505 ReleaseStgMedium(&medium);
506 return E_FAIL;
507 }
508
509 /* convert the data into pidl */
510 LPITEMIDLIST pidl;
511 LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
512 if (!apidl)
513 {
514 ReleaseStgMedium(&medium);
515 return E_FAIL;
516 }
517
518 CComPtr<IShellFolder> psfDesktop;
519 CComPtr<IShellFolder> psfFrom = NULL;
520
521 /* Grab the desktop shell folder */
522 hr = SHGetDesktopFolder(&psfDesktop);
523 if (FAILED(hr))
524 {
525 ERR("SHGetDesktopFolder failed\n");
526 SHFree(pidl);
527 _ILFreeaPidl(apidl, lpcida->cidl);
528 ReleaseStgMedium(&medium);
529 return E_FAIL;
530 }
531
532 /* Find source folder, this is where the clipboard data was copied from */
533 if (_ILIsDesktop(pidl))
534 {
535 /* use desktop shell folder */
536 psfFrom = psfDesktop;
537 }
538 else
539 {
540 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
541 if (FAILED(hr))
542 {
543 ERR("no IShellFolder\n");
544 SHFree(pidl);
545 _ILFreeaPidl(apidl, lpcida->cidl);
546 ReleaseStgMedium(&medium);
547 return E_FAIL;
548 }
549 }
550
551 if (bLinking)
552 {
553 WCHAR wszPath[MAX_PATH];
554 WCHAR wszTarget[MAX_PATH];
555
556 TRACE("target path = %s\n", debugstr_w(m_sPathTarget));
557
558 /* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
559 for (UINT i = 0; i < lpcida->cidl; i++)
560 {
561 // Find out which file we're linking.
562 STRRET strFile;
563 hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strFile);
565 break;
566
567 hr = StrRetToBufW(&strFile, apidl[i], wszPath, _countof(wszPath));
569 break;
570
571 TRACE("source path = %s\n", debugstr_w(wszPath));
572
573 WCHAR wszDisplayName[MAX_PATH];
574 LPWSTR pwszFileName = PathFindFileNameW(wszPath);
575 if (PathIsRootW(wszPath)) // Drive?
576 {
577 hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_NORMAL, &strFile);
579 break;
580
581 hr = StrRetToBufW(&strFile, apidl[i], wszDisplayName, _countof(wszDisplayName));
583 break;
584
585 // Delete a ':' in wszDisplayName.
586 LPWSTR pch0 = wcschr(wszDisplayName, L':');
587 if (pch0)
588 {
589 do
590 {
591 *pch0 = *(pch0 + 1);
592 ++pch0;
593 } while (*pch0);
594 }
595
596 pwszFileName = wszDisplayName; // Use wszDisplayName
597 }
598 else if (wszPath[0] == L':' && wszPath[1] == L':') // ::{GUID}?
599 {
600 CLSID clsid;
601 hr = ::CLSIDFromString(&wszPath[2], &clsid);
602 if (SUCCEEDED(hr))
603 {
604 LPITEMIDLIST pidl = ILCreateFromPathW(wszPath);
605 if (pidl)
606 {
607 SHFILEINFOW fi = { NULL };
608 SHGetFileInfoW((LPCWSTR)pidl, 0, &fi, sizeof(fi),
610 if (fi.szDisplayName[0])
611 {
612 lstrcpynW(wszDisplayName, fi.szDisplayName, _countof(wszDisplayName));
613 pwszFileName = wszDisplayName; // Use wszDisplayName
614 }
615 ILFree(pidl);
616 }
617 }
618 }
619
620 // Creating a buffer to hold the combined path.
621 WCHAR wszCombined[MAX_PATH];
622 PathCombineW(wszCombined, m_sPathTarget, pwszFileName);
623
624 // Check to see if the source is a link
625 BOOL fSourceIsLink = FALSE;
626 if (!wcsicmp(PathFindExtensionW(wszPath), L".lnk"))
627 {
628 fSourceIsLink = TRUE;
629 PathRemoveExtensionW(wszCombined);
630 }
631
632 // Create a pathname to save the new link.
633 _GetUniqueFileName(wszCombined, L".lnk", wszTarget, TRUE);
634
635 CComPtr<IPersistFile> ppf;
636 if (fSourceIsLink)
637 {
640 break;
641 }
642 else
643 {
644 CComPtr<IShellLinkW> pLink;
645 hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
647 break;
648
649 WCHAR szDirPath[MAX_PATH], *pwszFile;
650 GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile);
651 if (pwszFile)
652 pwszFile[0] = 0;
653
654 hr = pLink->SetPath(wszPath);
656 break;
657
658 hr = pLink->SetWorkingDirectory(szDirPath);
660 break;
661
662 hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
664 break;
665 }
666
667 hr = ppf->Save(wszTarget, !fSourceIsLink);
669 break;
670
672 }
673 }
674 else
675 {
676 hr = _CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
677 }
678
679 SHFree(pidl);
680 _ILFreeaPidl(apidl, lpcida->cidl);
681 ReleaseStgMedium(&medium);
682 }
683 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
684 {
685 FORMATETC fmt2;
686 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
687 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
688 {
689 WCHAR wszTargetPath[MAX_PATH + 1];
690 LPWSTR pszSrcList;
691
692 wcscpy(wszTargetPath, m_sPathTarget);
693 //Double NULL terminate.
694 wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
695
696 LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
697 if (!lpdf)
698 {
699 ERR("Error locking global\n");
700 return E_FAIL;
701 }
702 pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
703 ERR("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath), bCopy);
704
706 ZeroMemory(&op, sizeof(op));
707 op.pFrom = pszSrcList;
708 op.pTo = wszTargetPath;
709 op.hwnd = m_hwndSite;
710 op.wFunc = bCopy ? FO_COPY : FO_MOVE;
712 int res = SHFileOperationW(&op);
713 if (res)
714 {
715 ERR("SHFileOperationW failed with 0x%x\n", res);
716 hr = E_FAIL;
717 }
718
719 return hr;
720 }
721 ERR("Error calling GetData\n");
722 hr = E_FAIL;
723 }
724 else
725 {
726 ERR("No viable drop format.\n");
727 hr = E_FAIL;
728 }
729 return hr;
730}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#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)
#define TRUE
Definition: types.h:120
#define wcschr
Definition: compat.h:17
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
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
BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
Definition: path.c:1642
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:194
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
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 FAILED(hr)
Definition: intsafe.h:51
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST *pidl, const CIDA *cida)
Definition: pidl.c:2684
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2646
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:982
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:415
#define SHGFI_DISPLAYNAME
Definition: shellapi.h:163
#define SHGFI_PIDL
Definition: shellapi.h:177
struct CIDA * LPIDA
#define SHCNE_CREATE
Definition: shlobj.h:1743
#define SHCNF_PATHW
Definition: shlobj.h:1777
struct _DROPFILES * LPDROPFILES
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:68
Definition: shlobj.h:499
UINT cidl
Definition: shlobj.h:499
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:372
Definition: dsound.c:943
#define ZeroMemory
Definition: winbase.h:1670
#define GetFullPathName
Definition: winbase.h:3692
#define IID_PPV_ARG(Itype, ppType)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by Drop().

◆ _DoDropThreadProc()

DWORD WINAPI CFSDropTarget::_DoDropThreadProc ( LPVOID  lpParameter)
staticprivate

Definition at line 732 of file CFSDropTarget.cpp.

733{
735 _DoDropData *data = static_cast<_DoDropData*>(lpParameter);
736 CComPtr<IDataObject> pDataObject;
738
739 if (SUCCEEDED(hr))
740 {
741 CComPtr<IAsyncOperation> pAsyncOperation;
742 hr = data->This->_DoDrop(pDataObject, data->dwKeyState, data->pt, &data->pdwEffect);
743 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
744 {
745 pAsyncOperation->EndOperation(hr, NULL, data->pdwEffect);
746 }
747 }
748 //Release the CFSFolder and data object holds in the copying thread.
749 data->This->Release();
750 //Release the parameter from the heap.
753 return 0;
754}
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 190 of file CFSDropTarget.cpp.

191{
193 if (!hmenu)
194 return E_OUTOFMEMORY;
195
197
198 if ((dwAvailableEffects & DROPEFFECT_COPY) == 0)
200 else if ((dwAvailableEffects & DROPEFFECT_MOVE) == 0)
202 else if ((dwAvailableEffects & DROPEFFECT_LINK) == 0)
204
205 if ((*pdwEffect & DROPEFFECT_COPY))
207 else if ((*pdwEffect & DROPEFFECT_MOVE))
209 else if ((*pdwEffect & DROPEFFECT_LINK))
211
212 /* FIXME: We need to support shell extensions here */
213
214 /* We shouldn't use the site window here because the menu should work even when we don't have a site */
215 HWND hwndDummy = CreateWindowEx(0,
216 WC_STATIC,
217 NULL,
219 pt.x,
220 pt.y,
221 1,
222 1,
223 NULL,
224 NULL,
225 NULL,
226 NULL);
227
228 UINT uCommand = TrackPopupMenu(hpopupmenu,
230 pt.x, pt.y, 0, hwndDummy, NULL);
231
232 DestroyWindow(hwndDummy);
233
234 if (uCommand == 0)
235 return S_FALSE;
236 else if (uCommand == IDM_COPYHERE)
237 *pdwEffect = DROPEFFECT_COPY;
238 else if (uCommand == IDM_MOVEHERE)
239 *pdwEffect = DROPEFFECT_MOVE;
240 else if (uCommand == IDM_LINKHERE)
241 *pdwEffect = DROPEFFECT_LINK;
242
243 return S_OK;
244}
#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:60
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:849
#define IDM_MOVEHERE
Definition: shresdef.h:851
#define IDM_LINKHERE
Definition: shresdef.h:852
#define IDM_COPYHERE
Definition: shresdef.h:850
static HMENU hmenu
Definition: win.c:66
#define S_FALSE
Definition: winerror.h:2357
#define CreateWindowEx
Definition: winuser.h:5745
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_RIGHTBUTTON
Definition: winuser.h:2370
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_NONOTIFY
Definition: winuser.h:2376
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define TPM_LEFTALIGN
Definition: winuser.h:2367
#define TPM_LEFTBUTTON
Definition: winuser.h:2369
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:2377
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by Drop().

◆ _GetUniqueFileName()

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

Definition at line 138 of file CFSDropTarget.cpp.

139{
140 WCHAR wszLink[40];
141
142 if (!bShortcut)
143 {
144 if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink)))
145 wszLink[0] = L'\0';
146 }
147
148 if (!bShortcut)
149 swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt);
150 else
151 swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt);
152
153 for (UINT i = 2; PathFileExistsW(pwszTarget); ++i)
154 {
155 if (!bShortcut)
156 swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt);
157 else
158 swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt);
159 }
160
161 return TRUE;
162}
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
#define swprintf
Definition: precomp.h:40
#define IDS_LNK_FILE
Definition: shresdef.h:176
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 167 of file CFSDropTarget.cpp.

168{
169 /* TODO Windows does different drop effects if dragging across drives.
170 i.e., it will copy instead of move if the directories are on different disks. */
171
172 DWORD dwEffect = m_dwDefaultEffect;
173
174 *pdwEffect = DROPEFFECT_NONE;
175
176 if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */
177 *pdwEffect = KeyStateToDropEffect (dwKeyState);
178
179 if (*pdwEffect == DROPEFFECT_NONE)
180 *pdwEffect = dwEffect;
181
182 /* ... matches the desired effect ? */
183 if (dwEffect & *pdwEffect) {
184 return TRUE;
185 }
186 }
187 return FALSE;
188}
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:95

Referenced by DragOver(), and Drop().

◆ _RepositionItems()

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

Definition at line 246 of file CFSDropTarget.cpp.

247{
248 CComPtr<IFolderView> pfv;
249 POINT ptDrag;
252 return hr;
253
254 hr = psfv->GetDragPoint(&ptDrag);
256 return hr;
257
258 PIDLIST_ABSOLUTE pidlFolder;
259 PUITEMID_CHILD *apidl;
260 UINT cidl;
261 hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
263 return hr;
264
265 CComHeapPtr<POINT> apt;
266 if (!apt.Allocate(cidl))
267 {
268 SHFree(pidlFolder);
269 _ILFreeaPidl(apidl, cidl);
270 return E_OUTOFMEMORY;
271 }
272
273 for (UINT i = 0; i<cidl; i++)
274 {
275 pfv->GetItemPosition(apidl[i], &apt[i]);
276 apt[i].x += pt.x - ptDrag.x;
277 apt[i].y += pt.y - ptDrag.y;
278 }
279
280 pfv->SelectAndPositionItems(cidl, apidl, apt, SVSI_SELECT);
281
282 SHFree(pidlFolder);
283 _ILFreeaPidl(apidl, cidl);
284 return S_OK;
285}
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:328
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 
)
virtual

Implements IDropTarget.

Definition at line 287 of file CFSDropTarget.cpp.

289{
290 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
291
292 if (*pdwEffect == DROPEFFECT_NONE)
293 return S_OK;
294
295 FORMATETC fmt;
296 FORMATETC fmt2;
298
299 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
300 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
301
302 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
304 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
306
307 m_grfKeyState = dwKeyState;
308
309#define D_NONE DROPEFFECT_NONE
310#define D_COPY DROPEFFECT_COPY
311#define D_MOVE DROPEFFECT_MOVE
312#define D_LINK DROPEFFECT_LINK
313 m_dwDefaultEffect = *pdwEffect;
314 switch (*pdwEffect & (D_COPY | D_MOVE | D_LINK))
315 {
316 case D_COPY | D_MOVE:
317 if (dwKeyState & MK_CONTROL)
319 else
321 break;
322 case D_COPY | D_MOVE | D_LINK:
323 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
325 else if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == MK_CONTROL)
327 else
329 break;
330 case D_COPY | D_LINK:
331 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
333 else
335 break;
336 case D_MOVE | D_LINK:
337 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
339 else
341 break;
342 }
343
344 STGMEDIUM medium;
345 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)))
346 {
347 WCHAR wstrFirstFile[MAX_PATH];
348 if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, _countof(wstrFirstFile)))
349 {
350 /* Check if the drive letter is different */
351 if (wstrFirstFile[0] != m_sPathTarget[0])
352 {
354 }
355 }
356 ReleaseStgMedium(&medium);
357 }
358
359 if (!m_fAcceptFmt)
360 *pdwEffect = DROPEFFECT_NONE;
361 else
362 *pdwEffect = m_dwDefaultEffect;
363
364 return S_OK;
365}
#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:2359
#define MK_CONTROL
Definition: winuser.h:2360

◆ DragLeave()

HRESULT WINAPI CFSDropTarget::DragLeave ( void  )
virtual

Implements IDropTarget.

Definition at line 382 of file CFSDropTarget.cpp.

383{
384 TRACE("(%p)\n", this);
385
387
388 return S_OK;
389}

◆ DragOver()

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

Implements IDropTarget.

Definition at line 367 of file CFSDropTarget.cpp.

369{
370 TRACE("(%p)\n", this);
371
372 if (!pdwEffect)
373 return E_INVALIDARG;
374
375 m_grfKeyState = dwKeyState;
376
377 _QueryDrop(dwKeyState, pdwEffect);
378
379 return S_OK;
380}
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 
)
virtual

Implements IDropTarget.

Definition at line 391 of file CFSDropTarget.cpp.

393{
394 TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
395
396 if (!pdwEffect)
397 return E_INVALIDARG;
398
400
401 DWORD dwAvailableEffects = *pdwEffect;
402
403 _QueryDrop(dwKeyState, pdwEffect);
404
405 TRACE("pdwEffect: 0x%x, m_dwDefaultEffect: 0x%x, dwAvailableEffects: 0x%x\n", *pdwEffect, m_dwDefaultEffect, dwAvailableEffects);
406
408 {
409 HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect, dwAvailableEffects);
410 if (FAILED_UNEXPECTEDLY(hr) || hr == S_FALSE)
411 return hr;
412 }
413
414 if (*pdwEffect == DROPEFFECT_MOVE && m_site)
415 {
416 CComPtr<IShellFolderView> psfv;
418 if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK)
419 {
420 _RepositionItems(psfv, pDataObject, pt);
421 return S_OK;
422 }
423 }
424
425 BOOL fIsOpAsync = FALSE;
426 CComPtr<IAsyncOperation> pAsyncOperation;
427
428 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
429 {
430 if (SUCCEEDED(pAsyncOperation->GetAsyncMode(&fIsOpAsync)) && fIsOpAsync)
431 {
432 _DoDropData *data = static_cast<_DoDropData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData)));
433 data->This = this;
434 // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder).
435 pDataObject->AddRef();
436 pAsyncOperation->StartOperation(NULL);
438 this->AddRef();
439 data->dwKeyState = dwKeyState;
440 data->pt = pt;
441 // Need to dereference as pdweffect gets freed.
442 data->pdwEffect = *pdwEffect;
444 return S_OK;
445 }
446 }
447 return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
448}
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)
#define HeapAlloc
Definition: compat.h:733
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1494
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1329
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:2358

◆ GetSite()

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

Definition at line 460 of file CFSDropTarget.cpp.

461{
462 if (!m_site)
463 return E_FAIL;
464
465 return m_site->QueryInterface(riid, ppvSite);
466}
REFIID riid
Definition: atlbase.h:39

◆ Initialize()

HRESULT CFSDropTarget::Initialize ( LPWSTR  PathTarget)

Definition at line 114 of file CFSDropTarget.cpp.

115{
116 if (!PathTarget)
117 return E_UNEXPECTED;
118
120 if (!m_cfShellIDList)
121 return E_FAIL;
122
123 m_sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR));
124 if (!m_sPathTarget)
125 return E_OUTOFMEMORY;
126
127 wcscpy(m_sPathTarget, PathTarget);
128
129 return S_OK;
130}
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:477
#define E_UNEXPECTED
Definition: winerror.h:2456
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)

◆ SetSite()

HRESULT WINAPI CFSDropTarget::SetSite ( IUnknown pUnkSite)
virtual

Implements IObjectWithSite.

Definition at line 452 of file CFSDropTarget.cpp.

453{
454 m_site = pUnkSite;
455 return S_OK;
456}

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: