[SHELL32] Partially implement CFolderItems. Thanks to Giannis for the advice :)

svn path=/trunk/; revision=72416
This commit is contained in:
Mark Jansen 2016-08-21 19:58:32 +00:00
parent 63fae88fbc
commit 963d66822f
3 changed files with 102 additions and 10 deletions

View 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;
}

View 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;
}

View 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);