Sync to trunk revision 63922.
[reactos.git] / dll / win32 / shell32 / folders / mydocuments.cpp
1 /*
2 * Virtual MyDocuments Folder
3 *
4 * Copyright 2007 Johannes Anderwald
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <precomp.h>
23
24 WINE_DEFAULT_DEBUG_CHANNEL (mydocs);
25
26 /*
27 CFileSysEnumX should not exist. CMyDocsFolder should aggregate a CFSFolder which always
28 maps the contents of CSIDL_PERSONAL. Therefore, CMyDocsFolder::EnumObjects simply calls
29 CFSFolder::EnumObjects.
30 */
31
32 /***********************************************************************
33 * MyDocumentsfolder implementation
34 */
35
36 class CFileSysEnumX :
37 public IEnumIDListImpl
38 {
39 private:
40 public:
41 CFileSysEnumX();
42 ~CFileSysEnumX();
43 HRESULT WINAPI Initialize(DWORD dwFlags);
44
45 BEGIN_COM_MAP(CFileSysEnumX)
46 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
47 END_COM_MAP()
48 };
49
50 static const shvheader MyDocumentsSFHeader[] = {
51 {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
52 {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
53 {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
54 {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
55 {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
56 };
57
58 #define MYDOCUMENTSSHELLVIEWCOLUMNS 5
59
60 CFileSysEnumX::CFileSysEnumX()
61 {
62 }
63
64 CFileSysEnumX::~CFileSysEnumX()
65 {
66 }
67
68 HRESULT WINAPI CFileSysEnumX::Initialize(DWORD dwFlags)
69 {
70 WCHAR szPath[MAX_PATH];
71
72 if (SHGetSpecialFolderPathW(0, szPath, CSIDL_PERSONAL, FALSE) == FALSE)
73 return E_FAIL;
74 return CreateFolderEnumList(szPath, dwFlags);
75 }
76
77 CMyDocsFolder::CMyDocsFolder()
78 {
79 pidlRoot = NULL;
80 sPathTarget = NULL;
81 mFSDropTarget = NULL;
82 }
83
84 CMyDocsFolder::~CMyDocsFolder()
85 {
86 TRACE ("-- destroying IShellFolder(%p)\n", this);
87 SHFree(pidlRoot);
88 HeapFree(GetProcessHeap(), 0, sPathTarget);
89 mFSDropTarget->Release();
90 }
91
92 HRESULT WINAPI CMyDocsFolder::FinalConstruct()
93 {
94 WCHAR szMyPath[MAX_PATH];
95
96 if (!SHGetSpecialFolderPathW(0, szMyPath, CSIDL_PERSONAL, TRUE))
97 return E_UNEXPECTED;
98
99 pidlRoot = _ILCreateMyDocuments(); /* my qualified pidl */
100 sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
101 wcscpy(sPathTarget, szMyPath);
102
103 LPITEMIDLIST pidl = NULL;
104
105 WCHAR szPath[MAX_PATH];
106 lstrcpynW(szPath, sPathTarget, MAX_PATH);
107 PathAddBackslashW(szPath);
108 CComPtr<IShellFolder> psfDesktop = NULL;
109
110 HRESULT hr = SHGetDesktopFolder(&psfDesktop);
111 if (SUCCEEDED(hr))
112 hr = psfDesktop->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL);
113 else
114 ERR("Error getting desktop folder\n");
115
116 if (SUCCEEDED(hr))
117 {
118 hr = psfDesktop->BindToObject(pidl, NULL, IID_IDropTarget, (LPVOID*) &mFSDropTarget);
119 CoTaskMemFree(pidl);
120 if (FAILED(hr))
121 ERR("Error Binding");
122 }
123 else
124 ERR("Error creating from %s\n", debugstr_w(szPath));
125
126 return S_OK;
127 }
128
129 HRESULT WINAPI CMyDocsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
130 DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
131 {
132 WCHAR szElement[MAX_PATH];
133 LPCWSTR szNext = NULL;
134 LPITEMIDLIST pidlTemp = NULL;
135 HRESULT hr = S_OK;
136 CLSID clsid;
137
138 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
139 this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
140 pchEaten, ppidl, pdwAttributes);
141
142 if (!lpszDisplayName || !ppidl)
143 return E_INVALIDARG;
144
145 *ppidl = 0;
146
147 if (pchEaten)
148 *pchEaten = 0; /* strange but like the original */
149
150 if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
151 {
152 szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
153 TRACE("-- element: %s\n", debugstr_w (szElement));
154 CLSIDFromString(szElement + 2, &clsid);
155 pidlTemp = _ILCreateGuid (PT_GUID, clsid);
156 }
157 else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
158 {
159 *ppidl = pidlTemp;
160 return S_OK;
161 }
162 else
163 {
164 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
165
166 if (*lpszDisplayName)
167 {
168 WCHAR szPath[MAX_PATH];
169 LPWSTR pathPtr;
170
171 /* build a complete path to create a simple pidl */
172 lstrcpynW(szPath, sPathTarget, MAX_PATH);
173 pathPtr = PathAddBackslashW(szPath);
174 if (pathPtr)
175 {
176 lstrcpynW(pathPtr, lpszDisplayName, MAX_PATH - (pathPtr - szPath));
177 hr = _ILCreateFromPathW(szPath, &pidlTemp);
178 }
179 else
180 {
181 /* should never reach here, but for completeness */
182 hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
183 }
184 }
185 else
186 pidlTemp = _ILCreateMyDocuments();
187
188 szNext = NULL;
189 }
190
191 if (SUCCEEDED(hr) && pidlTemp)
192 {
193 if (szNext && *szNext)
194 {
195 hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
196 &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
197 }
198 else
199 {
200 if (pdwAttributes && *pdwAttributes)
201 hr = SHELL32_GetItemAttributes(this, pidlTemp, pdwAttributes);
202 }
203 }
204
205 *ppidl = pidlTemp;
206
207 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
208
209 return hr;
210 }
211
212 /**************************************************************************
213 * ISF_MyDocuments_fnEnumObjects
214 */
215 HRESULT WINAPI CMyDocsFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
216 {
217 CComObject<CFileSysEnumX> *theEnumerator;
218 CComPtr<IEnumIDList> result;
219 HRESULT hResult;
220
221 TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
222
223 if (ppEnumIDList == NULL)
224 return E_POINTER;
225 *ppEnumIDList = NULL;
226 ATLTRY (theEnumerator = new CComObject<CFileSysEnumX>);
227 if (theEnumerator == NULL)
228 return E_OUTOFMEMORY;
229 hResult = theEnumerator->QueryInterface(IID_IEnumIDList, (void **)&result);
230 if (FAILED (hResult))
231 {
232 delete theEnumerator;
233 return hResult;
234 }
235 hResult = theEnumerator->Initialize(dwFlags);
236 if (FAILED (hResult))
237 return hResult;
238 *ppEnumIDList = result.Detach();
239
240 TRACE("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
241
242 return S_OK;
243 }
244
245 /**************************************************************************
246 * CMyDocsFolder::BindToObject
247 */
248 HRESULT WINAPI CMyDocsFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
249 {
250 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
251 this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
252
253 return SHELL32_BindToChild( pidlRoot, sPathTarget, pidl, riid, ppvOut );
254 }
255
256 /**************************************************************************
257 * CMyDocsFolder::BindToStorage
258 */
259 HRESULT WINAPI CMyDocsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
260 {
261 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n",
262 this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
263
264 *ppvOut = NULL;
265 return E_NOTIMPL;
266 }
267
268 /**************************************************************************
269 * CMyDocsFolder::CompareIDs
270 */
271 HRESULT WINAPI CMyDocsFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
272 {
273 int nReturn;
274
275 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
276 nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
277 TRACE ("-- %i\n", nReturn);
278 return nReturn;
279 }
280
281 /**************************************************************************
282 * CMyDocsFolder::CreateViewObject
283 */
284 HRESULT WINAPI CMyDocsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
285 {
286 LPSHELLVIEW pShellView;
287 HRESULT hr = E_INVALIDARG;
288
289 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
290 this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
291
292 if (!ppvOut)
293 return hr;
294
295 *ppvOut = NULL;
296
297 if (IsEqualIID (riid, IID_IDropTarget))
298 {
299 hr = this->QueryInterface (IID_IDropTarget, ppvOut);
300 }
301 else if (IsEqualIID (riid, IID_IContextMenu))
302 {
303 WARN ("IContextMenu not implemented\n");
304 hr = E_NOTIMPL;
305 }
306 else if (IsEqualIID (riid, IID_IShellView))
307 {
308 hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
309 if (pShellView)
310 {
311 hr = pShellView->QueryInterface(riid, ppvOut);
312 pShellView->Release();
313 }
314 }
315 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
316 return hr;
317 }
318
319 /**************************************************************************
320 * CMyDocsFolder::GetAttributesOf
321 */
322 HRESULT WINAPI CMyDocsFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
323 {
324 HRESULT hr = S_OK;
325 static const DWORD dwMyDocumentsAttributes =
326 SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_CANCOPY |
327 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
328
329 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
330 this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
331
332 if (!rgfInOut)
333 return E_INVALIDARG;
334 if (cidl && !apidl)
335 return E_INVALIDARG;
336
337 if (*rgfInOut == 0)
338 *rgfInOut = ~0;
339
340 if(cidl == 0) {
341 *rgfInOut &= dwMyDocumentsAttributes;
342 } else {
343 while (cidl > 0 && *apidl) {
344 pdump (*apidl);
345 if (_ILIsMyDocuments(*apidl)) {
346 *rgfInOut &= dwMyDocumentsAttributes;
347 } else {
348 SHELL32_GetItemAttributes (this, *apidl, rgfInOut);
349 }
350 apidl++;
351 cidl--;
352 }
353 }
354 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
355 *rgfInOut &= ~SFGAO_VALIDATE;
356
357 TRACE ("-- result=0x%08x\n", *rgfInOut);
358
359 return hr;
360 }
361
362 /**************************************************************************
363 * CMyDocsFolder::GetUIObjectOf
364 *
365 * PARAMETERS
366 * HWND hwndOwner, //[in ] Parent window for any output
367 * UINT cidl, //[in ] array size
368 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
369 * REFIID riid, //[in ] Requested Interface
370 * UINT* prgfInOut, //[ ] reserved
371 * LPVOID* ppvObject) //[out] Resulting Interface
372 *
373 */
374 HRESULT WINAPI CMyDocsFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
375 REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
376 {
377 LPITEMIDLIST pidl;
378 IUnknown *pObj = NULL;
379 HRESULT hr = E_INVALIDARG;
380
381 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
382 this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
383
384 if (!ppvOut)
385 return hr;
386
387 *ppvOut = NULL;
388
389 if (IsEqualIID (riid, IID_IContextMenu))
390 {
391 hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu**)&pObj);
392 }
393 else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
394 {
395 hr = IDataObject_Constructor( hwndOwner,
396 pidlRoot, apidl, cidl, (IDataObject **)&pObj);
397 }
398 else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
399 {
400 pidl = ILCombine (pidlRoot, apidl[0]);
401 pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
402 SHFree (pidl);
403 hr = S_OK;
404 }
405 else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
406 {
407 pidl = ILCombine (pidlRoot, apidl[0]);
408 pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
409 SHFree (pidl);
410 hr = S_OK;
411 }
412 else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
413 {
414 hr = this->QueryInterface (IID_IDropTarget, (LPVOID *)&pObj);
415 }
416 else if ((IsEqualIID(riid, IID_IShellLinkW) ||
417 IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
418 {
419 pidl = ILCombine (pidlRoot, apidl[0]);
420 hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
421 SHFree (pidl);
422 }
423 else
424 hr = E_NOINTERFACE;
425
426 if (SUCCEEDED(hr) && !pObj)
427 hr = E_OUTOFMEMORY;
428
429 *ppvOut = pObj;
430 TRACE ("(%p)->hr=0x%08x\n", this, hr);
431 return hr;
432 }
433
434 HRESULT WINAPI CMyDocsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
435 {
436 HRESULT hr = S_OK;
437 LPWSTR pszPath;
438
439 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
440 pdump (pidl);
441
442 if (!strRet)
443 return E_INVALIDARG;
444
445 pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
446 if (!pszPath)
447 return E_OUTOFMEMORY;
448
449 ZeroMemory(pszPath, (MAX_PATH + 1) * sizeof(WCHAR));
450
451 if (_ILIsMyDocuments (pidl))
452 {
453 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
454 (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
455 wcscpy(pszPath, sPathTarget);
456 else
457 HCR_GetClassNameW(CLSID_MyDocuments, pszPath, MAX_PATH);
458 TRACE("CP\n");
459 }
460 else if (_ILIsPidlSimple (pidl))
461 {
462 GUID const *clsid;
463
464 if ((clsid = _ILGetGUIDPointer (pidl)))
465 {
466 if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
467 {
468 int bWantsForParsing;
469
470 /*
471 * We can only get a filesystem path from a shellfolder if the
472 * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
473 *
474 * Exception: The MyComputer folder doesn't have this key,
475 * but any other filesystem backed folder it needs it.
476 */
477 if (IsEqualIID (*clsid, CLSID_MyDocuments))
478 {
479 bWantsForParsing = TRUE;
480 }
481 else
482 {
483 /* get the "WantsFORPARSING" flag from the registry */
484 static const WCHAR clsidW[] = L"CLSID\\";
485 static const WCHAR shellfolderW[] = L"shellfolder";
486 static const WCHAR wantsForParsingW[] = L"WantsForParsing";
487 WCHAR szRegPath[100];
488 LONG r;
489
490 wcscpy (szRegPath, clsidW);
491 SHELL32_GUIDToStringW (*clsid, &szRegPath[6]);
492 wcscat (szRegPath, shellfolderW);
493 r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
494 wantsForParsingW, NULL, NULL, NULL);
495 if (r == ERROR_SUCCESS)
496 bWantsForParsing = TRUE;
497 else
498 bWantsForParsing = FALSE;
499 }
500
501 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
502 bWantsForParsing)
503 {
504 /*
505 * we need the filesystem path to the destination folder.
506 * Only the folder itself can know it
507 */
508 hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
509 pszPath,
510 MAX_PATH);
511 TRACE("CP\n");
512 }
513 else
514 {
515 /* parsing name like ::{...} */
516 pszPath[0] = ':';
517 pszPath[1] = ':';
518 SHELL32_GUIDToStringW (*clsid, &pszPath[2]);
519 TRACE("CP\n");
520 }
521 }
522 else
523 {
524 /* user friendly name */
525 HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
526 TRACE("CP\n");
527 }
528 }
529 else
530 {
531 int cLen = 0;
532
533 /* file system folder or file rooted at the desktop */
534 if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
535 (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
536 {
537 lstrcpynW(pszPath, sPathTarget, MAX_PATH - 1);
538 TRACE("CP %s\n", debugstr_w(pszPath));
539 }
540
541 if (!_ILIsDesktop(pidl))
542 {
543 PathAddBackslashW(pszPath);
544 cLen = wcslen(pszPath);
545 _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
546 if (!_ILIsFolder(pidl))
547 {
548 SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
549 TRACE("CP\n");
550 }
551 }
552 }
553 }
554 else
555 {
556 /* a complex pidl, let the subfolder do the work */
557 hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
558 pszPath, MAX_PATH);
559 TRACE("CP\n");
560 }
561
562 if (SUCCEEDED(hr))
563 {
564 strRet->uType = STRRET_WSTR;
565 strRet->pOleStr = pszPath;
566 }
567 else
568 CoTaskMemFree(pszPath);
569
570 TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr);
571 return hr;
572 }
573
574 HRESULT WINAPI CMyDocsFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
575 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
576 {
577 FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl,
578 debugstr_w (lpName), dwFlags, pPidlOut);
579
580 return E_FAIL;
581 }
582
583 HRESULT WINAPI CMyDocsFolder::GetDefaultSearchGUID(GUID *pguid)
584 {
585 FIXME ("(%p)\n", this);
586 return E_NOTIMPL;
587 }
588
589 HRESULT WINAPI CMyDocsFolder::EnumSearches(IEnumExtraSearch **ppenum)
590 {
591 FIXME ("(%p)\n", this);
592 return E_NOTIMPL;
593 }
594
595 HRESULT WINAPI CMyDocsFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
596 {
597 TRACE ("(%p)\n", this);
598
599 if (pSort)
600 *pSort = 0;
601 if (pDisplay)
602 *pDisplay = 0;
603
604 return S_OK;
605 }
606
607 HRESULT WINAPI CMyDocsFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
608 {
609 TRACE ("(%p)\n", this);
610
611 if (!pcsFlags || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
612 return E_INVALIDARG;
613
614 *pcsFlags = MyDocumentsSFHeader[iColumn].pcsFlags;
615
616 return S_OK;
617 }
618
619 HRESULT WINAPI CMyDocsFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
620 {
621 FIXME ("(%p)\n", this);
622
623 return E_NOTIMPL;
624 }
625
626 HRESULT WINAPI CMyDocsFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
627 {
628 HRESULT hr = S_OK;
629
630 TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
631
632 if (!psd || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
633 return E_INVALIDARG;
634
635 if (!pidl)
636 {
637 psd->fmt = MyDocumentsSFHeader[iColumn].fmt;
638 psd->cxChar = MyDocumentsSFHeader[iColumn].cxChar;
639 psd->str.uType = STRRET_CSTR;
640 LoadStringA (shell32_hInstance, MyDocumentsSFHeader[iColumn].colnameid,
641 psd->str.cStr, MAX_PATH);
642 return S_OK;
643 }
644
645 /* the data from the pidl */
646 psd->str.uType = STRRET_CSTR;
647 switch (iColumn)
648 {
649 case 0: /* name */
650 hr = GetDisplayNameOf(pidl,
651 SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
652 break;
653 case 1: /* size */
654 _ILGetFileSize (pidl, psd->str.cStr, MAX_PATH);
655 break;
656 case 2: /* type */
657 _ILGetFileType (pidl, psd->str.cStr, MAX_PATH);
658 break;
659 case 3: /* date */
660 _ILGetFileDate (pidl, psd->str.cStr, MAX_PATH);
661 break;
662 case 4: /* attributes */
663 _ILGetFileAttributes (pidl, psd->str.cStr, MAX_PATH);
664 break;
665 }
666
667 return hr;
668 }
669
670 HRESULT WINAPI CMyDocsFolder::MapColumnToSCID (UINT column, SHCOLUMNID *pscid)
671 {
672 FIXME ("(%p)\n", this);
673 return E_NOTIMPL;
674 }
675
676 HRESULT WINAPI CMyDocsFolder::GetClassID(CLSID *lpClassId)
677 {
678 static GUID const CLSID_MyDocuments =
679 { 0x450d8fba, 0xad25, 0x11d0, {0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03} };
680
681 TRACE ("(%p)\n", this);
682
683 if (!lpClassId)
684 return E_POINTER;
685
686 memcpy(lpClassId, &CLSID_MyDocuments, sizeof(GUID));
687
688 return S_OK;
689 }
690
691 HRESULT WINAPI CMyDocsFolder::Initialize(LPCITEMIDLIST pidl)
692 {
693 TRACE ("(%p)->(%p)\n", this, pidl);
694
695 return E_NOTIMPL;
696 }
697
698 HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
699 {
700 TRACE ("(%p)->(%p)\n", this, pidl);
701
702 if (!pidl) return E_POINTER;
703 *pidl = ILClone (pidlRoot);
704 return S_OK;
705 }
706
707 HRESULT WINAPI CMyDocsFolder::DragEnter(IDataObject *pDataObject,
708 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
709 {
710 return mFSDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
711 }
712
713 HRESULT WINAPI CMyDocsFolder::DragOver(DWORD dwKeyState, POINTL pt,
714 DWORD *pdwEffect)
715 {
716 return mFSDropTarget->DragOver(dwKeyState, pt, pdwEffect);
717 }
718
719 HRESULT WINAPI CMyDocsFolder::DragLeave()
720 {
721 return mFSDropTarget->DragLeave();
722 }
723
724 HRESULT WINAPI CMyDocsFolder::Drop(IDataObject *pDataObject,
725 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
726 {
727 return mFSDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
728 }