[RSHELL]
[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_PPV_ARG(IDropTarget, &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 return ShellObjectCreatorInit<CFileSysEnumX>(dwFlags, IID_IEnumIDList, ppEnumIDList);
218 }
219
220 /**************************************************************************
221 * CMyDocsFolder::BindToObject
222 */
223 HRESULT WINAPI CMyDocsFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
224 {
225 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
226 this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
227
228 return SHELL32_BindToChild( pidlRoot, sPathTarget, pidl, riid, ppvOut );
229 }
230
231 /**************************************************************************
232 * CMyDocsFolder::BindToStorage
233 */
234 HRESULT WINAPI CMyDocsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
235 {
236 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n",
237 this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
238
239 *ppvOut = NULL;
240 return E_NOTIMPL;
241 }
242
243 /**************************************************************************
244 * CMyDocsFolder::CompareIDs
245 */
246 HRESULT WINAPI CMyDocsFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
247 {
248 int nReturn;
249
250 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
251 nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
252 TRACE ("-- %i\n", nReturn);
253 return nReturn;
254 }
255
256 /**************************************************************************
257 * CMyDocsFolder::CreateViewObject
258 */
259 HRESULT WINAPI CMyDocsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
260 {
261 CComPtr<IShellView> pShellView;
262 HRESULT hr = E_INVALIDARG;
263
264 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
265 this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
266
267 if (!ppvOut)
268 return hr;
269
270 *ppvOut = NULL;
271
272 if (IsEqualIID (riid, IID_IDropTarget))
273 {
274 hr = this->QueryInterface (IID_IDropTarget, ppvOut);
275 }
276 else if (IsEqualIID (riid, IID_IContextMenu))
277 {
278 WARN ("IContextMenu not implemented\n");
279 hr = E_NOTIMPL;
280 }
281 else if (IsEqualIID (riid, IID_IShellView))
282 {
283 hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
284 if (pShellView)
285 {
286 hr = pShellView->QueryInterface(riid, ppvOut);
287 }
288 }
289 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
290 return hr;
291 }
292
293 /**************************************************************************
294 * CMyDocsFolder::GetAttributesOf
295 */
296 HRESULT WINAPI CMyDocsFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
297 {
298 HRESULT hr = S_OK;
299 static const DWORD dwMyDocumentsAttributes =
300 SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_CANCOPY |
301 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
302
303 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
304 this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
305
306 if (!rgfInOut)
307 return E_INVALIDARG;
308 if (cidl && !apidl)
309 return E_INVALIDARG;
310
311 if (*rgfInOut == 0)
312 *rgfInOut = ~0;
313
314 if(cidl == 0) {
315 *rgfInOut &= dwMyDocumentsAttributes;
316 } else {
317 while (cidl > 0 && *apidl) {
318 pdump (*apidl);
319 if (_ILIsMyDocuments(*apidl)) {
320 *rgfInOut &= dwMyDocumentsAttributes;
321 } else {
322 SHELL32_GetItemAttributes (this, *apidl, rgfInOut);
323 }
324 apidl++;
325 cidl--;
326 }
327 }
328 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
329 *rgfInOut &= ~SFGAO_VALIDATE;
330
331 TRACE ("-- result=0x%08x\n", *rgfInOut);
332
333 return hr;
334 }
335
336 /**************************************************************************
337 * CMyDocsFolder::GetUIObjectOf
338 *
339 * PARAMETERS
340 * HWND hwndOwner, //[in ] Parent window for any output
341 * UINT cidl, //[in ] array size
342 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
343 * REFIID riid, //[in ] Requested Interface
344 * UINT* prgfInOut, //[ ] reserved
345 * LPVOID* ppvObject) //[out] Resulting Interface
346 *
347 */
348 HRESULT WINAPI CMyDocsFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
349 REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
350 {
351 LPITEMIDLIST pidl;
352 IUnknown *pObj = NULL;
353 HRESULT hr = E_INVALIDARG;
354
355 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
356 this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
357
358 if (!ppvOut)
359 return hr;
360
361 *ppvOut = NULL;
362
363 if (IsEqualIID (riid, IID_IContextMenu))
364 {
365 IContextMenu * pCm = NULL;
366 hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, 0, NULL, &pCm);
367 pObj = pCm;
368 }
369 else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
370 {
371 IDataObject * pDo = NULL;
372 hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, &pDo);
373 pObj = pDo;
374 }
375 else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
376 {
377 pidl = ILCombine (pidlRoot, apidl[0]);
378 pObj = IExtractIconA_Constructor (pidl);
379 SHFree (pidl);
380 hr = S_OK;
381 }
382 else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
383 {
384 pidl = ILCombine (pidlRoot, apidl[0]);
385 pObj = IExtractIconW_Constructor (pidl);
386 SHFree (pidl);
387 hr = S_OK;
388 }
389 else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
390 {
391 IDropTarget * pDt = NULL;
392 hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
393 pObj = pDt;
394 }
395 else if ((IsEqualIID(riid, IID_IShellLinkW) ||
396 IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
397 {
398 pidl = ILCombine (pidlRoot, apidl[0]);
399 hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
400 SHFree (pidl);
401 }
402 else
403 hr = E_NOINTERFACE;
404
405 if (SUCCEEDED(hr) && !pObj)
406 hr = E_OUTOFMEMORY;
407
408 *ppvOut = pObj;
409 TRACE ("(%p)->hr=0x%08x\n", this, hr);
410 return hr;
411 }
412
413 HRESULT WINAPI CMyDocsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
414 {
415 HRESULT hr = S_OK;
416 LPWSTR pszPath;
417
418 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
419 pdump (pidl);
420
421 if (!strRet)
422 return E_INVALIDARG;
423
424 pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
425 if (!pszPath)
426 return E_OUTOFMEMORY;
427
428 ZeroMemory(pszPath, (MAX_PATH + 1) * sizeof(WCHAR));
429
430 if (_ILIsMyDocuments (pidl))
431 {
432 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
433 (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
434 wcscpy(pszPath, sPathTarget);
435 else
436 HCR_GetClassNameW(CLSID_MyDocuments, pszPath, MAX_PATH);
437 TRACE("CP\n");
438 }
439 else if (_ILIsPidlSimple (pidl))
440 {
441 GUID const *clsid;
442
443 if ((clsid = _ILGetGUIDPointer (pidl)))
444 {
445 if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
446 {
447 int bWantsForParsing;
448
449 /*
450 * We can only get a filesystem path from a shellfolder if the
451 * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
452 *
453 * Exception: The MyComputer folder doesn't have this key,
454 * but any other filesystem backed folder it needs it.
455 */
456 if (IsEqualIID (*clsid, CLSID_MyDocuments))
457 {
458 bWantsForParsing = TRUE;
459 }
460 else
461 {
462 /* get the "WantsFORPARSING" flag from the registry */
463 static const WCHAR clsidW[] = L"CLSID\\";
464 static const WCHAR shellfolderW[] = L"shellfolder";
465 static const WCHAR wantsForParsingW[] = L"WantsForParsing";
466 WCHAR szRegPath[100];
467 LONG r;
468
469 wcscpy (szRegPath, clsidW);
470 SHELL32_GUIDToStringW (*clsid, &szRegPath[6]);
471 wcscat (szRegPath, shellfolderW);
472 r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
473 wantsForParsingW, NULL, NULL, NULL);
474 if (r == ERROR_SUCCESS)
475 bWantsForParsing = TRUE;
476 else
477 bWantsForParsing = FALSE;
478 }
479
480 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
481 bWantsForParsing)
482 {
483 /*
484 * we need the filesystem path to the destination folder.
485 * Only the folder itself can know it
486 */
487 hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
488 pszPath,
489 MAX_PATH);
490 TRACE("CP\n");
491 }
492 else
493 {
494 /* parsing name like ::{...} */
495 pszPath[0] = ':';
496 pszPath[1] = ':';
497 SHELL32_GUIDToStringW (*clsid, &pszPath[2]);
498 TRACE("CP\n");
499 }
500 }
501 else
502 {
503 /* user friendly name */
504 HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
505 TRACE("CP\n");
506 }
507 }
508 else
509 {
510 int cLen = 0;
511
512 /* file system folder or file rooted at the desktop */
513 if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
514 (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
515 {
516 lstrcpynW(pszPath, sPathTarget, MAX_PATH - 1);
517 TRACE("CP %s\n", debugstr_w(pszPath));
518 }
519
520 if (!_ILIsDesktop(pidl))
521 {
522 PathAddBackslashW(pszPath);
523 cLen = wcslen(pszPath);
524 _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
525 if (!_ILIsFolder(pidl))
526 {
527 SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
528 TRACE("CP\n");
529 }
530 }
531 }
532 }
533 else
534 {
535 /* a complex pidl, let the subfolder do the work */
536 hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
537 pszPath, MAX_PATH);
538 TRACE("CP\n");
539 }
540
541 if (SUCCEEDED(hr))
542 {
543 strRet->uType = STRRET_WSTR;
544 strRet->pOleStr = pszPath;
545 }
546 else
547 CoTaskMemFree(pszPath);
548
549 TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr);
550 return hr;
551 }
552
553 HRESULT WINAPI CMyDocsFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
554 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
555 {
556 FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl,
557 debugstr_w (lpName), dwFlags, pPidlOut);
558
559 return E_FAIL;
560 }
561
562 HRESULT WINAPI CMyDocsFolder::GetDefaultSearchGUID(GUID *pguid)
563 {
564 FIXME ("(%p)\n", this);
565 return E_NOTIMPL;
566 }
567
568 HRESULT WINAPI CMyDocsFolder::EnumSearches(IEnumExtraSearch **ppenum)
569 {
570 FIXME ("(%p)\n", this);
571 return E_NOTIMPL;
572 }
573
574 HRESULT WINAPI CMyDocsFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
575 {
576 TRACE ("(%p)\n", this);
577
578 if (pSort)
579 *pSort = 0;
580 if (pDisplay)
581 *pDisplay = 0;
582
583 return S_OK;
584 }
585
586 HRESULT WINAPI CMyDocsFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
587 {
588 TRACE ("(%p)\n", this);
589
590 if (!pcsFlags || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
591 return E_INVALIDARG;
592
593 *pcsFlags = MyDocumentsSFHeader[iColumn].pcsFlags;
594
595 return S_OK;
596 }
597
598 HRESULT WINAPI CMyDocsFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
599 {
600 FIXME ("(%p)\n", this);
601
602 return E_NOTIMPL;
603 }
604
605 HRESULT WINAPI CMyDocsFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
606 {
607 HRESULT hr = S_OK;
608
609 TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
610
611 if (!psd || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
612 return E_INVALIDARG;
613
614 if (!pidl)
615 {
616 psd->fmt = MyDocumentsSFHeader[iColumn].fmt;
617 psd->cxChar = MyDocumentsSFHeader[iColumn].cxChar;
618 psd->str.uType = STRRET_CSTR;
619 LoadStringA (shell32_hInstance, MyDocumentsSFHeader[iColumn].colnameid,
620 psd->str.cStr, MAX_PATH);
621 return S_OK;
622 }
623
624 /* the data from the pidl */
625 psd->str.uType = STRRET_CSTR;
626 switch (iColumn)
627 {
628 case 0: /* name */
629 hr = GetDisplayNameOf(pidl,
630 SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
631 break;
632 case 1: /* size */
633 _ILGetFileSize (pidl, psd->str.cStr, MAX_PATH);
634 break;
635 case 2: /* type */
636 _ILGetFileType (pidl, psd->str.cStr, MAX_PATH);
637 break;
638 case 3: /* date */
639 _ILGetFileDate (pidl, psd->str.cStr, MAX_PATH);
640 break;
641 case 4: /* attributes */
642 _ILGetFileAttributes (pidl, psd->str.cStr, MAX_PATH);
643 break;
644 }
645
646 return hr;
647 }
648
649 HRESULT WINAPI CMyDocsFolder::MapColumnToSCID (UINT column, SHCOLUMNID *pscid)
650 {
651 FIXME ("(%p)\n", this);
652 return E_NOTIMPL;
653 }
654
655 HRESULT WINAPI CMyDocsFolder::GetClassID(CLSID *lpClassId)
656 {
657 static GUID const CLSID_MyDocuments =
658 { 0x450d8fba, 0xad25, 0x11d0, {0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03} };
659
660 TRACE ("(%p)\n", this);
661
662 if (!lpClassId)
663 return E_POINTER;
664
665 memcpy(lpClassId, &CLSID_MyDocuments, sizeof(GUID));
666
667 return S_OK;
668 }
669
670 HRESULT WINAPI CMyDocsFolder::Initialize(LPCITEMIDLIST pidl)
671 {
672 TRACE ("(%p)->(%p)\n", this, pidl);
673
674 return E_NOTIMPL;
675 }
676
677 HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
678 {
679 TRACE ("(%p)->(%p)\n", this, pidl);
680
681 if (!pidl) return E_POINTER;
682 *pidl = ILClone (pidlRoot);
683 return S_OK;
684 }
685
686 HRESULT WINAPI CMyDocsFolder::DragEnter(IDataObject *pDataObject,
687 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
688 {
689 return mFSDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
690 }
691
692 HRESULT WINAPI CMyDocsFolder::DragOver(DWORD dwKeyState, POINTL pt,
693 DWORD *pdwEffect)
694 {
695 return mFSDropTarget->DragOver(dwKeyState, pt, pdwEffect);
696 }
697
698 HRESULT WINAPI CMyDocsFolder::DragLeave()
699 {
700 return mFSDropTarget->DragLeave();
701 }
702
703 HRESULT WINAPI CMyDocsFolder::Drop(IDataObject *pDataObject,
704 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
705 {
706 return mFSDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
707 }