ReactOS 0.4.15-dev-7889-g76290a6
CFSDropTarget.cpp
Go to the documentation of this file.
1
2/*
3 * file system folder drop target
4 *
5 * Copyright 1997 Marcus Meissner
6 * Copyright 1998, 1999, 2002 Juergen Schmied
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
27
28/****************************************************************************
29 * CFSDropTarget::_CopyItems
30 *
31 * copies or moves items to this folder
32 */
34 LPCITEMIDLIST * apidl, BOOL bCopy)
35{
37 WCHAR wszDstPath[MAX_PATH + 1] = {0};
38 PWCHAR pwszSrcPathsList = (PWCHAR) HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
39 if (!pwszSrcPathsList)
40 return E_OUTOFMEMORY;
41
42 PWCHAR pwszListPos = pwszSrcPathsList;
43 STRRET strretFrom;
45 BOOL bRenameOnCollision = FALSE;
46
47 /* Build a double null terminated list of C strings from source paths */
48 for (UINT i = 0; i < cidl; i++)
49 {
50 ret = pSFFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strretFrom);
51 if (FAILED(ret))
52 goto cleanup;
53
54 ret = StrRetToBufW(&strretFrom, NULL, pwszListPos, MAX_PATH);
55 if (FAILED(ret))
56 goto cleanup;
57
58 pwszListPos += lstrlenW(pwszListPos) + 1;
59 }
60 /* Append the final null. */
61 *pwszListPos = L'\0';
62
63 /* Build a double null terminated target (this path) */
65 if (FAILED(ret))
66 goto cleanup;
67
68 wszDstPath[lstrlenW(wszDstPath) + 1] = UNICODE_NULL;
69
70 /* Set bRenameOnCollision to TRUE if necesssary */
71 if (bCopy)
72 {
73 WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
74 GetFullPathNameW(pwszSrcPathsList, _countof(szPath1), szPath1, NULL);
75 GetFullPathNameW(wszDstPath, _countof(szPath2), szPath2, NULL);
76 PathRemoveFileSpecW(szPath1);
77 if (_wcsicmp(szPath1, szPath2) == 0)
78 bRenameOnCollision = TRUE;
79 }
80
81 ZeroMemory(&fop, sizeof(fop));
82 fop.hwnd = m_hwndSite;
83 fop.wFunc = bCopy ? FO_COPY : FO_MOVE;
84 fop.pFrom = pwszSrcPathsList;
85 fop.pTo = wszDstPath;
87 if (bRenameOnCollision)
89
90 ret = S_OK;
91
92 if (SHFileOperationW(&fop))
93 {
94 ERR("SHFileOperationW failed\n");
95 ret = E_FAIL;
96 }
97
99 HeapFree(GetProcessHeap(), 0, pwszSrcPathsList);
100 return ret;
101}
102
104 m_cfShellIDList(0),
105 m_fAcceptFmt(FALSE),
106 m_sPathTarget(NULL),
107 m_hwndSite(NULL),
108 m_grfKeyState(0)
109{
110}
111
113{
114 if (!PathTarget)
115 return E_UNEXPECTED;
116
118 if (!m_cfShellIDList)
119 return E_FAIL;
120
121 m_sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR));
122 if (!m_sPathTarget)
123 return E_OUTOFMEMORY;
124
125 wcscpy(m_sPathTarget, PathTarget);
126
127 return S_OK;
128}
129
131{
133}
134
135BOOL
136CFSDropTarget::_GetUniqueFileName(LPCWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
137{
138 WCHAR wszLink[40];
139
140 if (!bShortcut)
141 {
142 if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink)))
143 wszLink[0] = L'\0';
144 }
145
146 if (!bShortcut)
147 swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt);
148 else
149 swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt);
150
151 for (UINT i = 2; PathFileExistsW(pwszTarget); ++i)
152 {
153 if (!bShortcut)
154 swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt);
155 else
156 swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt);
157 }
158
159 return TRUE;
160}
161
162/****************************************************************************
163 * IDropTarget implementation
164 */
166{
167 /* TODO Windows does different drop effects if dragging across drives.
168 i.e., it will copy instead of move if the directories are on different disks. */
169
170 DWORD dwEffect = m_dwDefaultEffect;
171
172 *pdwEffect = DROPEFFECT_NONE;
173
174 if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */
175 *pdwEffect = KeyStateToDropEffect (dwKeyState);
176
177 if (*pdwEffect == DROPEFFECT_NONE)
178 *pdwEffect = dwEffect;
179
180 /* ... matches the desired effect ? */
181 if (dwEffect & *pdwEffect) {
182 return TRUE;
183 }
184 }
185 return FALSE;
186}
187
188HRESULT CFSDropTarget::_GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
189{
191 if (!hmenu)
192 return E_OUTOFMEMORY;
193
195
196 if ((dwAvailableEffects & DROPEFFECT_COPY) == 0)
198 else if ((dwAvailableEffects & DROPEFFECT_MOVE) == 0)
200 else if ((dwAvailableEffects & DROPEFFECT_LINK) == 0)
202
203 if ((*pdwEffect & DROPEFFECT_COPY))
205 else if ((*pdwEffect & DROPEFFECT_MOVE))
207 else if ((*pdwEffect & DROPEFFECT_LINK))
209
210 /* FIXME: We need to support shell extensions here */
211
212 /* We shouldn't use the site window here because the menu should work even when we don't have a site */
213 HWND hwndDummy = CreateWindowEx(0,
214 WC_STATIC,
215 NULL,
217 pt.x,
218 pt.y,
219 1,
220 1,
221 NULL,
222 NULL,
223 NULL,
224 NULL);
225
226 UINT uCommand = TrackPopupMenu(hpopupmenu,
228 pt.x, pt.y, 0, hwndDummy, NULL);
229
230 DestroyWindow(hwndDummy);
231
232 if (uCommand == 0)
233 return S_FALSE;
234 else if (uCommand == IDM_COPYHERE)
235 *pdwEffect = DROPEFFECT_COPY;
236 else if (uCommand == IDM_MOVEHERE)
237 *pdwEffect = DROPEFFECT_MOVE;
238 else if (uCommand == IDM_LINKHERE)
239 *pdwEffect = DROPEFFECT_LINK;
240
241 return S_OK;
242}
243
245{
246 CComPtr<IFolderView> pfv;
247 POINT ptDrag;
250 return hr;
251
252 hr = psfv->GetDragPoint(&ptDrag);
254 return hr;
255
256 PIDLIST_ABSOLUTE pidlFolder;
257 PUITEMID_CHILD *apidl;
258 UINT cidl;
259 hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
261 return hr;
262
263 CComHeapPtr<POINT> apt;
264 if (!apt.Allocate(cidl))
265 {
266 SHFree(pidlFolder);
267 _ILFreeaPidl(apidl, cidl);
268 return E_OUTOFMEMORY;
269 }
270
271 for (UINT i = 0; i<cidl; i++)
272 {
273 pfv->GetItemPosition(apidl[i], &apt[i]);
274 apt[i].x += pt.x - ptDrag.x;
275 apt[i].y += pt.y - ptDrag.y;
276 }
277
278 pfv->SelectAndPositionItems(cidl, apidl, apt, SVSI_SELECT);
279
280 SHFree(pidlFolder);
281 _ILFreeaPidl(apidl, cidl);
282 return S_OK;
283}
284
286 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
287{
288 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
289
290 if (*pdwEffect == DROPEFFECT_NONE)
291 return S_OK;
292
293 FORMATETC fmt;
294 FORMATETC fmt2;
296
297 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
298 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
299
300 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
302 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
304
305 m_grfKeyState = dwKeyState;
306
307#define D_NONE DROPEFFECT_NONE
308#define D_COPY DROPEFFECT_COPY
309#define D_MOVE DROPEFFECT_MOVE
310#define D_LINK DROPEFFECT_LINK
311 m_dwDefaultEffect = *pdwEffect;
312 switch (*pdwEffect & (D_COPY | D_MOVE | D_LINK))
313 {
314 case D_COPY | D_MOVE:
315 if (dwKeyState & MK_CONTROL)
317 else
319 break;
320 case D_COPY | D_MOVE | D_LINK:
321 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
323 else if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == MK_CONTROL)
325 else
327 break;
328 case D_COPY | D_LINK:
329 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
331 else
333 break;
334 case D_MOVE | D_LINK:
335 if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
337 else
339 break;
340 }
341
342 STGMEDIUM medium;
343 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)))
344 {
345 WCHAR wstrFirstFile[MAX_PATH];
346 if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, _countof(wstrFirstFile)))
347 {
348 /* Check if the drive letter is different */
349 if (wstrFirstFile[0] != m_sPathTarget[0])
350 {
352 }
353 }
354 ReleaseStgMedium(&medium);
355 }
356
357 if (!m_fAcceptFmt)
358 *pdwEffect = DROPEFFECT_NONE;
359 else
360 *pdwEffect = m_dwDefaultEffect;
361
362 return S_OK;
363}
364
366 DWORD *pdwEffect)
367{
368 TRACE("(%p)\n", this);
369
370 if (!pdwEffect)
371 return E_INVALIDARG;
372
373 m_grfKeyState = dwKeyState;
374
375 _QueryDrop(dwKeyState, pdwEffect);
376
377 return S_OK;
378}
379
381{
382 TRACE("(%p)\n", this);
383
385
386 return S_OK;
387}
388
390 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
391{
392 TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
393
394 if (!pdwEffect)
395 return E_INVALIDARG;
396
398
399 DWORD dwAvailableEffects = *pdwEffect;
400
401 _QueryDrop(dwKeyState, pdwEffect);
402
403 TRACE("pdwEffect: 0x%x, m_dwDefaultEffect: 0x%x, dwAvailableEffects: 0x%x\n", *pdwEffect, m_dwDefaultEffect, dwAvailableEffects);
404
406 {
407 HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect, dwAvailableEffects);
408 if (FAILED_UNEXPECTEDLY(hr) || hr == S_FALSE)
409 return hr;
410 }
411
412 if (*pdwEffect == DROPEFFECT_MOVE && m_site)
413 {
414 CComPtr<IShellFolderView> psfv;
416 if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK)
417 {
418 _RepositionItems(psfv, pDataObject, pt);
419 return S_OK;
420 }
421 }
422
423 BOOL fIsOpAsync = FALSE;
424 CComPtr<IAsyncOperation> pAsyncOperation;
425
426 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
427 {
428 if (SUCCEEDED(pAsyncOperation->GetAsyncMode(&fIsOpAsync)) && fIsOpAsync)
429 {
430 _DoDropData *data = static_cast<_DoDropData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData)));
431 data->This = this;
432 // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder).
433 pDataObject->AddRef();
434 pAsyncOperation->StartOperation(NULL);
436 this->AddRef();
437 data->dwKeyState = dwKeyState;
438 data->pt = pt;
439 // Need to dereference as pdweffect gets freed.
440 data->pdwEffect = *pdwEffect;
442 return S_OK;
443 }
444 }
445 return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
446}
447
449WINAPI
451{
452 m_site = pUnkSite;
453 return S_OK;
454}
455
457WINAPI
459{
460 if (!m_site)
461 return E_FAIL;
462
463 return m_site->QueryInterface(riid, ppvSite);
464}
465
467 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
468{
469 TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
470 FORMATETC fmt;
471 FORMATETC fmt2;
472 STGMEDIUM medium;
473
474 InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
475 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
476
477 HRESULT hr;
478 bool bCopy = TRUE;
479 bool bLinking = FALSE;
480
481 /* Figure out what drop operation we're doing */
482 if (pdwEffect)
483 {
484 TRACE("Current drop effect flag %i\n", *pdwEffect);
485 if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
486 bCopy = FALSE;
487 if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
488 bLinking = TRUE;
489 }
490
491 if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
492 {
493 hr = pDataObject->GetData(&fmt, &medium);
494 TRACE("CFSTR_SHELLIDLIST\n");
495 if (FAILED(hr))
496 {
497 ERR("CFSTR_SHELLIDLIST failed\n");
498 }
499 /* lock the handle */
500 LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
501 if (!lpcida)
502 {
503 ReleaseStgMedium(&medium);
504 return E_FAIL;
505 }
506
507 /* convert the data into pidl */
508 LPITEMIDLIST pidl;
509 LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
510 if (!apidl)
511 {
512 ReleaseStgMedium(&medium);
513 return E_FAIL;
514 }
515
516 CComPtr<IShellFolder> psfDesktop;
517 CComPtr<IShellFolder> psfFrom = NULL;
518
519 /* Grab the desktop shell folder */
520 hr = SHGetDesktopFolder(&psfDesktop);
521 if (FAILED(hr))
522 {
523 ERR("SHGetDesktopFolder failed\n");
524 SHFree(pidl);
525 _ILFreeaPidl(apidl, lpcida->cidl);
526 ReleaseStgMedium(&medium);
527 return E_FAIL;
528 }
529
530 /* Find source folder, this is where the clipboard data was copied from */
531 if (_ILIsDesktop(pidl))
532 {
533 /* use desktop shell folder */
534 psfFrom = psfDesktop;
535 }
536 else
537 {
538 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
539 if (FAILED(hr))
540 {
541 ERR("no IShellFolder\n");
542 SHFree(pidl);
543 _ILFreeaPidl(apidl, lpcida->cidl);
544 ReleaseStgMedium(&medium);
545 return E_FAIL;
546 }
547 }
548
549 if (bLinking)
550 {
551 WCHAR wszPath[MAX_PATH];
552 WCHAR wszTarget[MAX_PATH];
553
554 TRACE("target path = %s\n", debugstr_w(m_sPathTarget));
555
556 /* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
557 for (UINT i = 0; i < lpcida->cidl; i++)
558 {
559 // Find out which file we're linking.
560 STRRET strFile;
561 hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strFile);
563 break;
564
565 hr = StrRetToBufW(&strFile, apidl[i], wszPath, _countof(wszPath));
567 break;
568
569 TRACE("source path = %s\n", debugstr_w(wszPath));
570
571 WCHAR wszDisplayName[MAX_PATH];
572 LPWSTR pwszFileName = PathFindFileNameW(wszPath);
573 if (PathIsRootW(wszPath)) // Drive?
574 {
575 hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_NORMAL, &strFile);
577 break;
578
579 hr = StrRetToBufW(&strFile, apidl[i], wszDisplayName, _countof(wszDisplayName));
581 break;
582
583 // Delete a ':' in wszDisplayName.
584 LPWSTR pch0 = wcschr(wszDisplayName, L':');
585 if (pch0)
586 {
587 do
588 {
589 *pch0 = *(pch0 + 1);
590 ++pch0;
591 } while (*pch0);
592 }
593
594 pwszFileName = wszDisplayName; // Use wszDisplayName
595 }
596 else if (wszPath[0] == L':' && wszPath[1] == L':') // ::{GUID}?
597 {
598 CLSID clsid;
599 hr = ::CLSIDFromString(&wszPath[2], &clsid);
600 if (SUCCEEDED(hr))
601 {
602 LPITEMIDLIST pidl = ILCreateFromPathW(wszPath);
603 if (pidl)
604 {
605 SHFILEINFOW fi = { NULL };
606 SHGetFileInfoW((LPCWSTR)pidl, 0, &fi, sizeof(fi),
608 if (fi.szDisplayName[0])
609 {
610 lstrcpynW(wszDisplayName, fi.szDisplayName, _countof(wszDisplayName));
611 pwszFileName = wszDisplayName; // Use wszDisplayName
612 }
613 ILFree(pidl);
614 }
615 }
616 }
617
618 // Creating a buffer to hold the combined path.
619 WCHAR wszCombined[MAX_PATH];
620 PathCombineW(wszCombined, m_sPathTarget, pwszFileName);
621
622 // Check to see if the source is a link
623 BOOL fSourceIsLink = FALSE;
624 if (!wcsicmp(PathFindExtensionW(wszPath), L".lnk"))
625 {
626 fSourceIsLink = TRUE;
627 PathRemoveExtensionW(wszCombined);
628 }
629
630 // Create a pathname to save the new link.
631 _GetUniqueFileName(wszCombined, L".lnk", wszTarget, TRUE);
632
633 CComPtr<IPersistFile> ppf;
634 if (fSourceIsLink)
635 {
638 break;
639 }
640 else
641 {
642 CComPtr<IShellLinkW> pLink;
643 hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
645 break;
646
647 WCHAR szDirPath[MAX_PATH], *pwszFile;
648 GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile);
649 if (pwszFile)
650 pwszFile[0] = 0;
651
652 hr = pLink->SetPath(wszPath);
654 break;
655
656 hr = pLink->SetWorkingDirectory(szDirPath);
658 break;
659
660 hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
662 break;
663 }
664
665 hr = ppf->Save(wszTarget, !fSourceIsLink);
667 break;
668
670 }
671 }
672 else
673 {
674 hr = _CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
675 }
676
677 SHFree(pidl);
678 _ILFreeaPidl(apidl, lpcida->cidl);
679 ReleaseStgMedium(&medium);
680 }
681 else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
682 {
683 FORMATETC fmt2;
684 InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
685 if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
686 {
687 WCHAR wszTargetPath[MAX_PATH + 1];
688 LPWSTR pszSrcList;
689
690 wcscpy(wszTargetPath, m_sPathTarget);
691 //Double NULL terminate.
692 wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
693
694 LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
695 if (!lpdf)
696 {
697 ERR("Error locking global\n");
698 return E_FAIL;
699 }
700 pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
701 ERR("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath), bCopy);
702
704 ZeroMemory(&op, sizeof(op));
705 op.pFrom = pszSrcList;
706 op.pTo = wszTargetPath;
707 op.hwnd = m_hwndSite;
708 op.wFunc = bCopy ? FO_COPY : FO_MOVE;
710 int res = SHFileOperationW(&op);
711 if (res)
712 {
713 ERR("SHFileOperationW failed with 0x%x\n", res);
714 hr = E_FAIL;
715 }
716
717 return hr;
718 }
719 ERR("Error calling GetData\n");
720 hr = E_FAIL;
721 }
722 else
723 {
724 ERR("No viable drop format\n");
725 hr = E_FAIL;
726 }
727 return hr;
728}
729
731{
733 _DoDropData *data = static_cast<_DoDropData*>(lpParameter);
734 CComPtr<IDataObject> pDataObject;
736
737 if (SUCCEEDED(hr))
738 {
739 CComPtr<IAsyncOperation> pAsyncOperation;
740 hr = data->This->_DoDrop(pDataObject, data->dwKeyState, data->pt, &data->pdwEffect);
741 if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
742 {
743 pAsyncOperation->EndOperation(hr, NULL, data->pdwEffect);
744 }
745 }
746 //Release the CFSFolder and data object holds in the copying thread.
747 data->This->Release();
748 //Release the parameter from the heap.
751 return 0;
752}
753
755{
756 return ShellObjectCreatorInit<CFSDropTarget>(sPathTarget, riid, ppvOut);
757}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
HRESULT CFSDropTarget_CreateInstance(LPWSTR sPathTarget, REFIID riid, LPVOID *ppvOut)
#define D_COPY
#define D_MOVE
#define D_LINK
#define shell32_hInstance
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_HDROP
Definition: constants.h:410
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define ERR(fmt,...)
Definition: debug.h:110
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
DWORD m_dwDefaultEffect
Definition: CFSDropTarget.h:37
STDMETHOD() Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
CComPtr< IUnknown > m_site
Definition: CFSDropTarget.h:38
STDMETHOD() DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
HRESULT Initialize(LPWSTR PathTarget)
STDMETHOD() GetSite(REFIID riid, void **ppvSite) override
LPWSTR m_sPathTarget
Definition: CFSDropTarget.h:34
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter)
HRESULT _CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy)
BOOL _QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
UINT m_cfShellIDList
Definition: CFSDropTarget.h:32
HRESULT _GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
STDMETHOD() DragLeave() override
HRESULT _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
BOOL _GetUniqueFileName(LPCWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
DWORD m_grfKeyState
Definition: CFSDropTarget.h:36
STDMETHOD() DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) override
STDMETHOD() SetSite(IUnknown *pUnkSite) override
HRESULT _RepositionItems(IShellFolderView *psfv, IDataObject *pDataObject, POINTL pt)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
#define wcschr
Definition: compat.h:17
#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 wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
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
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid, LPVOID *ppv)
Definition: marshal.c:2144
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:622
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
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 PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
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
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
#define swprintf
Definition: precomp.h:40
#define pt(x, y)
Definition: drawing.c:79
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
HRESULT QueryGetData([in, unique] FORMATETC *pformatetc)
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
const DWORD DROPEFFECT_LINK
Definition: oleidl.idl:932
const DWORD DROPEFFECT_COPY
Definition: oleidl.idl:930
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
ULONG AddRef()
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_w
Definition: kernel32.h:32
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
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
const GUID IID_IDataObject
#define PathCombineW
Definition: pathcch.h:317
#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
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST *pidl, const CIDA *cida)
Definition: pidl.c:2728
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2690
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:995
#define WC_STATIC
Definition: commctrl.h:4682
#define REFIID
Definition: guiddef.h:118
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:415
#define KeyStateToDropEffect(kst)
Definition: shell32_main.h:105
#define SHGFI_DISPLAYNAME
Definition: shellapi.h:166
#define FOF_ALLOWUNDO
Definition: shellapi.h:147
#define FO_COPY
Definition: shellapi.h:137
#define FOF_RENAMEONCOLLISION
Definition: shellapi.h:144
#define SHGFI_PIDL
Definition: shellapi.h:180
#define FOF_NOCONFIRMMKDIR
Definition: shellapi.h:150
#define FO_MOVE
Definition: shellapi.h:136
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:352
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1987
HRESULT hr
Definition: shlfolder.c:183
#define SID_IFolderView
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:543
struct CIDA * LPIDA
#define SHCNE_CREATE
Definition: shlobj.h:1876
#define SHCNF_PATHW
Definition: shlobj.h:1910
struct _DROPFILES * LPDROPFILES
#define IDM_DRAGFILE
Definition: shresdef.h:872
#define IDM_MOVEHERE
Definition: shresdef.h:874
#define IDM_LINKHERE
Definition: shresdef.h:875
#define IDS_LNK_FILE
Definition: shresdef.h:177
#define IDM_COPYHERE
Definition: shresdef.h:873
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
Definition: shlobj.h:565
UINT cidl
Definition: shlobj.h:565
DWORD pFiles
Definition: shlobj.h:2292
DWORD dwKeyState
Definition: CFSDropTarget.h:77
CFSDropTarget * This
Definition: CFSDropTarget.h:75
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:375
LPCWSTR pFrom
Definition: shellapi.h:357
FILEOP_FLAGS fFlags
Definition: shellapi.h:359
Definition: dsound.c:943
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
uint32_t * LPDWORD
Definition: typedefs.h:59
uint16_t * PWCHAR
Definition: typedefs.h:56
int ret
static HMENU hmenu
Definition: win.c:66
#define ZeroMemory
Definition: winbase.h:1712
#define GetFullPathName
Definition: winbase.h:3821
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_UNEXPECTED
Definition: winerror.h:2456
#define MK_RBUTTON
Definition: winuser.h:2368
#define CreateWindowEx
Definition: winuser.h:5755
#define MK_SHIFT
Definition: winuser.h:2369
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_RIGHTBUTTON
Definition: winuser.h:2380
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define TPM_NONOTIFY
Definition: winuser.h:2386
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define MK_CONTROL
Definition: winuser.h:2370
#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)
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185