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 static const WCHAR ClassicStartMenuW
[] = L
"SOFTWARE\\Microsoft\\Windows\\"
48 L
"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
51 IsNamespaceExtensionHidden(const WCHAR
*iid
)
53 DWORD Result
, dwResult
;
54 dwResult
= sizeof(DWORD
);
56 if (RegGetValueW(HKEY_CURRENT_USER
, /* FIXME use NewStartPanel when activated */
62 &dwResult
) != ERROR_SUCCESS
)
70 static INT
IsNamespaceExtensionHidden(LPCITEMIDLIST pidl
)
72 GUID
const *clsid
= _ILGetGUIDPointer (pidl
);
76 WCHAR pwszGuid
[CHARS_IN_GUID
];
77 SHELL32_GUIDToStringW(*clsid
, pwszGuid
);
78 return IsNamespaceExtensionHidden(pwszGuid
);
81 class CDesktopFolderEnum
:
82 public CEnumIDListBase
85 // CComPtr fDesktopEnumerator;
86 // CComPtr fCommonDesktopEnumerator;
89 void AddItemsFromClassicStartMenuKey(HKEY hKeyRoot
)
93 DWORD j
= 0, dwVal
, Val
, dwType
, dwIID
;
98 dwResult
= RegOpenKeyExW(hKeyRoot
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
99 if (dwResult
!= ERROR_SUCCESS
)
105 dwIID
= sizeof(iid
) / sizeof(WCHAR
);
107 r
= RegEnumValueW(hkey
, j
++, iid
, &dwIID
, NULL
, &dwType
, (LPBYTE
)&Val
, &dwVal
);
108 if (r
!= ERROR_SUCCESS
)
111 if (Val
== 0 && dwType
== REG_DWORD
)
113 pidl
= _ILCreateGuidFromStrW(iid
);
116 if (!HasItemWithCLSID(pidl
))
126 HRESULT WINAPI
Initialize(DWORD dwFlags
,IEnumIDList
* pRegEnumerator
, IEnumIDList
*pDesktopEnumerator
, IEnumIDList
*pCommonDesktopEnumerator
)
131 static const WCHAR MyDocumentsClassString
[] = L
"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
133 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
135 /* enumerate the root folders */
136 if (dwFlags
& SHCONTF_FOLDERS
)
138 AddToEnumList(_ILCreateMyComputer());
139 if (IsNamespaceExtensionHidden(MyDocumentsClassString
) < 1)
140 AddToEnumList(_ILCreateMyDocuments());
143 while((S_OK
== pRegEnumerator
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
145 if (IsNamespaceExtensionHidden(pidl
) < 1)
147 if (!HasItemWithCLSID(pidl
))
153 AddItemsFromClassicStartMenuKey(HKEY_LOCAL_MACHINE
);
154 AddItemsFromClassicStartMenuKey(HKEY_CURRENT_USER
);
157 /* Enumerate the items in the two fs folders */
158 AppendItemsFromEnumerator(pDesktopEnumerator
);
159 AppendItemsFromEnumerator(pCommonDesktopEnumerator
);
161 return ret
? S_OK
: E_FAIL
;
165 BEGIN_COM_MAP(CDesktopFolderEnum
)
166 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
170 int SHELL_ConfirmMsgBox(HWND hWnd
, LPWSTR lpszText
, LPWSTR lpszCaption
, HICON hIcon
, BOOL bYesToAll
);
172 static const shvheader DesktopSFHeader
[] = {
173 {IDS_SHV_COLUMN_NAME
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 15},
174 {IDS_SHV_COLUMN_COMMENTS
, SHCOLSTATE_TYPE_STR
, LVCFMT_LEFT
, 10},
175 {IDS_SHV_COLUMN_TYPE
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10},
176 {IDS_SHV_COLUMN_SIZE
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
177 {IDS_SHV_COLUMN_MODIFIED
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 12},
178 {IDS_SHV_COLUMN_ATTRIBUTES
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10}
181 #define DESKTOPSHELLVIEWCOLUMNS 6
183 static const DWORD dwDesktopAttributes
=
184 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
185 SFGAO_STORAGEANCESTOR
| SFGAO_HASPROPSHEET
| SFGAO_STORAGE
;
186 static const DWORD dwMyComputerAttributes
=
187 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
188 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
189 static DWORD dwMyNetPlacesAttributes
=
190 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
191 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
193 CDesktopFolder::CDesktopFolder() :
199 CDesktopFolder::~CDesktopFolder()
203 HRESULT WINAPI
CDesktopFolder::FinalConstruct()
205 WCHAR szMyPath
[MAX_PATH
];
208 /* Create the root pidl */
209 pidlRoot
= _ILCreateDesktop();
211 return E_OUTOFMEMORY
;
213 /* Create the inner fs folder */
214 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
215 &CLSID_ShellFSFolder
,
216 CSIDL_DESKTOPDIRECTORY
,
217 IID_PPV_ARG(IShellFolder2
, &m_DesktopFSFolder
));
218 if (FAILED_UNEXPECTEDLY(hr
))
221 /* Create the inner shared fs folder. Dont fail on failure. */
222 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
223 &CLSID_ShellFSFolder
,
224 CSIDL_COMMON_DESKTOPDIRECTORY
,
225 IID_PPV_ARG(IShellFolder2
, &m_SharedDesktopFSFolder
));
226 if (FAILED_UNEXPECTEDLY(hr
))
229 /* Create the inner reg folder */
230 hr
= CRegFolder_CreateInstance(&CLSID_ShellDesktop
,
234 IID_PPV_ARG(IShellFolder2
, &m_regFolder
));
235 if (FAILED_UNEXPECTEDLY(hr
))
238 /* Cache the path to the user desktop directory */
239 if (!SHGetSpecialFolderPathW( 0, szMyPath
, CSIDL_DESKTOPDIRECTORY
, TRUE
))
242 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
244 return E_OUTOFMEMORY
;
246 wcscpy(sPathTarget
, szMyPath
);
250 HRESULT
CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl
, IShellFolder2
** psf
)
252 WCHAR szFileName
[MAX_PATH
];
254 if (_ILIsSpecialFolder(pidl
))
255 return m_regFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
257 lstrcpynW(szFileName
, sPathTarget
, MAX_PATH
- 1);
258 PathAddBackslashW(szFileName
);
259 int cLen
= wcslen(szFileName
);
261 if (!_ILSimpleGetTextW(pidl
, szFileName
+ cLen
, MAX_PATH
- cLen
))
264 if (GetFileAttributes(szFileName
) == INVALID_FILE_ATTRIBUTES
)
265 return m_SharedDesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
267 return m_DesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
270 /**************************************************************************
271 * CDesktopFolder::ParseDisplayName
274 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
277 HRESULT WINAPI
CDesktopFolder::ParseDisplayName(
280 LPOLESTR lpszDisplayName
,
282 PIDLIST_RELATIVE
*ppidl
,
283 DWORD
*pdwAttributes
)
285 LPCWSTR szNext
= NULL
;
286 LPITEMIDLIST pidlTemp
= NULL
;
290 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
291 this, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
292 pchEaten
, ppidl
, pdwAttributes
);
299 if (!lpszDisplayName
)
303 *pchEaten
= 0; /* strange but like the original */
305 urldata
.cbSize
= sizeof(urldata
);
307 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
309 return m_regFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
311 else if (PathGetDriveNumberW (lpszDisplayName
) >= 0)
313 /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
314 pidlTemp
= _ILCreateMyComputer ();
315 szNext
= lpszDisplayName
;
317 else if (PathIsUNCW(lpszDisplayName
))
319 pidlTemp
= _ILCreateNetwork();
320 szNext
= lpszDisplayName
;
322 else if( (pidlTemp
= SHELL32_CreatePidlFromBindCtx(pbc
, lpszDisplayName
)) )
327 else if (SUCCEEDED(ParseURLW(lpszDisplayName
, &urldata
)))
329 if (urldata
.nScheme
== URL_SCHEME_SHELL
) /* handle shell: urls */
331 TRACE ("-- shell url: %s\n", debugstr_w(urldata
.pszSuffix
));
332 pidlTemp
= _ILCreateGuidFromStrW(urldata
.pszSuffix
+ 2);
335 return IEParseDisplayNameWithBCW(CP_ACP
, lpszDisplayName
, pbc
, ppidl
);
339 if (*lpszDisplayName
)
341 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
342 hr
= m_DesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
346 return m_SharedDesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
349 pidlTemp
= _ILCreateMyComputer();
354 if (SUCCEEDED(hr
) && pidlTemp
)
356 if (szNext
&& *szNext
)
358 hr
= SHELL32_ParseNextElement(this, hwndOwner
, pbc
,
359 &pidlTemp
, (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
363 if (pdwAttributes
&& *pdwAttributes
)
365 GetAttributesOf(1, &pidlTemp
, pdwAttributes
);
375 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
380 /**************************************************************************
381 * CDesktopFolder::EnumObjects
383 HRESULT WINAPI
CDesktopFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
385 CComPtr
<IEnumIDList
> pRegEnumerator
;
386 CComPtr
<IEnumIDList
> pDesktopEnumerator
;
387 CComPtr
<IEnumIDList
> pCommonDesktopEnumerator
;
390 hr
= m_regFolder
->EnumObjects(hwndOwner
, dwFlags
, &pRegEnumerator
);
392 ERR("EnumObjects for reg folder failed\n");
394 hr
= m_DesktopFSFolder
->EnumObjects(hwndOwner
, dwFlags
, &pDesktopEnumerator
);
396 ERR("EnumObjects for desktop fs folder failed\n");
398 hr
= m_SharedDesktopFSFolder
->EnumObjects(hwndOwner
, dwFlags
, &pCommonDesktopEnumerator
);
400 ERR("EnumObjects for shared desktop fs folder failed\n");
402 return ShellObjectCreatorInit
<CDesktopFolderEnum
>(dwFlags
,pRegEnumerator
, pDesktopEnumerator
, pCommonDesktopEnumerator
, IID_PPV_ARG(IEnumIDList
, ppEnumIDList
));
405 /**************************************************************************
406 * CDesktopFolder::BindToObject
408 HRESULT WINAPI
CDesktopFolder::BindToObject(
409 PCUIDLIST_RELATIVE pidl
,
417 CComPtr
<IShellFolder2
> psf
;
418 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
419 if (FAILED_UNEXPECTEDLY(hr
))
422 return psf
->BindToObject(pidl
, pbcReserved
, riid
, ppvOut
);
425 /**************************************************************************
426 * CDesktopFolder::BindToStorage
428 HRESULT WINAPI
CDesktopFolder::BindToStorage(
429 PCUIDLIST_RELATIVE pidl
,
434 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
435 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
441 /**************************************************************************
442 * CDesktopFolder::CompareIDs
444 HRESULT WINAPI
CDesktopFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
446 bool bIsDesktopFolder1
, bIsDesktopFolder2
;
448 if (!pidl1
|| !pidl2
)
450 ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam
, pidl1
, pidl2
);
454 bIsDesktopFolder1
= _ILIsDesktop(pidl1
);
455 bIsDesktopFolder2
= _ILIsDesktop(pidl2
);
456 if (bIsDesktopFolder1
|| bIsDesktopFolder2
)
457 return MAKE_COMPARE_HRESULT(bIsDesktopFolder1
- bIsDesktopFolder2
);
459 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
460 return m_regFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
462 return m_DesktopFSFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
465 /**************************************************************************
466 * CDesktopFolder::CreateViewObject
468 HRESULT WINAPI
CDesktopFolder::CreateViewObject(
473 HRESULT hr
= E_INVALIDARG
;
475 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
476 this, hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
483 if (IsEqualIID (riid
, IID_IDropTarget
))
485 hr
= m_DesktopFSFolder
->CreateViewObject(hwndOwner
, riid
, ppvOut
);
487 else if (IsEqualIID (riid
, IID_IContextMenu
))
491 AddClassKeyToArray(L
"Directory\\Background", hKeys
, &cKeys
);
494 dcm
.hwnd
= hwndOwner
;
496 dcm
.pidlFolder
= pidlRoot
;
502 dcm
.punkAssociationInfo
= NULL
;
503 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, ppvOut
);
505 else if (IsEqualIID (riid
, IID_IShellView
))
507 SFV_CREATE sfvparams
= {sizeof(SFV_CREATE
), this};
508 hr
= SHCreateShellFolderView(&sfvparams
, (IShellView
**)ppvOut
);
510 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
514 /**************************************************************************
515 * CDesktopFolder::GetAttributesOf
517 HRESULT WINAPI
CDesktopFolder::GetAttributesOf(
519 PCUITEMID_CHILD_ARRAY apidl
,
524 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
525 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
534 *rgfInOut
&= dwDesktopAttributes
;
537 /* TODO: always add SFGAO_CANLINK */
538 for (UINT i
= 0; i
< cidl
; ++i
)
541 if (_ILIsDesktop(*apidl
))
542 *rgfInOut
&= dwDesktopAttributes
;
543 else if (_ILIsMyComputer(apidl
[i
]))
544 *rgfInOut
&= dwMyComputerAttributes
;
545 else if (_ILIsNetHood(apidl
[i
]))
546 *rgfInOut
&= dwMyNetPlacesAttributes
;
547 else if (_ILIsFolder(apidl
[i
]) || _ILIsValue(apidl
[i
]) || _ILIsSpecialFolder(apidl
[i
]))
549 CComPtr
<IShellFolder2
> psf
;
550 HRESULT hr
= _GetSFFromPidl(apidl
[i
], &psf
);
551 if (FAILED_UNEXPECTEDLY(hr
))
554 psf
->GetAttributesOf(1, &apidl
[i
], rgfInOut
);
557 ERR("Got an unknown pidl type!!!\n");
560 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
561 *rgfInOut
&= ~SFGAO_VALIDATE
;
563 TRACE("-- result=0x%08x\n", *rgfInOut
);
568 /**************************************************************************
569 * CDesktopFolder::GetUIObjectOf
572 * HWND hwndOwner, //[in ] Parent window for any output
573 * UINT cidl, //[in ] array size
574 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
575 * REFIID riid, //[in ] Requested Interface
576 * UINT* prgfInOut, //[ ] reserved
577 * LPVOID* ppvObject) //[out] Resulting Interface
580 HRESULT WINAPI
CDesktopFolder::GetUIObjectOf(
583 PCUITEMID_CHILD_ARRAY apidl
,
589 HRESULT hr
= E_INVALIDARG
;
591 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
592 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
599 if (cidl
== 1 && !_ILIsSpecialFolder(apidl
[0]))
601 CComPtr
<IShellFolder2
> psf
;
602 HRESULT hr
= _GetSFFromPidl(apidl
[0], &psf
);
603 if (FAILED_UNEXPECTEDLY(hr
))
606 return psf
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, ppvOut
);
609 if (IsEqualIID (riid
, IID_IContextMenu
))
611 if (_ILIsSpecialFolder(apidl
[0]))
613 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
617 /* Do not use the context menu of the CFSFolder here. */
618 /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
619 /* Otherwise operations like that involve items from both user and shared desktop will not work */
622 AddFSClassKeysToArray(apidl
[0], hKeys
, &cKeys
);
625 dcm
.hwnd
= hwndOwner
;
627 dcm
.pidlFolder
= pidlRoot
;
633 dcm
.punkAssociationInfo
= NULL
;
634 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, &pObj
);
637 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
639 hr
= IDataObject_Constructor( hwndOwner
, pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
641 else if ((IsEqualIID (riid
, IID_IExtractIconA
) || IsEqualIID (riid
, IID_IExtractIconW
)) && (cidl
== 1))
643 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
645 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
== 1))
647 CComPtr
<IShellFolder
> psfChild
;
648 hr
= this->BindToObject(apidl
[0], NULL
, IID_PPV_ARG(IShellFolder
, &psfChild
));
649 if (FAILED_UNEXPECTEDLY(hr
))
652 return psfChild
->CreateViewObject(NULL
, riid
, ppvOut
);
657 if (SUCCEEDED(hr
) && !pObj
)
661 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
665 /**************************************************************************
666 * CDesktopFolder::GetDisplayNameOf
669 * special case: pidl = null gives desktop-name back
671 HRESULT WINAPI
CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
673 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
679 if (!_ILIsPidlSimple (pidl
))
681 return SHELL32_GetDisplayNameOfChild(this, pidl
, dwFlags
, strRet
);
683 else if (_ILIsDesktop(pidl
))
685 if ((GET_SHGDN_RELATION(dwFlags
) == SHGDN_NORMAL
) && (GET_SHGDN_FOR(dwFlags
) & SHGDN_FORPARSING
))
686 return SHSetStrRet(strRet
, sPathTarget
);
688 return m_regFolder
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
691 /* file system folder or file rooted at the desktop */
692 CComPtr
<IShellFolder2
> psf
;
693 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
694 if (FAILED_UNEXPECTEDLY(hr
))
697 return psf
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
700 /**************************************************************************
701 * CDesktopFolder::SetNameOf
702 * Changes the name of a file object or subfolder, possibly changing its item
703 * identifier in the process.
706 * HWND hwndOwner, //[in ] Owner window for output
707 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
708 * LPCOLESTR lpszName, //[in ] the items new display name
709 * DWORD dwFlags, //[in ] SHGNO formatting flags
710 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
712 HRESULT WINAPI
CDesktopFolder::SetNameOf(
714 PCUITEMID_CHILD pidl
, /* simple pidl */
717 PITEMID_CHILD
*pPidlOut
)
719 CComPtr
<IShellFolder2
> psf
;
720 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
721 if (FAILED_UNEXPECTEDLY(hr
))
724 return psf
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
727 HRESULT WINAPI
CDesktopFolder::GetDefaultSearchGUID(GUID
*pguid
)
729 FIXME ("(%p)\n", this);
733 HRESULT WINAPI
CDesktopFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
735 FIXME ("(%p)\n", this);
739 HRESULT WINAPI
CDesktopFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
741 TRACE ("(%p)\n", this);
751 HRESULT WINAPI
CDesktopFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
753 TRACE ("(%p)\n", this);
755 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
758 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
763 HRESULT WINAPI
CDesktopFolder::GetDetailsEx(
764 PCUITEMID_CHILD pidl
,
765 const SHCOLUMNID
*pscid
,
768 FIXME ("(%p)\n", this);
773 HRESULT WINAPI
CDesktopFolder::GetDetailsOf(
774 PCUITEMID_CHILD pidl
,
778 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
783 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
784 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
785 return SHSetStrRet(&psd
->str
, DesktopSFHeader
[iColumn
].colnameid
);
788 CComPtr
<IShellFolder2
> psf
;
789 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
790 if (FAILED_UNEXPECTEDLY(hr
))
793 hr
= psf
->GetDetailsOf(pidl
, iColumn
, psd
);
794 if (FAILED_UNEXPECTEDLY(hr
))
800 HRESULT WINAPI
CDesktopFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
802 FIXME ("(%p)\n", this);
806 HRESULT WINAPI
CDesktopFolder::GetClassID(CLSID
*lpClassId
)
808 TRACE ("(%p)\n", this);
813 *lpClassId
= CLSID_ShellDesktop
;
818 HRESULT WINAPI
CDesktopFolder::Initialize(LPCITEMIDLIST pidl
)
820 TRACE ("(%p)->(%p)\n", this, pidl
);
828 HRESULT WINAPI
CDesktopFolder::GetCurFolder(LPITEMIDLIST
* pidl
)
830 TRACE ("(%p)->(%p)\n", this, pidl
);
833 return E_INVALIDARG
; /* xp doesn't have this check and crashes on NULL */
834 *pidl
= ILClone (pidlRoot
);
838 HRESULT WINAPI
CDesktopFolder::CallBack(IShellFolder
*psf
, HWND hwndOwner
, IDataObject
*pdtobj
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
840 if (uMsg
!= DFM_MERGECONTEXTMENU
&& uMsg
!= DFM_INVOKECOMMAND
)
843 /* no data object means no selection */
846 if (uMsg
== DFM_INVOKECOMMAND
&& wParam
== 0)
848 if (32 >= (UINT
)ShellExecuteW(hwndOwner
, L
"open", L
"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
))
852 else if (uMsg
== DFM_MERGECONTEXTMENU
)
854 QCMINFO
*pqcminfo
= (QCMINFO
*)lParam
;
855 HMENU hpopup
= CreatePopupMenu();
856 _InsertMenuItemW(hpopup
, 0, TRUE
, 0, MFT_STRING
, MAKEINTRESOURCEW(IDS_PROPERTIES
), MFS_ENABLED
);
857 Shell_MergeMenus(pqcminfo
->hmenu
, hpopup
, pqcminfo
->indexMenu
++, pqcminfo
->idCmdFirst
, pqcminfo
->idCmdLast
, MM_ADDSEPARATOR
);
864 if (uMsg
!= DFM_INVOKECOMMAND
|| wParam
!= DFM_CMD_PROPERTIES
)
867 return Shell_DefaultContextMenuCallBack(this, pdtobj
);
870 /*************************************************************************
871 * SHGetDesktopFolder [SHELL32.@]
873 HRESULT WINAPI
SHGetDesktopFolder(IShellFolder
**psf
)
878 if(!psf
) return E_INVALIDARG
;
880 hres
= CDesktopFolder::_CreatorClass::CreateInstance(NULL
, IID_PPV_ARG(IShellFolder
, psf
));
882 TRACE("-- %p->(%p)\n",psf
, *psf
);