xref: /reactos/dll/shellext/zipfldr/CSendToZip.cpp (revision 8a978a17)
1 /*
2  * PROJECT:   ReactOS Zip Shell Extension
3  * LICENSE:   GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:   SendTo handler
5  * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6  *            Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7  */
8 
9 #include "precomp.h"
10 
11 STDMETHODIMP
12 CSendToZip::DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt,
13                       DWORD *pdwEffect)
14 {
15     m_pDataObject = pDataObj;
16 
17     FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
18     m_fCanDragDrop = SUCCEEDED(pDataObj->QueryGetData(&etc));
19 
20     if (m_fCanDragDrop)
21         *pdwEffect &= DROPEFFECT_COPY;
22     else
23         *pdwEffect = DROPEFFECT_NONE;
24 
25     return S_OK;
26 }
27 
28 STDMETHODIMP CSendToZip::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
29 {
30     if (m_fCanDragDrop)
31         *pdwEffect &= DROPEFFECT_COPY;
32     else
33         *pdwEffect = DROPEFFECT_NONE;
34 
35     return S_OK;
36 }
37 
38 STDMETHODIMP CSendToZip::DragLeave()
39 {
40     m_fCanDragDrop = FALSE;
41     m_pDataObject.Release();
42     return S_OK;
43 }
44 
45 STDMETHODIMP
46 CSendToZip::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt,
47                  DWORD *pdwEffect)
48 {
49     m_pDataObject = pDataObj;
50 
51     if (!pDataObj || !m_fCanDragDrop)
52     {
53         DPRINT1("Drop failed: %d %d\n", !pDataObj, !m_fCanDragDrop);
54         *pdwEffect = 0;
55         DragLeave();
56         return E_FAIL;
57     }
58 
59     STGMEDIUM stg;
60     FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
61     HRESULT hr = pDataObj->GetData(&etc, &stg);
62     if (FAILED_UNEXPECTEDLY(hr))
63     {
64         *pdwEffect = 0;
65         DragLeave();
66         return E_FAIL;
67     }
68 
69     HDROP hDrop = reinterpret_cast<HDROP>(stg.hGlobal);
70     UINT cItems = ::DragQueryFileW(hDrop, -1, NULL, 0);
71 
72     CZipCreator *pCreator = CZipCreator::DoCreate();
73 
74     for (UINT iItem = 0; iItem < cItems; ++iItem)
75     {
76         WCHAR szPath[MAX_PATH];
77         DragQueryFileW(hDrop, iItem, szPath, _countof(szPath));
78 
79         pCreator->DoAddItem(szPath);
80     }
81 
82     ::ReleaseStgMedium(&stg);
83 
84     CZipCreator::runThread(pCreator);   // pCreator is deleted in runThread
85 
86     DragLeave();
87     return hr;
88 }
89