ReactOS  0.4.14-dev-358-gbef841c
CRecyclerDropTarget.cpp
Go to the documentation of this file.
1 /*
2  * Trash virtual folder support. The trashing engine is implemented in trash.c
3  *
4  * Copyright (C) 2006 Mikolaj Zalewski
5  * Copyright (C) 2009 Andrew Hill
6  * Copyright (C) 2017 Giannis Adamopoulos
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <precomp.h>
24 
26 
28  public CComObjectRootEx<CComMultiThreadModelNoCS>,
29  public IDropTarget
30 {
31  private:
32  BOOL fAcceptFmt; /* flag for pending Drop */
34 
36  {
37  HRESULT hr;
38  STGMEDIUM medium;
39  FORMATETC formatetc;
40  InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
41  hr = pda->GetData(&formatetc, &medium);
43  return hr;
44 
45  LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
46  if (!lpdf)
47  {
48  ERR("Error locking global\n");
49  return E_FAIL;
50  }
51 
52  /* Delete them */
53  SHFILEOPSTRUCTW FileOp;
54  ZeroMemory(&FileOp, sizeof(FileOp));
55  FileOp.wFunc = FO_DELETE;
56  FileOp.pFrom = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);;
57  if ((fMask & CMIC_MASK_SHIFT_DOWN) == 0)
58  FileOp.fFlags = FOF_ALLOWUNDO;
59  ERR("Deleting file (just the first) = %s, allowundo: %d\n", debugstr_w(FileOp.pFrom), (FileOp.fFlags == FOF_ALLOWUNDO));
60 
61  if (SHFileOperationW(&FileOp) != 0)
62  {
63  ERR("SHFileOperation failed with 0x%x\n", GetLastError());
64  hr = E_FAIL;
65  }
66 
67  ReleaseStgMedium(&medium);
68 
69  return hr;
70  }
71 
75  };
76 
78  {
79  DeleteThreadData *data = static_cast<DeleteThreadData*>(lpParameter);
81  IDataObject *pDataObject;
83  if (SUCCEEDED(hr))
84  {
85  _DoDeleteDataObject(pDataObject, data->fMask);
86  }
87  pDataObject->Release();
90  return 0;
91  }
92 
93  static void _DoDeleteAsync(IDataObject *pda, DWORD fMask)
94  {
95  DeleteThreadData *data = static_cast<DeleteThreadData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(DeleteThreadData)));
96  data->fMask = fMask;
99  }
100 
101  public:
102 
104  {
105  fAcceptFmt = FALSE;
107  }
108 
110  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
111  {
112  TRACE("Recycle bin drag over (%p)\n", this);
113  /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
114  fAcceptFmt = TRUE;
115 
116  *pdwEffect = DROPEFFECT_MOVE;
117  return S_OK;
118  }
119 
120  HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
121  {
122  TRACE("(%p)\n", this);
123 
124  if (!pdwEffect)
125  return E_INVALIDARG;
126 
127  *pdwEffect = DROPEFFECT_MOVE;
128 
129  return S_OK;
130  }
131 
133  {
134  TRACE("(%p)\n", this);
135 
136  fAcceptFmt = FALSE;
137 
138  return S_OK;
139  }
140 
142  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
143  {
144  TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
145 
146  /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
147 
148  FORMATETC fmt;
149  TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
150  InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
151 
152  /* Handle cfShellIDList Drop objects here, otherwise send the appropriate message to other software */
153  if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
154  {
155  DWORD fMask = 0;
156 
157  if ((dwKeyState & MK_SHIFT) == MK_SHIFT)
158  fMask |= CMIC_MASK_SHIFT_DOWN;
159 
160  _DoDeleteAsync(pDataObject, fMask);
161  }
162  else
163  {
164  /*
165  * TODO call SetData on the data object with format CFSTR_TARGETCLSID
166  * set to the Recycle Bin's class identifier CLSID_RecycleBin.
167  */
168  }
169  return S_OK;
170  }
171 
173 
175 
177  COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
178  END_COM_MAP()
179 };
180 
182 {
183  return ShellObjectCreator<CRecyclerDropTarget>(riid, ppvOut);
184 }
struct _DROPFILES * LPDROPFILES
HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
#define MK_SHIFT
Definition: winuser.h:2344
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:469
HRESULT hr
Definition: shlfolder.c:183
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:33
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
#define pt(x, y)
Definition: drawing.c:79
REFIID riid
Definition: precomp.h:44
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
const char * fmt
Definition: wsprintf.c:30
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid, LPVOID *ppv)
Definition: marshal.c:2144
#define FOF_ALLOWUNDO
Definition: shellapi.h:144
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
#define DECLARE_NOT_AGGREGATABLE(x)
Definition: atlcom.h:611
const GUID IID_IDataObject
static void _DoDeleteAsync(IDataObject *pda, DWORD fMask)
FILEOP_FLAGS fFlags
Definition: shellapi.h:357
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1782
HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
unsigned int BOOL
Definition: ntddk_ex.h:94
WINE_DEFAULT_DEBUG_CHANNEL(shell)
#define debugstr_w
Definition: kernel32.h:32
ULONG Release()
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define CF_HDROP
Definition: constants.h:410
HRESULT WINAPI DragLeave()
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG HRESULT
Definition: typedefs.h:77
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPCWSTR pFrom
Definition: shellapi.h:355
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
LPVOID lpParameter
Definition: kernel32.h:241
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)
#define ERR(fmt,...)
Definition: debug.h:109
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
#define S_OK
Definition: intsafe.h:59
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
HRESULT QueryGetData([in, unique] FORMATETC *pformatetc)
unsigned int UINT
Definition: ndis.h:50
#define DECLARE_PROTECT_FINAL_CONSTRUCT()
Definition: atlcom.h:639
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
#define END_COM_MAP()
Definition: atlcom.h:552
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
#define FO_DELETE
Definition: shellapi.h:135
Definition: dsound.c:943
#define HeapFree(x, y, z)
Definition: compat.h:402
static DWORD WINAPI _DoDeleteThreadProc(LPVOID lpParameter)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT _DoDeleteDataObject(IDataObject *pda, DWORD fMask)