[SHELL32]
[reactos.git] / dll / win32 / shell32 / shellitem.cpp
index 28fbc2e..49ae0ca 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2008 Vincent Povirk for CodeWeavers
  * Copyright 2009 Andrew Hill
+ * Copyright 2013 Katayama Hirofumi MZ
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,19 +27,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 EXTERN_C HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
     IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi);
 
-CShellItem::CShellItem()
+CShellItem::CShellItem() :
+    m_pidl(NULL)
 {
-    pidl = NULL;
 }
 
 CShellItem::~CShellItem()
 {
-    ILFree(pidl);
+    ILFree(m_pidl);
 }
 
 HRESULT CShellItem::get_parent_pidl(LPITEMIDLIST *parent_pidl)
 {
-    *parent_pidl = ILClone(pidl);
+    *parent_pidl = ILClone(m_pidl);
     if (*parent_pidl)
     {
         if (ILRemoveLastID(*parent_pidl))
@@ -59,20 +60,20 @@ HRESULT CShellItem::get_parent_pidl(LPITEMIDLIST *parent_pidl)
 
 HRESULT CShellItem::get_parent_shellfolder(IShellFolder **ppsf)
 {
+    HRESULT hr;
     LPITEMIDLIST parent_pidl;
     CComPtr<IShellFolder>        desktop;
-    HRESULT ret;
 
-    ret = get_parent_pidl(&parent_pidl);
-    if (SUCCEEDED(ret))
+    hr = get_parent_pidl(&parent_pidl);
+    if (SUCCEEDED(hr))
     {
-        ret = SHGetDesktopFolder(&desktop);
-        if (SUCCEEDED(ret))
-            ret = desktop->BindToObject(parent_pidl, NULL, IID_IShellFolder, (void**)ppsf);
+        hr = SHGetDesktopFolder(&desktop);
+        if (SUCCEEDED(hr))
+            hr = desktop->BindToObject(parent_pidl, NULL, IID_PPV_ARG(IShellFolder, ppsf));
         ILFree(parent_pidl);
     }
 
-    return ret;
+    return hr;
 }
 
 HRESULT WINAPI CShellItem::BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut)
@@ -86,54 +87,121 @@ HRESULT WINAPI CShellItem::BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID ri
 
 HRESULT WINAPI CShellItem::GetParent(IShellItem **ppsi)
 {
+    HRESULT hr;
     LPITEMIDLIST parent_pidl;
-    HRESULT ret;
 
     TRACE("(%p,%p)\n", this, ppsi);
 
-    ret = get_parent_pidl(&parent_pidl);
-    if (SUCCEEDED(ret))
+    hr = get_parent_pidl(&parent_pidl);
+    if (SUCCEEDED(hr))
     {
-        ret = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
+        hr = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
         ILFree(parent_pidl);
     }
 
-    return ret;
+    return hr;
 }
 
 HRESULT WINAPI CShellItem::GetDisplayName(SIGDN sigdnName, LPWSTR *ppszName)
 {
-    FIXME("(%p,%x,%p)\n", this, sigdnName, ppszName);
+    HRESULT hr;
+    CComPtr<IShellFolder>        parent_folder;
+    STRRET name;
+    DWORD uFlags;
+
+    TRACE("(%p,%x,%p)\n", this, sigdnName, ppszName);
+
+    if (sigdnName & SIGDN_URL)
+        return E_NOTIMPL;
+
+    if (ppszName == NULL)
+        return E_POINTER;
 
     *ppszName = NULL;
 
-    return E_NOTIMPL;
+    hr = get_parent_shellfolder(&parent_folder);
+    if (SUCCEEDED(hr))
+    {
+        switch (sigdnName)
+        {
+        case SIGDN_PARENTRELATIVEEDITING:
+            uFlags = SHGDN_FOREDITING | SHGDN_INFOLDER;
+            break;
+        case SIGDN_DESKTOPABSOLUTEEDITING:
+            uFlags = SHGDN_FOREDITING;
+            break;
+        case SIGDN_PARENTRELATIVEPARSING:
+            uFlags = SHGDN_FORPARSING | SHGDN_INFOLDER;
+            break;
+        case SIGDN_DESKTOPABSOLUTEPARSING:
+            uFlags = SHGDN_FORPARSING;
+            break;
+        default:
+            uFlags = SHGDN_NORMAL;
+            break;
+        }
+
+        hr = parent_folder->GetDisplayNameOf(m_pidl, uFlags, &name);
+        if (SUCCEEDED(hr))
+        {
+            StrRetToStrW(&name, m_pidl, ppszName);
+            return S_OK;
+        }
+    }
+
+    return hr;
 }
 
 HRESULT WINAPI CShellItem::GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs)
 {
     CComPtr<IShellFolder>        parent_folder;
-    LPITEMIDLIST child_pidl;
-    HRESULT ret;
+    LPCITEMIDLIST child_pidl;
+    HRESULT hr;
 
     TRACE("(%p,%x,%p)\n", this, sfgaoMask, psfgaoAttribs);
 
-    ret = get_parent_shellfolder(&parent_folder);
-    if (SUCCEEDED(ret))
+    hr = get_parent_shellfolder(&parent_folder);
+    if (SUCCEEDED(hr))
     {
-        child_pidl = ILFindLastID(pidl);
+        child_pidl = ILFindLastID(m_pidl);
         *psfgaoAttribs = sfgaoMask;
-        ret = parent_folder->GetAttributesOf(1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs);
+        hr = parent_folder->GetAttributesOf(1, &child_pidl, psfgaoAttribs);
     }
 
-    return ret;
+    return hr;
 }
 
 HRESULT WINAPI CShellItem::Compare(IShellItem *oth, SICHINTF hint, int *piOrder)
 {
-    FIXME("(%p,%p,%x,%p)\n", this, oth, hint, piOrder);
+    HRESULT hr;
+    CComPtr<IPersistIDList>      pIDList;
+    CComPtr<IShellFolder>        parent_folder;
+    LPITEMIDLIST pidl;
 
-    return E_NOTIMPL;
+    TRACE("(%p,%p,%x,%p)\n", this, oth, hint, piOrder);
+
+    if (piOrder == NULL || oth == NULL)
+        return E_POINTER;
+
+    hr = oth->QueryInterface(IID_PPV_ARG(IPersistIDList, &pIDList));
+    if (SUCCEEDED(hr))
+    {
+        hr = pIDList->GetIDList(&pidl);
+        if (SUCCEEDED(hr))
+        {
+            hr = get_parent_shellfolder(&parent_folder);
+            if (SUCCEEDED(hr))
+            {
+                hr = parent_folder->CompareIDs(hint, m_pidl, pidl);
+                *piOrder = static_cast<int>(SCODE_CODE(hr));
+            }
+            ILFree(pidl);
+        }
+    }
+
+    if (SUCCEEDED(hr))
+        return S_OK;
+    return hr;
 }
 
 HRESULT WINAPI CShellItem::GetClassID(CLSID *pClassID)
@@ -144,7 +212,6 @@ HRESULT WINAPI CShellItem::GetClassID(CLSID *pClassID)
     return S_OK;
 }
 
-
 HRESULT WINAPI CShellItem::SetIDList(LPCITEMIDLIST pidlx)
 {
     LPITEMIDLIST new_pidl;
@@ -152,11 +219,10 @@ HRESULT WINAPI CShellItem::SetIDList(LPCITEMIDLIST pidlx)
     TRACE("(%p,%p)\n", this, pidlx);
 
     new_pidl = ILClone(pidlx);
-
     if (new_pidl)
     {
-        ILFree(pidl);
-        pidl = new_pidl;
+        ILFree(m_pidl);
+        m_pidl = new_pidl;
         return S_OK;
     }
     else
@@ -167,7 +233,7 @@ HRESULT WINAPI CShellItem::GetIDList(LPITEMIDLIST *ppidl)
 {
     TRACE("(%p,%p)\n", this, ppidl);
 
-    *ppidl = ILClone(pidl);
+    *ppidl = ILClone(m_pidl);
     if (*ppidl)
         return S_OK;
     else
@@ -177,25 +243,24 @@ HRESULT WINAPI CShellItem::GetIDList(LPITEMIDLIST *ppidl)
 HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
     IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
 {
+    HRESULT hr;
     IShellItem *newShellItem;
     LPITEMIDLIST new_pidl;
     CComPtr<IPersistIDList>            newPersistIDList;
-    HRESULT ret;
 
     TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi);
 
     if (!pidl)
-    {
         return E_INVALIDARG;
-    }
-    else if (pidlParent || psfParent)
+
+    if (pidlParent || psfParent)
     {
-        LPITEMIDLIST temp_parent=NULL;
+        LPITEMIDLIST temp_parent = NULL;
         if (!pidlParent)
         {
             CComPtr<IPersistFolder2>    ppf2Parent;
 
-            if (FAILED(psfParent->QueryInterface(IID_IPersistFolder2, (void**)&ppf2Parent)))
+            if (FAILED(psfParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2Parent))))
             {
                 FIXME("couldn't get IPersistFolder2 interface of parent\n");
                 return E_NOINTERFACE;
@@ -223,26 +288,26 @@ HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
             return E_OUTOFMEMORY;
     }
 
-    ret = CShellItem::_CreatorClass::CreateInstance(NULL, IID_IShellItem, (void**)&newShellItem);
-    if (FAILED(ret))
+    hr = CShellItem::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellItem, &newShellItem));
+    if (FAILED(hr))
     {
         *ppsi = NULL;
         ILFree(new_pidl);
-        return ret;
+        return hr;
     }
-    ret = newShellItem->QueryInterface(IID_IPersistIDList, (void **)&newPersistIDList);
-    if (FAILED(ret))
+    hr = newShellItem->QueryInterface(IID_PPV_ARG(IPersistIDList, &newPersistIDList));
+    if (FAILED(hr))
     {
         ILFree(new_pidl);
-        return ret;
+        return hr;
     }
-    ret = newPersistIDList->SetIDList(new_pidl);
-    if (FAILED(ret))
+    hr = newPersistIDList->SetIDList(new_pidl);
+    if (FAILED(hr))
     {
         ILFree(new_pidl);
-        return ret;
+        return hr;
     }
     ILFree(new_pidl);
     *ppsi = newShellItem;
-    return ret;
+    return hr;
 }