2 * Virtual Desktop Folder
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
6 * Copyright 2009 Andrew Hill
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
);
28 CDesktopFolder should create two file system folders internally, one representing the
29 user's desktop folder, and the other representing the common desktop folder. It should
30 also create a CRegFolder to represent the virtual items that exist only in the registry.
31 The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
32 CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
34 The CDesktopFolderEnum class should create two enumerators, one for each of the file
35 system folders, and enumerate the contents of each folder. Since the CRegFolder
36 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
37 CDesktopFolderEnum is only responsible for returning the physical items.
38 CDesktopFolderEnum is incorrect where it filters My Computer from the enumeration
39 if the new start menu is used. The CDesktopViewCallback is responsible for filtering
40 it from the view by handling the IncludeObject query to return S_FALSE. The enumerator
41 always shows My Computer.
44 /* Undocumented functions from shdocvw */
45 extern "C" HRESULT WINAPI
IEParseDisplayNameWithBCW(DWORD codepage
, LPCWSTR lpszDisplayName
, LPBC pbc
, LPITEMIDLIST
*ppidl
);
47 class CDesktopFolderEnum
:
48 public CEnumIDListBase
51 // CComPtr fDesktopEnumerator;
52 // CComPtr fCommonDesktopEnumerator;
55 ~CDesktopFolderEnum();
56 HRESULT WINAPI
Initialize(CDesktopFolder
*desktopFolder
, HWND hwndOwner
, DWORD dwFlags
);
58 BEGIN_COM_MAP(CDesktopFolderEnum
)
59 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
63 int SHELL_ConfirmMsgBox(HWND hWnd
, LPWSTR lpszText
, LPWSTR lpszCaption
, HICON hIcon
, BOOL bYesToAll
);
65 static const shvheader DesktopSFHeader
[] = {
66 {IDS_SHV_COLUMN_NAME
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 15},
67 {IDS_SHV_COLUMN_COMMENTS
, SHCOLSTATE_TYPE_STR
, LVCFMT_LEFT
, 10},
68 {IDS_SHV_COLUMN_TYPE
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10},
69 {IDS_SHV_COLUMN_SIZE
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
70 {IDS_SHV_COLUMN_MODIFIED
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 12},
71 {IDS_SHV_COLUMN_ATTRIBUTES
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10}
74 #define DESKTOPSHELLVIEWCOLUMNS 6
76 static const DWORD dwDesktopAttributes
=
77 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
78 SFGAO_STORAGEANCESTOR
| SFGAO_HASPROPSHEET
| SFGAO_STORAGE
| SFGAO_CANLINK
;
79 static const DWORD dwMyComputerAttributes
=
80 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
81 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
82 static DWORD dwMyNetPlacesAttributes
=
83 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
84 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
87 CDesktopFolderEnum::CDesktopFolderEnum()
91 CDesktopFolderEnum::~CDesktopFolderEnum()
95 static const WCHAR ClassicStartMenuW
[] = L
"SOFTWARE\\Microsoft\\Windows\\"
96 L
"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
99 IsNamespaceExtensionHidden(const WCHAR
*iid
)
101 DWORD Result
, dwResult
;
102 dwResult
= sizeof(DWORD
);
104 if (RegGetValueW(HKEY_CURRENT_USER
, /* FIXME use NewStartPanel when activated */
110 &dwResult
) != ERROR_SUCCESS
)
118 /**************************************************************************
119 * CreateDesktopEnumList()
122 HRESULT WINAPI
CDesktopFolderEnum::Initialize(CDesktopFolder
*desktopFolder
, HWND hwndOwner
, DWORD dwFlags
)
125 WCHAR szPath
[MAX_PATH
];
127 static const WCHAR MyDocumentsClassString
[] = L
"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
128 static const WCHAR Desktop_NameSpaceW
[] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
130 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
132 /* enumerate the root folders */
133 if (dwFlags
& SHCONTF_FOLDERS
)
139 /* create the pidl for This item */
140 if (IsNamespaceExtensionHidden(MyDocumentsClassString
) < 1)
142 ret
= AddToEnumList(_ILCreateMyDocuments());
144 ret
= AddToEnumList(_ILCreateMyComputer());
146 for (i
= 0; i
< 2; i
++)
149 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
151 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
153 if (dwResult
== ERROR_SUCCESS
)
164 size
= sizeof (iid
) / sizeof (iid
[0]);
165 r
= RegEnumKeyExW(hkey
, i
, iid
, &size
, 0, NULL
, NULL
, NULL
);
166 if (ERROR_SUCCESS
== r
)
168 if (IsNamespaceExtensionHidden(iid
) < 1)
170 pidl
= _ILCreateGuidFromStrW(iid
);
173 if (!HasItemWithCLSID(pidl
))
175 ret
= AddToEnumList(pidl
);
184 else if (ERROR_NO_MORE_ITEMS
== r
)
193 for (i
= 0; i
< 2; i
++)
196 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
198 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
200 if (dwResult
== ERROR_SUCCESS
)
202 DWORD j
= 0, dwVal
, Val
, dwType
, dwIID
;
209 dwIID
= sizeof(iid
) / sizeof(WCHAR
);
211 r
= RegEnumValueW(hkey
, j
++, iid
, &dwIID
, NULL
, &dwType
, (LPBYTE
)&Val
, &dwVal
);
212 if (r
== ERROR_SUCCESS
)
214 if (Val
== 0 && dwType
== REG_DWORD
)
216 LPITEMIDLIST pidl
= _ILCreateGuidFromStrW(iid
);
219 if (!HasItemWithCLSID(pidl
))
230 else if (ERROR_NO_MORE_ITEMS
== r
)
241 /* enumerate the elements in %windir%\desktop */
242 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
243 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
245 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_COMMON_DESKTOPDIRECTORY
, FALSE
);
246 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
248 return ret
? S_OK
: E_FAIL
;
251 CDesktopFolder::CDesktopFolder() :
257 CDesktopFolder::~CDesktopFolder()
261 HRESULT WINAPI
CDesktopFolder::FinalConstruct()
263 WCHAR szMyPath
[MAX_PATH
];
266 /* Create the root pidl */
267 pidlRoot
= _ILCreateDesktop();
269 return E_OUTOFMEMORY
;
271 /* Create the inner fs folder */
272 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
275 &CLSID_ShellFSFolder
,
276 CSIDL_DESKTOPDIRECTORY
,
277 IID_PPV_ARG(IShellFolder2
, &m_DesktopFSFolder
));
278 if (FAILED_UNEXPECTEDLY(hr
))
281 /* Create the inner shared fs folder. Dont fail on failure. */
282 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
285 &CLSID_ShellFSFolder
,
286 CSIDL_COMMON_DESKTOPDIRECTORY
,
287 IID_PPV_ARG(IShellFolder2
, &m_SharedDesktopFSFolder
));
288 if (FAILED_UNEXPECTEDLY(hr
))
291 /* Create the inner reg folder */
292 hr
= CRegFolder_CreateInstance(&CLSID_ShellDesktop
,
295 IID_PPV_ARG(IShellFolder2
, &m_regFolder
));
296 if (FAILED_UNEXPECTEDLY(hr
))
299 /* Cache the path to the user desktop directory */
300 if (!SHGetSpecialFolderPathW( 0, szMyPath
, CSIDL_DESKTOPDIRECTORY
, TRUE
))
303 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
305 return E_OUTOFMEMORY
;
307 wcscpy(sPathTarget
, szMyPath
);
311 HRESULT
CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl
, IShellFolder2
** psf
)
313 WCHAR szFileName
[MAX_PATH
];
315 if (_ILIsSpecialFolder(pidl
))
316 return m_regFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
318 lstrcpynW(szFileName
, sPathTarget
, MAX_PATH
- 1);
319 PathAddBackslashW(szFileName
);
320 int cLen
= wcslen(szFileName
);
322 if (!_ILSimpleGetTextW(pidl
, szFileName
+ cLen
, MAX_PATH
- cLen
))
325 if (GetFileAttributes(szFileName
) == INVALID_FILE_ATTRIBUTES
)
326 return m_SharedDesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
328 return m_DesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
331 /**************************************************************************
332 * CDesktopFolder::ParseDisplayName
335 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
338 HRESULT WINAPI
CDesktopFolder::ParseDisplayName(
341 LPOLESTR lpszDisplayName
,
343 PIDLIST_RELATIVE
*ppidl
,
344 DWORD
*pdwAttributes
)
346 LPCWSTR szNext
= NULL
;
347 LPITEMIDLIST pidlTemp
= NULL
;
351 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
352 this, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
353 pchEaten
, ppidl
, pdwAttributes
);
360 if (!lpszDisplayName
)
364 *pchEaten
= 0; /* strange but like the original */
366 urldata
.cbSize
= sizeof(urldata
);
368 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
370 return m_regFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
372 else if (PathGetDriveNumberW (lpszDisplayName
) >= 0)
374 /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
375 pidlTemp
= _ILCreateMyComputer ();
376 szNext
= lpszDisplayName
;
378 else if (PathIsUNCW(lpszDisplayName
))
380 pidlTemp
= _ILCreateNetwork();
381 szNext
= lpszDisplayName
;
383 else if( (pidlTemp
= SHELL32_CreatePidlFromBindCtx(pbc
, lpszDisplayName
)) )
388 else if (SUCCEEDED(ParseURLW(lpszDisplayName
, &urldata
)))
390 if (urldata
.nScheme
== URL_SCHEME_SHELL
) /* handle shell: urls */
392 TRACE ("-- shell url: %s\n", debugstr_w(urldata
.pszSuffix
));
393 pidlTemp
= _ILCreateGuidFromStrW(urldata
.pszSuffix
+ 2);
396 return IEParseDisplayNameWithBCW(CP_ACP
, lpszDisplayName
, pbc
, ppidl
);
400 if (*lpszDisplayName
)
402 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
403 hr
= m_DesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
407 return m_SharedDesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
410 pidlTemp
= _ILCreateMyComputer();
415 if (SUCCEEDED(hr
) && pidlTemp
)
417 if (szNext
&& *szNext
)
419 hr
= SHELL32_ParseNextElement(this, hwndOwner
, pbc
,
420 &pidlTemp
, (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
424 if (pdwAttributes
&& *pdwAttributes
)
426 GetAttributesOf(1, &pidlTemp
, pdwAttributes
);
436 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
441 /**************************************************************************
442 * CDesktopFolder::EnumObjects
444 HRESULT WINAPI
CDesktopFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
446 return ShellObjectCreatorInit
<CDesktopFolderEnum
>(this, hwndOwner
, dwFlags
, IID_PPV_ARG(IEnumIDList
, ppEnumIDList
));
449 /**************************************************************************
450 * CDesktopFolder::BindToObject
452 HRESULT WINAPI
CDesktopFolder::BindToObject(
453 PCUIDLIST_RELATIVE pidl
,
461 CComPtr
<IShellFolder2
> psf
;
462 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
463 if (FAILED_UNEXPECTEDLY(hr
))
466 return psf
->BindToObject(pidl
, pbcReserved
, riid
, ppvOut
);
469 /**************************************************************************
470 * CDesktopFolder::BindToStorage
472 HRESULT WINAPI
CDesktopFolder::BindToStorage(
473 PCUIDLIST_RELATIVE pidl
,
478 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
479 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
485 /**************************************************************************
486 * CDesktopFolder::CompareIDs
488 HRESULT WINAPI
CDesktopFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
490 bool bIsDesktopFolder1
, bIsDesktopFolder2
;
492 if (!pidl1
|| !pidl2
)
494 ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam
, pidl1
, pidl2
);
498 bIsDesktopFolder1
= _ILIsDesktop(pidl1
);
499 bIsDesktopFolder2
= _ILIsDesktop(pidl2
);
500 if (bIsDesktopFolder1
|| bIsDesktopFolder2
)
501 return MAKE_COMPARE_HRESULT(bIsDesktopFolder1
- bIsDesktopFolder2
);
503 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
504 return m_regFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
506 return m_DesktopFSFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
509 /**************************************************************************
510 * CDesktopFolder::CreateViewObject
512 HRESULT WINAPI
CDesktopFolder::CreateViewObject(
517 CComPtr
<IShellView
> pShellView
;
518 HRESULT hr
= E_INVALIDARG
;
520 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
521 this, hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
528 if (IsEqualIID (riid
, IID_IDropTarget
))
530 hr
= m_DesktopFSFolder
->CreateViewObject(hwndOwner
, riid
, ppvOut
);
532 else if (IsEqualIID (riid
, IID_IContextMenu
))
536 AddClassKeyToArray(L
"Directory\\Background", hKeys
, &cKeys
);
539 dcm
.hwnd
= hwndOwner
;
541 dcm
.pidlFolder
= pidlRoot
;
547 dcm
.punkAssociationInfo
= NULL
;
548 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, ppvOut
);
550 else if (IsEqualIID (riid
, IID_IShellView
))
552 hr
= IShellView_Constructor((IShellFolder
*)this, &pShellView
);
554 hr
= pShellView
->QueryInterface(riid
, ppvOut
);
556 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
560 /**************************************************************************
561 * CDesktopFolder::GetAttributesOf
563 HRESULT WINAPI
CDesktopFolder::GetAttributesOf(
565 PCUITEMID_CHILD_ARRAY apidl
,
570 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
571 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
580 *rgfInOut
&= dwDesktopAttributes
;
583 /* TODO: always add SFGAO_CANLINK */
584 for (UINT i
= 0; i
< cidl
; ++i
)
587 if (_ILIsDesktop(*apidl
))
588 *rgfInOut
&= dwDesktopAttributes
;
589 else if (_ILIsMyComputer(apidl
[i
]))
590 *rgfInOut
&= dwMyComputerAttributes
;
591 else if (_ILIsNetHood(apidl
[i
]))
592 *rgfInOut
&= dwMyNetPlacesAttributes
;
593 else if (_ILIsFolder(apidl
[i
]) || _ILIsValue(apidl
[i
]) || _ILIsSpecialFolder(apidl
[i
]))
595 CComPtr
<IShellFolder2
> psf
;
596 HRESULT hr
= _GetSFFromPidl(apidl
[i
], &psf
);
597 if (FAILED_UNEXPECTEDLY(hr
))
600 psf
->GetAttributesOf(1, &apidl
[i
], rgfInOut
);
603 ERR("Got an unknown pidl type!!!\n");
606 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
607 *rgfInOut
&= ~SFGAO_VALIDATE
;
609 TRACE("-- result=0x%08x\n", *rgfInOut
);
614 /**************************************************************************
615 * CDesktopFolder::GetUIObjectOf
618 * HWND hwndOwner, //[in ] Parent window for any output
619 * UINT cidl, //[in ] array size
620 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
621 * REFIID riid, //[in ] Requested Interface
622 * UINT* prgfInOut, //[ ] reserved
623 * LPVOID* ppvObject) //[out] Resulting Interface
626 HRESULT WINAPI
CDesktopFolder::GetUIObjectOf(
629 PCUITEMID_CHILD_ARRAY apidl
,
635 HRESULT hr
= E_INVALIDARG
;
637 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
638 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
645 if (cidl
== 1 && !_ILIsSpecialFolder(apidl
[0]))
647 CComPtr
<IShellFolder2
> psf
;
648 HRESULT hr
= _GetSFFromPidl(apidl
[0], &psf
);
649 if (FAILED_UNEXPECTEDLY(hr
))
652 return psf
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, ppvOut
);
655 if (IsEqualIID (riid
, IID_IContextMenu
))
657 if (_ILIsSpecialFolder(apidl
[0]))
659 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
663 /* Do not use the context menu of the CFSFolder here. */
664 /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
665 /* Otherwise operations like that involve items from both user and shared desktop will not work */
668 AddFSClassKeysToArray(apidl
[0], hKeys
, &cKeys
);
671 dcm
.hwnd
= hwndOwner
;
673 dcm
.pidlFolder
= pidlRoot
;
679 dcm
.punkAssociationInfo
= NULL
;
680 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, &pObj
);
683 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
685 hr
= IDataObject_Constructor( hwndOwner
, pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
687 else if ((IsEqualIID (riid
, IID_IExtractIconA
) || IsEqualIID (riid
, IID_IExtractIconW
)) && (cidl
== 1))
689 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
691 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
== 1))
693 CComPtr
<IShellFolder
> psfChild
;
694 hr
= this->BindToObject(apidl
[0], NULL
, IID_PPV_ARG(IShellFolder
, &psfChild
));
695 if (FAILED_UNEXPECTEDLY(hr
))
698 return psfChild
->CreateViewObject(NULL
, riid
, ppvOut
);
703 if (SUCCEEDED(hr
) && !pObj
)
707 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
711 /**************************************************************************
712 * CDesktopFolder::GetDisplayNameOf
715 * special case: pidl = null gives desktop-name back
717 HRESULT WINAPI
CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
719 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
725 if (!_ILIsPidlSimple (pidl
))
727 return SHELL32_GetDisplayNameOfChild(this, pidl
, dwFlags
, strRet
);
729 else if (_ILIsDesktop(pidl
))
731 if ((GET_SHGDN_RELATION(dwFlags
) == SHGDN_NORMAL
) && (GET_SHGDN_FOR(dwFlags
) & SHGDN_FORPARSING
))
732 return SHSetStrRet(strRet
, sPathTarget
);
734 return m_regFolder
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
737 /* file system folder or file rooted at the desktop */
738 CComPtr
<IShellFolder2
> psf
;
739 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
740 if (FAILED_UNEXPECTEDLY(hr
))
743 return psf
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
746 /**************************************************************************
747 * CDesktopFolder::SetNameOf
748 * Changes the name of a file object or subfolder, possibly changing its item
749 * identifier in the process.
752 * HWND hwndOwner, //[in ] Owner window for output
753 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
754 * LPCOLESTR lpszName, //[in ] the items new display name
755 * DWORD dwFlags, //[in ] SHGNO formatting flags
756 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
758 HRESULT WINAPI
CDesktopFolder::SetNameOf(
760 PCUITEMID_CHILD pidl
, /* simple pidl */
763 PITEMID_CHILD
*pPidlOut
)
765 CComPtr
<IShellFolder2
> psf
;
766 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
767 if (FAILED_UNEXPECTEDLY(hr
))
770 return psf
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
773 HRESULT WINAPI
CDesktopFolder::GetDefaultSearchGUID(GUID
*pguid
)
775 FIXME ("(%p)\n", this);
779 HRESULT WINAPI
CDesktopFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
781 FIXME ("(%p)\n", this);
785 HRESULT WINAPI
CDesktopFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
787 TRACE ("(%p)\n", this);
797 HRESULT WINAPI
CDesktopFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
799 TRACE ("(%p)\n", this);
801 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
804 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
809 HRESULT WINAPI
CDesktopFolder::GetDetailsEx(
810 PCUITEMID_CHILD pidl
,
811 const SHCOLUMNID
*pscid
,
814 FIXME ("(%p)\n", this);
819 HRESULT WINAPI
CDesktopFolder::GetDetailsOf(
820 PCUITEMID_CHILD pidl
,
824 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
829 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
830 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
831 return SHSetStrRet(&psd
->str
, DesktopSFHeader
[iColumn
].colnameid
);
834 CComPtr
<IShellFolder2
> psf
;
835 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
836 if (FAILED_UNEXPECTEDLY(hr
))
839 hr
= psf
->GetDetailsOf(pidl
, iColumn
, psd
);
840 if (FAILED_UNEXPECTEDLY(hr
))
846 HRESULT WINAPI
CDesktopFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
848 FIXME ("(%p)\n", this);
852 HRESULT WINAPI
CDesktopFolder::GetClassID(CLSID
*lpClassId
)
854 TRACE ("(%p)\n", this);
859 *lpClassId
= CLSID_ShellDesktop
;
864 HRESULT WINAPI
CDesktopFolder::Initialize(LPCITEMIDLIST pidl
)
866 TRACE ("(%p)->(%p)\n", this, pidl
);
871 HRESULT WINAPI
CDesktopFolder::GetCurFolder(LPITEMIDLIST
* pidl
)
873 TRACE ("(%p)->(%p)\n", this, pidl
);
876 return E_INVALIDARG
; /* xp doesn't have this check and crashes on NULL */
877 *pidl
= ILClone (pidlRoot
);
881 HRESULT WINAPI
CDesktopFolder::CallBack(IShellFolder
*psf
, HWND hwndOwner
, IDataObject
*pdtobj
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
883 if (uMsg
!= DFM_MERGECONTEXTMENU
&& uMsg
!= DFM_INVOKECOMMAND
)
886 /* no data object means no selection */
889 if (uMsg
== DFM_INVOKECOMMAND
&& wParam
== DFM_CMD_PROPERTIES
)
891 if (32 >= (UINT
)ShellExecuteW(hwndOwner
, L
"open", L
"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
))
895 else if (uMsg
== DFM_MERGECONTEXTMENU
)
897 QCMINFO
*pqcminfo
= (QCMINFO
*)lParam
;
898 _InsertMenuItemW(pqcminfo
->hmenu
, pqcminfo
->indexMenu
++, TRUE
, 0, MFT_SEPARATOR
, NULL
, 0);
899 _InsertMenuItemW(pqcminfo
->hmenu
, pqcminfo
->indexMenu
++, TRUE
, FCIDM_SHVIEW_PROPERTIES
, MFT_STRING
, MAKEINTRESOURCEW(IDS_PROPERTIES
), MFS_ENABLED
);
905 PIDLIST_ABSOLUTE pidlFolder
;
906 PUITEMID_CHILD
*apidl
;
908 HRESULT hr
= SH_GetApidlFromDataObject(pdtobj
, &pidlFolder
, &apidl
, &cidl
);
909 if (FAILED_UNEXPECTEDLY(hr
))
913 ERR("SHMultiFileProperties is not yet implemented\n");
916 hr
= GetDisplayNameOf(apidl
[0], SHGDN_FORPARSING
, &strFile
);
919 hr
= SH_ShowPropertiesDialog(strFile
.pOleStr
, pidlFolder
, apidl
);
921 ERR("SH_ShowPropertiesDialog failed\n");
925 ERR("Failed to get display name\n");
929 _ILFreeaPidl(apidl
, cidl
);
934 /*************************************************************************
935 * SHGetDesktopFolder [SHELL32.@]
937 HRESULT WINAPI
SHGetDesktopFolder(IShellFolder
**psf
)
942 if(!psf
) return E_INVALIDARG
;
944 hres
= CDesktopFolder::_CreatorClass::CreateInstance(NULL
, IID_PPV_ARG(IShellFolder
, psf
));
946 TRACE("-- %p->(%p)\n",psf
, *psf
);