2 * IShellItem implementation
4 * Copyright 2008 Vincent Povirk for CodeWeavers
5 * Copyright 2009 Andrew Hill
6 * Copyright 2013 Katayama Hirofumi MZ
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
27 EXTERN_C HRESULT WINAPI
SHCreateShellItem(LPCITEMIDLIST pidlParent
,
28 IShellFolder
*psfParent
, LPCITEMIDLIST pidl
, IShellItem
**ppsi
);
30 CShellItem::CShellItem() :
35 CShellItem::~CShellItem()
40 HRESULT
CShellItem::get_parent_pidl(LPITEMIDLIST
*parent_pidl
)
42 *parent_pidl
= ILClone(m_pidl
);
45 if (ILRemoveLastID(*parent_pidl
))
61 HRESULT
CShellItem::get_parent_shellfolder(IShellFolder
**ppsf
)
64 LPITEMIDLIST parent_pidl
;
65 CComPtr
<IShellFolder
> desktop
;
67 hr
= get_parent_pidl(&parent_pidl
);
70 hr
= SHGetDesktopFolder(&desktop
);
72 hr
= desktop
->BindToObject(parent_pidl
, NULL
, IID_PPV_ARG(IShellFolder
, ppsf
));
79 HRESULT WINAPI
CShellItem::BindToHandler(IBindCtx
*pbc
, REFGUID rbhid
, REFIID riid
, void **ppvOut
)
81 FIXME("(%p,%p,%s,%p,%p)\n", this, pbc
, shdebugstr_guid(&rbhid
), riid
, ppvOut
);
88 HRESULT WINAPI
CShellItem::GetParent(IShellItem
**ppsi
)
91 LPITEMIDLIST parent_pidl
;
93 TRACE("(%p,%p)\n", this, ppsi
);
95 hr
= get_parent_pidl(&parent_pidl
);
98 hr
= SHCreateShellItem(NULL
, NULL
, parent_pidl
, ppsi
);
105 HRESULT WINAPI
CShellItem::GetDisplayName(SIGDN sigdnName
, LPWSTR
*ppszName
)
108 CComPtr
<IShellFolder
> parent_folder
;
112 TRACE("(%p,%x,%p)\n", this, sigdnName
, ppszName
);
114 if (sigdnName
& SIGDN_URL
)
117 if (ppszName
== NULL
)
122 hr
= get_parent_shellfolder(&parent_folder
);
125 if (sigdnName
== SIGDN_PARENTRELATIVEEDITING
)
126 uFlags
= SHGDN_FOREDITING
| SHGDN_INFOLDER
;
127 else if (sigdnName
== SIGDN_DESKTOPABSOLUTEEDITING
)
128 uFlags
= SHGDN_FOREDITING
;
129 else if (sigdnName
== SIGDN_PARENTRELATIVEEDITING
)
130 uFlags
= SHGDN_FOREDITING
| SHGDN_INFOLDER
;
131 else if (sigdnName
== SIGDN_DESKTOPABSOLUTEEDITING
)
132 uFlags
= SHGDN_FOREDITING
;
133 else if (sigdnName
== SIGDN_PARENTRELATIVEPARSING
)
134 uFlags
= SHGDN_FORPARSING
| SHGDN_INFOLDER
;
135 else if (sigdnName
== SIGDN_DESKTOPABSOLUTEPARSING
)
136 uFlags
= SHGDN_FORPARSING
;
138 uFlags
= SHGDN_NORMAL
;
140 hr
= parent_folder
->GetDisplayNameOf(m_pidl
, uFlags
, &name
);
143 StrRetToStrW(&name
, m_pidl
, ppszName
);
151 HRESULT WINAPI
CShellItem::GetAttributes(SFGAOF sfgaoMask
, SFGAOF
*psfgaoAttribs
)
153 CComPtr
<IShellFolder
> parent_folder
;
154 LPCITEMIDLIST child_pidl
;
157 TRACE("(%p,%x,%p)\n", this, sfgaoMask
, psfgaoAttribs
);
159 hr
= get_parent_shellfolder(&parent_folder
);
162 child_pidl
= ILFindLastID(m_pidl
);
163 *psfgaoAttribs
= sfgaoMask
;
164 hr
= parent_folder
->GetAttributesOf(1, &child_pidl
, psfgaoAttribs
);
170 HRESULT WINAPI
CShellItem::Compare(IShellItem
*oth
, SICHINTF hint
, int *piOrder
)
173 CComPtr
<IPersistIDList
> pIDList
;
174 CComPtr
<IShellFolder
> parent_folder
;
177 TRACE("(%p,%p,%x,%p)\n", this, oth
, hint
, piOrder
);
179 if (piOrder
== NULL
|| oth
== NULL
)
182 hr
= oth
->QueryInterface(IID_PPV_ARG(IPersistIDList
, &pIDList
));
185 hr
= pIDList
->GetIDList(&pidl
);
188 hr
= get_parent_shellfolder(&parent_folder
);
191 hr
= parent_folder
->CompareIDs(hint
, m_pidl
, pidl
);
192 *piOrder
= static_cast<int>(SCODE_CODE(hr
));
203 HRESULT WINAPI
CShellItem::GetClassID(CLSID
*pClassID
)
205 TRACE("(%p,%p)\n", this, pClassID
);
207 *pClassID
= CLSID_ShellItem
;
211 HRESULT WINAPI
CShellItem::SetIDList(LPCITEMIDLIST pidlx
)
213 LPITEMIDLIST new_pidl
;
215 TRACE("(%p,%p)\n", this, pidlx
);
217 new_pidl
= ILClone(pidlx
);
225 return E_OUTOFMEMORY
;
228 HRESULT WINAPI
CShellItem::GetIDList(LPITEMIDLIST
*ppidl
)
230 TRACE("(%p,%p)\n", this, ppidl
);
232 *ppidl
= ILClone(m_pidl
);
236 return E_OUTOFMEMORY
;
239 HRESULT WINAPI
SHCreateShellItem(LPCITEMIDLIST pidlParent
,
240 IShellFolder
*psfParent
, LPCITEMIDLIST pidl
, IShellItem
**ppsi
)
243 IShellItem
*newShellItem
;
244 LPITEMIDLIST new_pidl
;
245 CComPtr
<IPersistIDList
> newPersistIDList
;
247 TRACE("(%p,%p,%p,%p)\n", pidlParent
, psfParent
, pidl
, ppsi
);
252 if (pidlParent
|| psfParent
)
254 LPITEMIDLIST temp_parent
= NULL
;
257 CComPtr
<IPersistFolder2
> ppf2Parent
;
259 if (FAILED(psfParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2Parent
))))
261 FIXME("couldn't get IPersistFolder2 interface of parent\n");
262 return E_NOINTERFACE
;
265 if (FAILED(ppf2Parent
->GetCurFolder(&temp_parent
)))
267 FIXME("couldn't get parent PIDL\n");
268 return E_NOINTERFACE
;
271 pidlParent
= temp_parent
;
274 new_pidl
= ILCombine(pidlParent
, pidl
);
278 return E_OUTOFMEMORY
;
282 new_pidl
= ILClone(pidl
);
284 return E_OUTOFMEMORY
;
287 hr
= CShellItem::_CreatorClass::CreateInstance(NULL
, IID_PPV_ARG(IShellItem
, &newShellItem
));
294 hr
= newShellItem
->QueryInterface(IID_PPV_ARG(IPersistIDList
, &newPersistIDList
));
300 hr
= newPersistIDList
->SetIDList(new_pidl
);
307 *ppsi
= newShellItem
;