[SHELL32] Partially implement CFolderItems. Thanks to Giannis for the advice :)
[reactos.git] / reactos / dll / win32 / shell32 / CFolderItems.cpp
1 /*
2 * FolderItem(s) implementation
3 *
4 * Copyright 2015,2016 Mark Jansen
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "precomp.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(shell);
24
25
26 CFolderItem::CFolderItem()
27 {
28 }
29
30 CFolderItem::~CFolderItem()
31 {
32 }
33
34 void CFolderItem::Init(LPITEMIDLIST idlist)
35 {
36 m_idlist.Attach(idlist);
37 }
38
39 // *** FolderItem methods ***
40 HRESULT STDMETHODCALLTYPE CFolderItem::get_Application(IDispatch **ppid)
41 {
42 TRACE("(%p, %p)\n", this, ppid);
43 return E_NOTIMPL;
44 }
45
46 HRESULT STDMETHODCALLTYPE CFolderItem::get_Parent(IDispatch **ppid)
47 {
48 TRACE("(%p, %p)\n", this, ppid);
49 return E_NOTIMPL;
50 }
51
52 HRESULT STDMETHODCALLTYPE CFolderItem::get_Name(BSTR *pbs)
53 {
54 TRACE("(%p, %p)\n", this, pbs);
55 return E_NOTIMPL;
56 }
57
58 HRESULT STDMETHODCALLTYPE CFolderItem::put_Name(BSTR bs)
59 {
60 TRACE("(%p, %s)\n", this, wine_dbgstr_w(bs));
61 return E_NOTIMPL;
62 }
63
64 HRESULT STDMETHODCALLTYPE CFolderItem::get_Path(BSTR *pbs)
65 {
66 CComPtr<IShellFolder> psfDesktop;
67
68 HRESULT hr = SHGetDesktopFolder(&psfDesktop);
69 if (!SUCCEEDED(hr))
70 return hr;
71
72 STRRET strret;
73 hr = psfDesktop->GetDisplayNameOf(m_idlist, SHGDN_FORPARSING, &strret);
74 if (FAILED_UNEXPECTEDLY(hr))
75 return hr;
76
77 return StrRetToBSTR(&strret, NULL, pbs);
78 }
79
80 HRESULT STDMETHODCALLTYPE CFolderItem::get_GetLink(IDispatch **ppid)
81 {
82 TRACE("(%p, %p)\n", this, ppid);
83 return E_NOTIMPL;
84 }
85
86 HRESULT STDMETHODCALLTYPE CFolderItem::get_GetFolder(IDispatch **ppid)
87 {
88 TRACE("(%p, %p)\n", this, ppid);
89 return E_NOTIMPL;
90 }
91
92 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsLink(VARIANT_BOOL *pb)
93 {
94 TRACE("(%p, %p)\n", this, pb);
95 return E_NOTIMPL;
96 }
97
98 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFolder(VARIANT_BOOL *pb)
99 {
100 TRACE("(%p, %p)\n", this, pb);
101 return E_NOTIMPL;
102 }
103
104 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsFileSystem(VARIANT_BOOL *pb)
105 {
106 TRACE("(%p, %p)\n", this, pb);
107 return E_NOTIMPL;
108 }
109
110 HRESULT STDMETHODCALLTYPE CFolderItem::get_IsBrowsable(VARIANT_BOOL *pb)
111 {
112 TRACE("(%p, %p)\n", this, pb);
113 return E_NOTIMPL;
114 }
115
116 HRESULT STDMETHODCALLTYPE CFolderItem::get_ModifyDate(DATE *pdt)
117 {
118 TRACE("(%p, %p)\n", this, pdt);
119 return E_NOTIMPL;
120 }
121
122 HRESULT STDMETHODCALLTYPE CFolderItem::put_ModifyDate(DATE dt)
123 {
124 TRACE("(%p, %f)\n", this, dt);
125 return E_NOTIMPL;
126 }
127
128 HRESULT STDMETHODCALLTYPE CFolderItem::get_Size(LONG *pul)
129 {
130 TRACE("(%p, %p)\n", this, pul);
131 return E_NOTIMPL;
132 }
133
134 HRESULT STDMETHODCALLTYPE CFolderItem::get_Type(BSTR *pbs)
135 {
136 TRACE("(%p, %p)\n", this, pbs);
137 return E_NOTIMPL;
138 }
139
140 HRESULT STDMETHODCALLTYPE CFolderItem::Verbs(FolderItemVerbs **ppfic)
141 {
142 if (!ppfic)
143 return E_POINTER;
144 CFolderItemVerbs* verbs = new CComObject<CFolderItemVerbs>();
145 HRESULT hr = verbs->Init(m_idlist);
146 if (FAILED_UNEXPECTEDLY(hr))
147 {
148 delete verbs;
149 return hr;
150 }
151 verbs->AddRef();
152 *ppfic = verbs;
153 return S_OK;
154 }
155
156 HRESULT STDMETHODCALLTYPE CFolderItem::InvokeVerb(VARIANT vVerb)
157 {
158 TRACE("(%p, %s)\n", this, wine_dbgstr_variant(&vVerb));
159 return E_NOTIMPL;
160 }
161
162
163
164 CFolderItems::CFolderItems()
165 :m_Count(-1)
166 {
167 }
168
169 CFolderItems::~CFolderItems()
170 {
171 }
172
173 HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
174 {
175 CComPtr<IShellFolder> psfDesktop, psfTarget;
176
177 m_idlist.Attach(idlist);
178
179 HRESULT hr = SHGetDesktopFolder(&psfDesktop);
180 if (FAILED_UNEXPECTEDLY(hr))
181 return hr;
182
183 hr = psfDesktop->BindToObject(m_idlist, NULL, IID_PPV_ARG(IShellFolder, &psfTarget));
184 if (FAILED_UNEXPECTEDLY(hr))
185 return hr;
186
187 hr = psfTarget->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &m_EnumIDList);
188
189 if (FAILED_UNEXPECTEDLY(hr))
190 return hr;
191
192 return S_OK;
193 }
194
195 // *** FolderItems methods ***
196 HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
197 {
198 if (!m_EnumIDList)
199 return E_FAIL;
200
201 if (!plCount)
202 return E_POINTER;
203
204 if (m_Count == -1)
205 {
206 long count = 0;
207
208 HRESULT hr = m_EnumIDList->Reset();
209 if (FAILED_UNEXPECTEDLY(hr))
210 return hr;
211
212 CComHeapPtr<ITEMIDLIST> Pidl;
213 hr = m_EnumIDList->Next(1, &Pidl, 0);
214 while (hr != S_FALSE)
215 {
216 count++;
217 Pidl.Free();
218 }
219 m_Count = count;
220 }
221 *plCount = m_Count;
222
223 return S_OK;
224 }
225
226 HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid)
227 {
228 TRACE("(%p, %p)\n", this, ppid);
229 return E_NOTIMPL;
230 }
231
232 HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid)
233 {
234 TRACE("(%p, %p)\n", this, ppid);
235 return E_NOTIMPL;
236 }
237
238 HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
239 {
240 if (!m_EnumIDList)
241 return E_FAIL;
242
243 if (V_VT(&index) != VT_I4 && V_VT(&index) != VT_UI4)
244 return E_INVALIDARG;
245
246 ULONG count = V_UI4(&index);
247
248 HRESULT hr = m_EnumIDList->Reset();
249 if (FAILED_UNEXPECTEDLY(hr))
250 return hr;
251
252 hr = m_EnumIDList->Skip(count);
253
254 if (FAILED_UNEXPECTEDLY(hr))
255 return hr;
256
257 CComHeapPtr<ITEMIDLIST> spPidl;
258 hr = m_EnumIDList->Next(1, &spPidl, 0);
259 if (hr == S_OK)
260 {
261 CFolderItem* item = new CComObject<CFolderItem>();
262 item->AddRef();
263 item->Init(spPidl.Detach());
264 *ppid = item;
265 return S_OK;
266 }
267
268 return hr;
269 }
270
271 HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
272 {
273 CFolderItems* items = new CComObject<CFolderItems>();
274 items->AddRef();
275 items->Init(ILClone(m_idlist));
276 *ppunk = items;
277 return S_OK;
278 }
279