[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) HRESULT STDMETHODCALLTYPE CFolder::Items(FolderItems **ppid)
{ {
CFolderItems* item = new CComObject<CFolderItems>(); CFolderItems* items = new CComObject<CFolderItems>();
item->AddRef(); items->AddRef();
*ppid = item;
HRESULT hr = items->Init(ILClone(m_idlist));
if (FAILED_UNEXPECTEDLY(hr))
{
items->Release();
return hr;
}
*ppid = items;
return S_OK; return S_OK;
} }

View file

@ -1,7 +1,7 @@
/* /*
* FolderItem(s) implementation * FolderItem(s) implementation
* *
* Copyright 2015 Mark Jansen * Copyright 2015,2016 Mark Jansen
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -162,6 +162,7 @@ HRESULT STDMETHODCALLTYPE CFolderItem::InvokeVerb(VARIANT vVerb)
CFolderItems::CFolderItems() 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 *** // *** FolderItems methods ***
HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount) HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
{ {
TRACE("(%p, %p)\n", this, plCount); if (!m_EnumIDList)
return E_NOTIMPL; 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) 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) HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
{ {
TRACE("(%p, %s, %p)\n", this, wine_dbgstr_variant(&index), ppid); if (!m_EnumIDList)
return E_NOTIMPL; 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) HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
{ {
TRACE("(%p, %p)\n", this, ppunk); CFolderItems* items = new CComObject<CFolderItems>();
return E_NOTIMPL; items->AddRef();
items->Init(ILClone(m_idlist));
*ppunk = items;
return S_OK;
} }

View file

@ -34,6 +34,7 @@ public:
CFolderItem(); CFolderItem();
~CFolderItem(); ~CFolderItem();
// Please note: CFolderItem takes ownership of idlist.
void Init(LPITEMIDLIST idlist); void Init(LPITEMIDLIST idlist);
@ -72,11 +73,17 @@ class CFolderItems:
public IDispatchImpl<FolderItems, &IID_FolderItems> public IDispatchImpl<FolderItems, &IID_FolderItems>
{ {
private: private:
CComHeapPtr<ITEMIDLIST> m_idlist;
CComPtr<IEnumIDList> m_EnumIDList;
long m_Count;
public: public:
CFolderItems(); CFolderItems();
~CFolderItems(); ~CFolderItems();
// Please note: CFolderItems takes ownership of idlist.
HRESULT Init(LPITEMIDLIST idlist);
// *** FolderItems methods *** // *** FolderItems methods ***
virtual HRESULT STDMETHODCALLTYPE get_Count(long *plCount); virtual HRESULT STDMETHODCALLTYPE get_Count(long *plCount);
virtual HRESULT STDMETHODCALLTYPE get_Application(IDispatch **ppid); virtual HRESULT STDMETHODCALLTYPE get_Application(IDispatch **ppid);