mirror of
https://github.com/reactos/reactos.git
synced 2026-06-02 17:31:23 +08:00
[SHELL32] Sync CShellDispatch and family with wine.
Incorporates work from Ivan Rodionov. CORE-12955
This commit is contained in:
@@ -1,21 +1,8 @@
|
||||
/*
|
||||
* FolderItem(s) implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* PROJECT: shell32
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: FolderItem(s) implementation
|
||||
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
@@ -31,28 +18,49 @@ CFolderItem::~CFolderItem()
|
||||
{
|
||||
}
|
||||
|
||||
void CFolderItem::Init(LPITEMIDLIST idlist)
|
||||
HRESULT CFolderItem::Initialize(Folder* folder, LPITEMIDLIST idlist)
|
||||
{
|
||||
m_idlist.Attach(idlist);
|
||||
m_idlist.Attach(ILClone(idlist));
|
||||
m_Folder = folder;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// *** FolderItem methods ***
|
||||
HRESULT STDMETHODCALLTYPE CFolderItem::get_Application(IDispatch **ppid)
|
||||
{
|
||||
TRACE("(%p, %p)\n", this, ppid);
|
||||
return E_NOTIMPL;
|
||||
return m_Folder->get_Application(ppid);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CFolderItem::get_Parent(IDispatch **ppid)
|
||||
{
|
||||
TRACE("(%p, %p)\n", this, ppid);
|
||||
if (ppid)
|
||||
{
|
||||
*ppid = m_Folder;
|
||||
m_Folder->AddRef();
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CFolderItem::get_Name(BSTR *pbs)
|
||||
{
|
||||
TRACE("(%p, %p)\n", this, pbs);
|
||||
return E_NOTIMPL;
|
||||
|
||||
*pbs = NULL;
|
||||
|
||||
CComPtr<IShellFolder2> Parent;
|
||||
LPCITEMIDLIST last_part;
|
||||
HRESULT hr = SHBindToParent(m_idlist, IID_PPV_ARG(IShellFolder2, &Parent), &last_part);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
STRRET strret;
|
||||
hr = Parent->GetDisplayNameOf(last_part, SHGDN_INFOLDER, &strret);
|
||||
if (!FAILED_UNEXPECTEDLY(hr))
|
||||
hr = StrRetToBSTR(&strret, last_part, pbs);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CFolderItem::put_Name(BSTR bs)
|
||||
@@ -170,11 +178,11 @@ CFolderItems::~CFolderItems()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
|
||||
HRESULT CFolderItems::Initialize(LPITEMIDLIST idlist, Folder* parent)
|
||||
{
|
||||
CComPtr<IShellFolder> psfDesktop, psfTarget;
|
||||
|
||||
m_idlist.Attach(idlist);
|
||||
m_idlist.Attach(ILClone(idlist));
|
||||
|
||||
HRESULT hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
@@ -189,6 +197,7 @@ HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
m_Folder = parent;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -210,8 +219,7 @@ HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
|
||||
return hr;
|
||||
|
||||
CComHeapPtr<ITEMIDLIST> Pidl;
|
||||
hr = m_EnumIDList->Next(1, &Pidl, 0);
|
||||
while (hr != S_FALSE)
|
||||
while ((hr = m_EnumIDList->Next(1, &Pidl, 0)) != S_FALSE)
|
||||
{
|
||||
count++;
|
||||
Pidl.Free();
|
||||
@@ -226,12 +234,16 @@ HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
|
||||
HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid)
|
||||
{
|
||||
TRACE("(%p, %p)\n", this, ppid);
|
||||
return E_NOTIMPL;
|
||||
return m_Folder->get_Application(ppid);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid)
|
||||
{
|
||||
TRACE("(%p, %p)\n", this, ppid);
|
||||
|
||||
if (ppid)
|
||||
*ppid = NULL;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -240,40 +252,48 @@ HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
|
||||
if (!m_EnumIDList)
|
||||
return E_FAIL;
|
||||
|
||||
if (V_VT(&index) != VT_I4 && V_VT(&index) != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
if (V_VT(&index) == VT_I2)
|
||||
VariantChangeType(&index, &index, 0, VT_I4);
|
||||
|
||||
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)
|
||||
if (V_VT(&index) == VT_I4)
|
||||
{
|
||||
CFolderItem* item = new CComObject<CFolderItem>();
|
||||
item->AddRef();
|
||||
item->Init(spPidl.Detach());
|
||||
*ppid = item;
|
||||
return S_OK;
|
||||
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 (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
hr = ShellObjectCreatorInit<CFolderItem>(m_Folder, static_cast<LPITEMIDLIST>(spPidl), IID_PPV_ARG(FolderItem, ppid));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
return hr;
|
||||
}
|
||||
else if (V_VT(&index) == VT_BSTR)
|
||||
{
|
||||
if (!V_BSTR(&index))
|
||||
return S_FALSE;
|
||||
|
||||
HRESULT hr = m_Folder->ParseName(V_BSTR(&index), ppid);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
FIXME("Index type %d not handled.\n", V_VT(&index));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
|
||||
{
|
||||
CFolderItems* items = new CComObject<CFolderItems>();
|
||||
items->AddRef();
|
||||
items->Init(ILClone(m_idlist));
|
||||
*ppunk = items;
|
||||
return S_OK;
|
||||
return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), m_Folder, IID_FolderItems, reinterpret_cast<void**>(ppunk));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user