[SHELLEXT][ZIPFLDR] Implement ZIP creation (#2114)
[reactos.git] / dll / shellext / zipfldr / CSendToZip.cpp
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 *pdwEffect &= DROPEFFECT_COPY;
51
52 if (!pDataObj || !m_fCanDragDrop || !*pdwEffect)
53 {
54 DPRINT1("Drop failed: %d %d %d\n",
55 !pDataObj, !m_fCanDragDrop, !*pdwEffect);
56 *pdwEffect = 0;
57 DragLeave();
58 return E_FAIL;
59 }
60
61 STGMEDIUM stg;
62 FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
63 HRESULT hr = pDataObj->GetData(&etc, &stg);
64 if (FAILED_UNEXPECTEDLY(hr))
65 {
66 *pdwEffect = 0;
67 DragLeave();
68 return E_FAIL;
69 }
70
71 HDROP hDrop = reinterpret_cast<HDROP>(stg.hGlobal);
72 UINT cItems = ::DragQueryFileW(hDrop, -1, NULL, 0);
73
74 CZipCreator *pCreater = CZipCreator::DoCreate();
75
76 for (UINT iItem = 0; iItem < cItems; ++iItem)
77 {
78 WCHAR szPath[MAX_PATH];
79 DragQueryFileW(hDrop, iItem, szPath, _countof(szPath));
80
81 pCreater->DoAddItem(szPath);
82 }
83
84 ::ReleaseStgMedium(&stg);
85
86 CZipCreator::runThread(pCreater); // pCreater is deleted in runThread
87
88 DragLeave();
89 return hr;
90 }