ReactOS  0.4.15-dev-1201-gb2cf5a4
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  TRACE("Deleting file (just the first) = %s, allowundo: %d\n", debugstr_w(FileOp.pFrom), (FileOp.fFlags == FOF_ALLOWUNDO));
60 
61  int res = SHFileOperationW(&FileOp);
62  if (res)
63  {
64  ERR("SHFileOperation failed with 0x%x\n", res);
65  hr = E_FAIL;
66  }
67 
68  ReleaseStgMedium(&medium);
69 
70  return hr;
71  }
72 
76  };
77 
79  {
80  DeleteThreadData *data = static_cast<DeleteThreadData*>(lpParameter);
82  IDataObject *pDataObject;
84  if (SUCCEEDED(hr))
85  {
86  _DoDeleteDataObject(pDataObject, data->fMask);
87  }
88  pDataObject->Release();
91  return 0;
92  }
93 
94  static void _DoDeleteAsync(IDataObject *pda, DWORD fMask)
95  {
96  DeleteThreadData *data = static_cast<DeleteThreadData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(DeleteThreadData)));
97  data->fMask = fMask;
100  }
101 
102  public:
103 
105  {
106  fAcceptFmt = FALSE;
108  }
109 
111  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
112  {
113  TRACE("Recycle bin drag over (%p)\n", this);
114  /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
115  fAcceptFmt = TRUE;
116 
117  *pdwEffect = DROPEFFECT_MOVE;
118  return S_OK;
119  }
120 
121  HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
122  {
123  TRACE("(%p)\n", this);
124 
125  if (!pdwEffect)
126  return E_INVALIDARG;
127 
128  *pdwEffect = DROPEFFECT_MOVE;
129 
130  return S_OK;
131  }
132 
134  {
135  TRACE("(%p)\n", this);
136 
137  fAcceptFmt = FALSE;
138 
139  return S_OK;
140  }
141 
143  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
144  {
145  TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
146 
147  /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
148 
149  FORMATETC fmt;
150  TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
151  InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
152 
153  /* Handle cfShellIDList Drop objects here, otherwise send the appropriate message to other software */
154  if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
155  {
156  DWORD fMask = 0;
157 
158  if ((dwKeyState & MK_SHIFT) == MK_SHIFT)
159  fMask |= CMIC_MASK_SHIFT_DOWN;
160 
161  _DoDeleteAsync(pDataObject, fMask);
162  }
163  else
164  {
165  /*
166  * TODO call SetData on the data object with format CFSTR_TARGETCLSID
167  * set to the Recycle Bin's class identifier CLSID_RecycleBin.
168  */
169  }
170  return S_OK;
171  }
172 
174 
176 
178  COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
179  END_COM_MAP()
180 };
181 
183 {
184  return ShellObjectCreator<CRecyclerDropTarget>(riid, ppvOut);
185 }
struct _DROPFILES * LPDROPFILES
HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
#define REFIID
Definition: guiddef.h:118
HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
#define MK_SHIFT
Definition: winuser.h:2344
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:477
HRESULT hr
Definition: shlfolder.c:183
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
#define TRUE
Definition: types.h:120
#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)
#define ZeroMemory
Definition: winbase.h:1648
#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:1918
#define FALSE
Definition: types.h:117
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:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG HRESULT
Definition: typedefs.h:79
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define WINAPI
Definition: msvc.h:6
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:110
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
#define S_OK
Definition: intsafe.h:51
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
GLuint res
Definition: glext.h:9613
#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:594
static DWORD WINAPI _DoDeleteThreadProc(LPVOID lpParameter)
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static HRESULT _DoDeleteDataObject(IDataObject *pda, DWORD fMask)