1 /* 2 * PROJECT: ReactOS Zip Shell Extension 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: IExplorerCommand implementation 5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 class CExplorerCommand : 11 public CComObjectRootEx<CComMultiThreadModelNoCS>, 12 public IExplorerCommand 13 { 14 private: 15 CComPtr<IContextMenu> m_pZipObject; 16 17 public: 18 19 STDMETHODIMP Initialize(IContextMenu* zipObject) 20 { 21 m_pZipObject = zipObject; 22 return S_OK; 23 } 24 25 // *** IExplorerCommand methods *** 26 STDMETHODIMP GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName) 27 { 28 CStringW Title(MAKEINTRESOURCEW(IDS_MENUITEM)); 29 return SHStrDup(Title, ppszName); 30 } 31 STDMETHODIMP GetIcon(IShellItemArray *psiItemArray, LPWSTR *ppszIcon) 32 { 33 CStringW IconName = L"zipfldr.dll,-1"; 34 return SHStrDup(IconName, ppszIcon); 35 } 36 STDMETHODIMP GetToolTip(IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) 37 { 38 CStringW HelpText(MAKEINTRESOURCEW(IDS_HELPTEXT)); 39 return SHStrDup(HelpText, ppszInfotip); 40 } 41 STDMETHODIMP GetCanonicalName(GUID *pguidCommandName) 42 { 43 *pguidCommandName = CLSID_ZipFolderExtractAllCommand; 44 return S_OK; 45 } 46 STDMETHODIMP GetState(IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) 47 { 48 *pCmdState = ECS_ENABLED; 49 return S_OK; 50 } 51 STDMETHODIMP Invoke(IShellItemArray *psiItemArray, IBindCtx *pbc) 52 { 53 CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 }; 54 cm.lpVerb = EXTRACT_VERBA; 55 cm.nShow = SW_SHOW; 56 return m_pZipObject->InvokeCommand(&cm); 57 } 58 STDMETHODIMP GetFlags(EXPCMDFLAGS *pFlags) 59 { 60 *pFlags = ECF_DEFAULT; 61 return S_OK; 62 } 63 STDMETHODIMP EnumSubCommands(IEnumExplorerCommand **ppEnum) 64 { 65 DbgPrint("%s\n", __FUNCTION__); 66 return E_NOTIMPL; 67 } 68 69 public: 70 DECLARE_NOT_AGGREGATABLE(CExplorerCommand) 71 DECLARE_PROTECT_FINAL_CONSTRUCT() 72 73 BEGIN_COM_MAP(CExplorerCommand) 74 COM_INTERFACE_ENTRY_IID(IID_IExplorerCommand, IExplorerCommand) 75 END_COM_MAP() 76 }; 77 78 79 class CEnumExplorerCommand : 80 public CComObjectRootEx<CComMultiThreadModelNoCS>, 81 public IEnumExplorerCommand 82 { 83 private: 84 bool m_bFirst; 85 CComPtr<IContextMenu> m_pZipObject; 86 87 public: 88 89 CEnumExplorerCommand() 90 :m_bFirst(true) 91 { 92 } 93 94 STDMETHODIMP Initialize(IContextMenu* zipObject) 95 { 96 m_pZipObject = zipObject; 97 return S_OK; 98 } 99 100 // *** IEnumExplorerCommand methods *** 101 STDMETHODIMP Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) 102 { 103 if (!pUICommand) 104 return E_POINTER; 105 106 if (pceltFetched) 107 *pceltFetched = 0; 108 if (m_bFirst && celt) 109 { 110 m_bFirst = false; 111 celt--; 112 HRESULT hr = ShellObjectCreatorInit<CExplorerCommand>(m_pZipObject, IID_PPV_ARG(IExplorerCommand, pUICommand)); 113 if (SUCCEEDED(hr)) 114 { 115 if (pceltFetched) 116 *pceltFetched = 1; 117 } 118 return hr; 119 } 120 return S_FALSE; 121 } 122 STDMETHODIMP Skip(ULONG celt) 123 { 124 if (m_bFirst) 125 { 126 m_bFirst = false; 127 return S_OK; 128 } 129 return S_FALSE; 130 } 131 STDMETHODIMP Reset() 132 { 133 m_bFirst = true; 134 return S_OK; 135 } 136 STDMETHODIMP Clone(IEnumExplorerCommand **ppenum) 137 { 138 return E_NOTIMPL; 139 } 140 141 public: 142 DECLARE_NOT_AGGREGATABLE(CEnumExplorerCommand) 143 DECLARE_PROTECT_FINAL_CONSTRUCT() 144 145 BEGIN_COM_MAP(CEnumExplorerCommand) 146 COM_INTERFACE_ENTRY_IID(IID_IEnumExplorerCommand, IEnumExplorerCommand) 147 END_COM_MAP() 148 }; 149 150 class CExplorerCommandProvider : 151 public CComObjectRootEx<CComMultiThreadModelNoCS>, 152 public IExplorerCommandProvider 153 { 154 private: 155 CComPtr<IContextMenu> m_pZipObject; 156 157 public: 158 STDMETHODIMP Initialize(IContextMenu* zipObject) 159 { 160 m_pZipObject = zipObject; 161 return S_OK; 162 } 163 164 // *** IExplorerCommandProvider methods *** 165 STDMETHODIMP GetCommands(IUnknown *punkSite, REFIID riid, void **ppv) 166 { 167 return ShellObjectCreatorInit<CEnumExplorerCommand>(m_pZipObject, riid, ppv); 168 } 169 STDMETHODIMP GetCommand(REFGUID rguidCommandId, REFIID riid, void **ppv) 170 { 171 UNIMPLEMENTED; 172 *ppv = NULL; 173 return E_NOTIMPL; 174 } 175 176 public: 177 DECLARE_NOT_AGGREGATABLE(CExplorerCommandProvider) 178 DECLARE_PROTECT_FINAL_CONSTRUCT() 179 180 BEGIN_COM_MAP(CExplorerCommandProvider) 181 COM_INTERFACE_ENTRY_IID(IID_IExplorerCommandProvider, IExplorerCommandProvider) 182 END_COM_MAP() 183 }; 184 185 186 HRESULT _CExplorerCommandProvider_CreateInstance(IContextMenu* zipObject, REFIID riid, LPVOID * ppvOut) 187 { 188 return ShellObjectCreatorInit<CExplorerCommandProvider>(zipObject, riid, ppvOut); 189 } 190