[SHELL32] Partially implement CFolderItems. Thanks to Giannis for the advice :)
authorMark Jansen <mark.jansen@reactos.org>
Sun, 21 Aug 2016 19:58:32 +0000 (19:58 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 21 Aug 2016 19:58:32 +0000 (19:58 +0000)
svn path=/trunk/; revision=72416

reactos/dll/win32/shell32/CFolder.cpp
reactos/dll/win32/shell32/CFolderItems.cpp
reactos/dll/win32/shell32/CFolderItems.h

index c7e8c2d..26eea6c 100644 (file)
@@ -82,9 +82,17 @@ HRESULT STDMETHODCALLTYPE CFolder::get_ParentFolder(Folder **ppsf)
 
 HRESULT STDMETHODCALLTYPE CFolder::Items(FolderItems **ppid)
 {
-    CFolderItems* item = new CComObject<CFolderItems>();
-    item->AddRef();
-    *ppid = item;
+    CFolderItems* items = new CComObject<CFolderItems>();
+    items->AddRef();
+
+    HRESULT hr = items->Init(ILClone(m_idlist));
+    if (FAILED_UNEXPECTEDLY(hr))
+    {
+        items->Release();
+        return hr;
+    }
+
+    *ppid = items;
     return S_OK;
 }
 
index 95edc91..614ead2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * FolderItem(s) implementation
  *
- * Copyright 2015 Mark Jansen
+ * Copyright 2015,2016 Mark Jansen
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -162,6 +162,7 @@ HRESULT STDMETHODCALLTYPE CFolderItem::InvokeVerb(VARIANT vVerb)
 
 
 CFolderItems::CFolderItems()
+    :m_Count(-1)
 {
 }
 
@@ -169,11 +170,57 @@ CFolderItems::~CFolderItems()
 {
 }
 
+HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
+{
+    CComPtr<IShellFolder> psfDesktop, psfTarget;
+
+    m_idlist.Attach(idlist);
+
+    HRESULT hr = SHGetDesktopFolder(&psfDesktop);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = psfDesktop->BindToObject(m_idlist, NULL, IID_PPV_ARG(IShellFolder, &psfTarget));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = psfTarget->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &m_EnumIDList);
+
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    return S_OK;
+}
+
 // *** FolderItems methods ***
 HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
 {
-    TRACE("(%p, %p)\n", this, plCount);
-    return E_NOTIMPL;
+    if (!m_EnumIDList)
+        return E_FAIL;
+
+    if (!plCount)
+        return E_POINTER;
+
+    if (m_Count == -1)
+    {
+        long count = 0;
+
+        HRESULT hr = m_EnumIDList->Reset();
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        CComHeapPtr<ITEMIDLIST> Pidl;
+        hr = m_EnumIDList->Next(1, &Pidl, 0);
+        while (hr != S_FALSE)
+        {
+            count++;
+            Pidl.Free();
+        }
+        m_Count = count;
+    }
+    *plCount = m_Count;
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid)
@@ -190,13 +237,43 @@ HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid)
 
 HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
 {
-    TRACE("(%p, %s, %p)\n", this, wine_dbgstr_variant(&index), ppid);
-    return E_NOTIMPL;
+    if (!m_EnumIDList)
+        return E_FAIL;
+
+    if (V_VT(&index) != VT_I4 && V_VT(&index) != VT_UI4)
+        return E_INVALIDARG;
+
+    ULONG count = V_UI4(&index);
+
+    HRESULT hr = m_EnumIDList->Reset();
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = m_EnumIDList->Skip(count);
+
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    CComHeapPtr<ITEMIDLIST> spPidl;
+    hr = m_EnumIDList->Next(1, &spPidl, 0);
+    if (hr == S_OK)
+    {
+        CFolderItem* item = new CComObject<CFolderItem>();
+        item->AddRef();
+        item->Init(spPidl.Detach());
+        *ppid = item;
+        return S_OK;
+    }
+
+    return hr;
 }
 
 HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
 {
-    TRACE("(%p, %p)\n", this, ppunk);
-    return E_NOTIMPL;
+    CFolderItems* items = new CComObject<CFolderItems>();
+    items->AddRef();
+    items->Init(ILClone(m_idlist));
+    *ppunk = items;
+    return S_OK;
 }
 
index 48858fb..ddb62c8 100644 (file)
@@ -34,6 +34,7 @@ public:
     CFolderItem();
     ~CFolderItem();
 
+    // Please note: CFolderItem takes ownership of idlist.
     void Init(LPITEMIDLIST idlist);
 
 
@@ -72,11 +73,17 @@ class CFolderItems:
     public IDispatchImpl<FolderItems, &IID_FolderItems>
 {
 private:
+    CComHeapPtr<ITEMIDLIST> m_idlist;
+    CComPtr<IEnumIDList> m_EnumIDList;
+    long m_Count;
 
 public:
     CFolderItems();
     ~CFolderItems();
 
+    // Please note: CFolderItems takes ownership of idlist.
+    HRESULT Init(LPITEMIDLIST idlist);
+
     // *** FolderItems methods ***
     virtual HRESULT STDMETHODCALLTYPE get_Count(long *plCount);
     virtual HRESULT STDMETHODCALLTYPE get_Application(IDispatch **ppid);