Reactos
at master 306 lines 6.9 kB view raw
1/* 2 * PROJECT: shell32 3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) 4 * PURPOSE: FolderItem(s) implementation 5 * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8#include "precomp.h" 9 10WINE_DEFAULT_DEBUG_CHANNEL(shell); 11 12 13CFolderItem::CFolderItem() 14{ 15} 16 17CFolderItem::~CFolderItem() 18{ 19} 20 21HRESULT CFolderItem::Initialize(Folder* folder, LPITEMIDLIST idlist) 22{ 23 m_idlist.Attach(ILClone(idlist)); 24 m_Folder = folder; 25 return S_OK; 26} 27 28// *** FolderItem methods *** 29HRESULT STDMETHODCALLTYPE CFolderItem::get_Application(IDispatch **ppid) 30{ 31 TRACE("(%p, %p)\n", this, ppid); 32 return m_Folder->get_Application(ppid); 33} 34 35HRESULT STDMETHODCALLTYPE CFolderItem::get_Parent(IDispatch **ppid) 36{ 37 TRACE("(%p, %p)\n", this, ppid); 38 if (ppid) 39 { 40 *ppid = m_Folder; 41 (*ppid)->AddRef(); 42 } 43 return E_NOTIMPL; 44} 45 46HRESULT STDMETHODCALLTYPE CFolderItem::get_Name(BSTR *pbs) 47{ 48 TRACE("(%p, %p)\n", this, pbs); 49 50 *pbs = NULL; 51 52 CComPtr<IShellFolder2> Parent; 53 LPCITEMIDLIST last_part; 54 HRESULT hr = SHBindToParent(m_idlist, IID_PPV_ARG(IShellFolder2, &Parent), &last_part); 55 if (FAILED_UNEXPECTEDLY(hr)) 56 return hr; 57 58 STRRET strret; 59 hr = Parent->GetDisplayNameOf(last_part, SHGDN_INFOLDER, &strret); 60 if (!FAILED_UNEXPECTEDLY(hr)) 61 hr = StrRetToBSTR(&strret, last_part, pbs); 62 63 return hr; 64} 65 66HRESULT STDMETHODCALLTYPE CFolderItem::put_Name(BSTR bs) 67{ 68 TRACE("(%p, %s)\n", this, wine_dbgstr_w(bs)); 69 return E_NOTIMPL; 70} 71 72HRESULT STDMETHODCALLTYPE CFolderItem::get_Path(BSTR *pbs) 73{ 74 CComPtr<IShellFolder> psfDesktop; 75 76 HRESULT hr = SHGetDesktopFolder(&psfDesktop); 77 if (!SUCCEEDED(hr)) 78 return hr; 79 80 STRRET strret; 81 hr = psfDesktop->GetDisplayNameOf(m_idlist, SHGDN_FORPARSING, &strret); 82 if (FAILED_UNEXPECTEDLY(hr)) 83 return hr; 84 85 return StrRetToBSTR(&strret, NULL, pbs); 86} 87 88HRESULT STDMETHODCALLTYPE CFolderItem::get_GetLink(IDispatch **ppid) 89{ 90 TRACE("(%p, %p)\n", this, ppid); 91 return E_NOTIMPL; 92} 93 94HRESULT STDMETHODCALLTYPE CFolderItem::get_GetFolder(IDispatch **ppid) 95{ 96 TRACE("(%p, %p)\n", this, ppid); 97 return E_NOTIMPL; 98} 99 100HRESULT STDMETHODCALLTYPE CFolderItem::get_IsLink(VARIANT_BOOL *pb) 101{ 102 TRACE("(%p, %p)\n", this, pb); 103 return E_NOTIMPL; 104} 105 106HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFolder(VARIANT_BOOL *pb) 107{ 108 TRACE("(%p, %p)\n", this, pb); 109 return E_NOTIMPL; 110} 111 112HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFileSystem(VARIANT_BOOL *pb) 113{ 114 TRACE("(%p, %p)\n", this, pb); 115 return E_NOTIMPL; 116} 117 118HRESULT STDMETHODCALLTYPE CFolderItem::get_IsBrowsable(VARIANT_BOOL *pb) 119{ 120 TRACE("(%p, %p)\n", this, pb); 121 return E_NOTIMPL; 122} 123 124HRESULT STDMETHODCALLTYPE CFolderItem::get_ModifyDate(DATE *pdt) 125{ 126 TRACE("(%p, %p)\n", this, pdt); 127 return E_NOTIMPL; 128} 129 130HRESULT STDMETHODCALLTYPE CFolderItem::put_ModifyDate(DATE dt) 131{ 132 TRACE("(%p, %f)\n", this, dt); 133 return E_NOTIMPL; 134} 135 136HRESULT STDMETHODCALLTYPE CFolderItem::get_Size(LONG *pul) 137{ 138 TRACE("(%p, %p)\n", this, pul); 139 return E_NOTIMPL; 140} 141 142HRESULT STDMETHODCALLTYPE CFolderItem::get_Type(BSTR *pbs) 143{ 144 TRACE("(%p, %p)\n", this, pbs); 145 return E_NOTIMPL; 146} 147 148HRESULT STDMETHODCALLTYPE CFolderItem::Verbs(FolderItemVerbs **ppfic) 149{ 150 if (!ppfic) 151 return E_POINTER; 152 CFolderItemVerbs* verbs = new CComObject<CFolderItemVerbs>(); 153 HRESULT hr = verbs->Init(m_idlist); 154 if (FAILED_UNEXPECTEDLY(hr)) 155 { 156 delete verbs; 157 return hr; 158 } 159 verbs->AddRef(); 160 *ppfic = verbs; 161 return S_OK; 162} 163 164HRESULT STDMETHODCALLTYPE CFolderItem::InvokeVerb(VARIANT vVerb) 165{ 166 TRACE("(%p, %s)\n", this, wine_dbgstr_variant(&vVerb)); 167 return E_NOTIMPL; 168} 169 170 171 172CFolderItems::CFolderItems() 173 :m_Count(-1) 174{ 175} 176 177CFolderItems::~CFolderItems() 178{ 179} 180 181HRESULT CFolderItems::Initialize(LPITEMIDLIST idlist, Folder* parent) 182{ 183 CComPtr<IShellFolder> psfDesktop, psfTarget; 184 185 m_idlist.Attach(ILClone(idlist)); 186 187 HRESULT hr = SHGetDesktopFolder(&psfDesktop); 188 if (FAILED_UNEXPECTEDLY(hr)) 189 return hr; 190 191 hr = psfDesktop->BindToObject(m_idlist, NULL, IID_PPV_ARG(IShellFolder, &psfTarget)); 192 if (FAILED_UNEXPECTEDLY(hr)) 193 return hr; 194 195 hr = psfTarget->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &m_EnumIDList); 196 197 if (FAILED_UNEXPECTEDLY(hr)) 198 return hr; 199 200 m_Folder = parent; 201 return S_OK; 202} 203 204// *** FolderItems methods *** 205HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount) 206{ 207 if (!m_EnumIDList) 208 return E_FAIL; 209 210 if (!plCount) 211 return E_POINTER; 212 213 if (m_Count == -1) 214 { 215 long count = 0; 216 217 HRESULT hr = m_EnumIDList->Reset(); 218 if (FAILED_UNEXPECTEDLY(hr)) 219 return hr; 220 221 CComHeapPtr<ITEMIDLIST> Pidl; 222 while ((hr = m_EnumIDList->Next(1, &Pidl, 0)) != S_FALSE) 223 { 224 count++; 225 Pidl.Free(); 226 } 227 m_Count = count; 228 } 229 *plCount = m_Count; 230 231 return S_OK; 232} 233 234HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid) 235{ 236 TRACE("(%p, %p)\n", this, ppid); 237 return m_Folder->get_Application(ppid); 238} 239 240HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid) 241{ 242 TRACE("(%p, %p)\n", this, ppid); 243 244 if (ppid) 245 *ppid = NULL; 246 247 return E_NOTIMPL; 248} 249 250HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT var, FolderItem **ppid) 251{ 252 CComVariant index; 253 HRESULT hr; 254 255 if (!m_EnumIDList) 256 return E_FAIL; 257 258 hr = VariantCopyInd(&index, &var); 259 if (FAILED(hr)) 260 return hr; 261 262 if (V_VT(&index) == VT_I2) 263 VariantChangeType(&index, &index, 0, VT_I4); 264 265 if (V_VT(&index) == VT_I4) 266 { 267 ULONG count = V_UI4(&index); 268 269 hr = m_EnumIDList->Reset(); 270 if (FAILED_UNEXPECTEDLY(hr)) 271 return hr; 272 273 hr = m_EnumIDList->Skip(count); 274 275 if (FAILED_UNEXPECTEDLY(hr)) 276 return hr; 277 278 CComHeapPtr<ITEMIDLIST> spPidl; 279 hr = m_EnumIDList->Next(1, &spPidl, 0); 280 if (FAILED_UNEXPECTEDLY(hr)) 281 return hr; 282 hr = ShellObjectCreatorInit<CFolderItem>(m_Folder, static_cast<LPITEMIDLIST>(spPidl), IID_PPV_ARG(FolderItem, ppid)); 283 if (FAILED_UNEXPECTEDLY(hr)) 284 return hr; 285 return hr; 286 } 287 else if (V_VT(&index) == VT_BSTR) 288 { 289 if (!V_BSTR(&index)) 290 return S_FALSE; 291 292 hr = m_Folder->ParseName(V_BSTR(&index), ppid); 293 if (FAILED_UNEXPECTEDLY(hr)) 294 return hr; 295 return hr; 296 } 297 298 FIXME("Index type %d not handled.\n", V_VT(&index)); 299 return E_NOTIMPL; 300} 301 302HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk) 303{ 304 return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), m_Folder, IID_FolderItems, reinterpret_cast<void**>(ppunk)); 305} 306