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_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 15},
67 {IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
68 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10},
69 {IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 12},
72 #define DESKTOPSHELLVIEWCOLUMNS 4
74 static const DWORD dwDesktopAttributes
=
75 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
76 SFGAO_STORAGEANCESTOR
| SFGAO_HASPROPSHEET
| SFGAO_STORAGE
| SFGAO_CANLINK
;
77 static const DWORD dwMyComputerAttributes
=
78 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
79 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
80 static DWORD dwMyNetPlacesAttributes
=
81 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
82 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
85 CDesktopFolderEnum::CDesktopFolderEnum()
89 CDesktopFolderEnum::~CDesktopFolderEnum()
93 static const WCHAR ClassicStartMenuW
[] = L
"SOFTWARE\\Microsoft\\Windows\\"
94 L
"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
97 IsNamespaceExtensionHidden(const WCHAR
*iid
)
99 DWORD Result
, dwResult
;
100 dwResult
= sizeof(DWORD
);
102 if (RegGetValueW(HKEY_CURRENT_USER
, /* FIXME use NewStartPanel when activated */
108 &dwResult
) != ERROR_SUCCESS
)
116 /**************************************************************************
117 * CreateDesktopEnumList()
120 HRESULT WINAPI
CDesktopFolderEnum::Initialize(CDesktopFolder
*desktopFolder
, HWND hwndOwner
, DWORD dwFlags
)
123 WCHAR szPath
[MAX_PATH
];
125 static const WCHAR MyDocumentsClassString
[] = L
"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
126 static const WCHAR Desktop_NameSpaceW
[] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
128 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
130 /* enumerate the root folders */
131 if (dwFlags
& SHCONTF_FOLDERS
)
137 /* create the pidl for This item */
138 if (IsNamespaceExtensionHidden(MyDocumentsClassString
) < 1)
140 ret
= AddToEnumList(_ILCreateMyDocuments());
142 ret
= AddToEnumList(_ILCreateMyComputer());
144 for (i
= 0; i
< 2; i
++)
147 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
149 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
151 if (dwResult
== ERROR_SUCCESS
)
162 size
= sizeof (iid
) / sizeof (iid
[0]);
163 r
= RegEnumKeyExW(hkey
, i
, iid
, &size
, 0, NULL
, NULL
, NULL
);
164 if (ERROR_SUCCESS
== r
)
166 if (IsNamespaceExtensionHidden(iid
) < 1)
168 pidl
= _ILCreateGuidFromStrW(iid
);
171 if (!HasItemWithCLSID(pidl
))
173 ret
= AddToEnumList(pidl
);
182 else if (ERROR_NO_MORE_ITEMS
== r
)
191 for (i
= 0; i
< 2; i
++)
194 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
196 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
198 if (dwResult
== ERROR_SUCCESS
)
200 DWORD j
= 0, dwVal
, Val
, dwType
, dwIID
;
207 dwIID
= sizeof(iid
) / sizeof(WCHAR
);
209 r
= RegEnumValueW(hkey
, j
++, iid
, &dwIID
, NULL
, &dwType
, (LPBYTE
)&Val
, &dwVal
);
210 if (r
== ERROR_SUCCESS
)
212 if (Val
== 0 && dwType
== REG_DWORD
)
214 LPITEMIDLIST pidl
= _ILCreateGuidFromStrW(iid
);
217 if (!HasItemWithCLSID(pidl
))
228 else if (ERROR_NO_MORE_ITEMS
== r
)
239 /* enumerate the elements in %windir%\desktop */
240 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
241 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
243 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_COMMON_DESKTOPDIRECTORY
, FALSE
);
244 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
246 return ret
? S_OK
: E_FAIL
;
249 CDesktopFolder::CDesktopFolder() :
255 CDesktopFolder::~CDesktopFolder()
259 HRESULT WINAPI
CDesktopFolder::FinalConstruct()
261 WCHAR szMyPath
[MAX_PATH
];
264 /* Create the root pidl */
265 pidlRoot
= _ILCreateDesktop();
267 return E_OUTOFMEMORY
;
269 /* Create the inner fs folder */
270 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
273 &CLSID_ShellFSFolder
,
274 CSIDL_DESKTOPDIRECTORY
,
275 IID_PPV_ARG(IShellFolder2
, &m_DesktopFSFolder
));
276 if (FAILED_UNEXPECTEDLY(hr
))
279 /* Create the inner shared fs folder. Dont fail on failure. */
280 hr
= SHELL32_CoCreateInitSF(pidlRoot
,
283 &CLSID_ShellFSFolder
,
284 CSIDL_COMMON_DESKTOPDIRECTORY
,
285 IID_PPV_ARG(IShellFolder2
, &m_SharedDesktopFSFolder
));
286 if (FAILED_UNEXPECTEDLY(hr
))
289 /* Create the inner reg folder */
290 hr
= CRegFolder_CreateInstance(&CLSID_ShellDesktop
,
293 IID_PPV_ARG(IShellFolder2
, &m_regFolder
));
294 if (FAILED_UNEXPECTEDLY(hr
))
297 /* Cache the path to the user desktop directory */
298 if (!SHGetSpecialFolderPathW( 0, szMyPath
, CSIDL_DESKTOPDIRECTORY
, TRUE
))
301 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
303 return E_OUTOFMEMORY
;
305 wcscpy(sPathTarget
, szMyPath
);
309 HRESULT
CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl
, IShellFolder2
** psf
)
311 WCHAR szFileName
[MAX_PATH
];
313 if (_ILIsSpecialFolder(pidl
))
314 return m_regFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
316 lstrcpynW(szFileName
, sPathTarget
, MAX_PATH
- 1);
317 PathAddBackslashW(szFileName
);
318 int cLen
= wcslen(szFileName
);
320 if (!_ILSimpleGetTextW(pidl
, szFileName
+ cLen
, MAX_PATH
- cLen
))
323 if (GetFileAttributes(szFileName
) == INVALID_FILE_ATTRIBUTES
)
324 return m_SharedDesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
326 return m_DesktopFSFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, psf
));
329 /**************************************************************************
330 * CDesktopFolder::ParseDisplayName
333 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
336 HRESULT WINAPI
CDesktopFolder::ParseDisplayName(
339 LPOLESTR lpszDisplayName
,
341 PIDLIST_RELATIVE
*ppidl
,
342 DWORD
*pdwAttributes
)
344 LPCWSTR szNext
= NULL
;
345 LPITEMIDLIST pidlTemp
= NULL
;
349 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
350 this, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
351 pchEaten
, ppidl
, pdwAttributes
);
358 if (!lpszDisplayName
)
362 *pchEaten
= 0; /* strange but like the original */
364 urldata
.cbSize
= sizeof(urldata
);
366 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
368 return m_regFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
370 else if (PathGetDriveNumberW (lpszDisplayName
) >= 0)
372 /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
373 pidlTemp
= _ILCreateMyComputer ();
374 szNext
= lpszDisplayName
;
376 else if (PathIsUNCW(lpszDisplayName
))
378 pidlTemp
= _ILCreateNetwork();
379 szNext
= lpszDisplayName
;
381 else if( (pidlTemp
= SHELL32_CreatePidlFromBindCtx(pbc
, lpszDisplayName
)) )
386 else if (SUCCEEDED(ParseURLW(lpszDisplayName
, &urldata
)))
388 if (urldata
.nScheme
== URL_SCHEME_SHELL
) /* handle shell: urls */
390 TRACE ("-- shell url: %s\n", debugstr_w(urldata
.pszSuffix
));
391 pidlTemp
= _ILCreateGuidFromStrW(urldata
.pszSuffix
+ 2);
394 return IEParseDisplayNameWithBCW(CP_ACP
, lpszDisplayName
, pbc
, ppidl
);
398 if (*lpszDisplayName
)
400 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
401 hr
= m_DesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
405 return m_SharedDesktopFSFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
408 pidlTemp
= _ILCreateMyComputer();
413 if (SUCCEEDED(hr
) && pidlTemp
)
415 if (szNext
&& *szNext
)
417 hr
= SHELL32_ParseNextElement(this, hwndOwner
, pbc
,
418 &pidlTemp
, (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
422 if (pdwAttributes
&& *pdwAttributes
)
424 GetAttributesOf(1, &pidlTemp
, pdwAttributes
);
434 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
439 /**************************************************************************
440 * CDesktopFolder::EnumObjects
442 HRESULT WINAPI
CDesktopFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
444 return ShellObjectCreatorInit
<CDesktopFolderEnum
>(this, hwndOwner
, dwFlags
, IID_IEnumIDList
, ppEnumIDList
);
447 /**************************************************************************
448 * CDesktopFolder::BindToObject
450 HRESULT WINAPI
CDesktopFolder::BindToObject(
451 PCUIDLIST_RELATIVE pidl
,
459 CComPtr
<IShellFolder2
> psf
;
460 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
461 if (FAILED_UNEXPECTEDLY(hr
))
464 return psf
->BindToObject(pidl
, pbcReserved
, riid
, ppvOut
);
467 /**************************************************************************
468 * CDesktopFolder::BindToStorage
470 HRESULT WINAPI
CDesktopFolder::BindToStorage(
471 PCUIDLIST_RELATIVE pidl
,
476 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
477 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
483 /**************************************************************************
484 * CDesktopFolder::CompareIDs
486 HRESULT WINAPI
CDesktopFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
488 bool bIsDesktopFolder1
, bIsDesktopFolder2
;
490 if (!pidl1
|| !pidl2
)
492 ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam
, pidl1
, pidl2
);
496 bIsDesktopFolder1
= _ILIsDesktop(pidl1
);
497 bIsDesktopFolder2
= _ILIsDesktop(pidl2
);
498 if (bIsDesktopFolder1
|| bIsDesktopFolder2
)
499 return MAKE_COMPARE_HRESULT(bIsDesktopFolder1
- bIsDesktopFolder2
);
501 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
502 return m_regFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
504 return m_DesktopFSFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
507 /**************************************************************************
508 * CDesktopFolder::CreateViewObject
510 HRESULT WINAPI
CDesktopFolder::CreateViewObject(
515 CComPtr
<IShellView
> pShellView
;
516 HRESULT hr
= E_INVALIDARG
;
518 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
519 this, hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
526 if (IsEqualIID (riid
, IID_IDropTarget
))
528 hr
= m_DesktopFSFolder
->CreateViewObject(hwndOwner
, riid
, ppvOut
);
530 else if (IsEqualIID (riid
, IID_IContextMenu
))
534 AddClassKeyToArray(L
"Directory\\Background", hKeys
, &cKeys
);
537 dcm
.hwnd
= hwndOwner
;
539 dcm
.pidlFolder
= pidlRoot
;
545 dcm
.punkAssociationInfo
= NULL
;
546 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, ppvOut
);
548 else if (IsEqualIID (riid
, IID_IShellView
))
550 hr
= IShellView_Constructor((IShellFolder
*)this, &pShellView
);
552 hr
= pShellView
->QueryInterface(riid
, ppvOut
);
554 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
558 /**************************************************************************
559 * CDesktopFolder::GetAttributesOf
561 HRESULT WINAPI
CDesktopFolder::GetAttributesOf(
563 PCUITEMID_CHILD_ARRAY apidl
,
568 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
569 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
578 *rgfInOut
&= dwDesktopAttributes
;
581 /* TODO: always add SFGAO_CANLINK */
582 for (UINT i
= 0; i
< cidl
; ++i
)
585 if (_ILIsDesktop(*apidl
))
586 *rgfInOut
&= dwDesktopAttributes
;
587 else if (_ILIsMyComputer(apidl
[i
]))
588 *rgfInOut
&= dwMyComputerAttributes
;
589 else if (_ILIsNetHood(apidl
[i
]))
590 *rgfInOut
&= dwMyNetPlacesAttributes
;
591 else if (_ILIsFolder(apidl
[i
]) || _ILIsValue(apidl
[i
]) || _ILIsSpecialFolder(apidl
[i
]))
593 CComPtr
<IShellFolder2
> psf
;
594 HRESULT hr
= _GetSFFromPidl(apidl
[i
], &psf
);
595 if (FAILED_UNEXPECTEDLY(hr
))
598 psf
->GetAttributesOf(1, &apidl
[i
], rgfInOut
);
601 ERR("Got an unknown pidl type!!!\n");
604 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
605 *rgfInOut
&= ~SFGAO_VALIDATE
;
607 TRACE("-- result=0x%08x\n", *rgfInOut
);
612 /**************************************************************************
613 * CDesktopFolder::GetUIObjectOf
616 * HWND hwndOwner, //[in ] Parent window for any output
617 * UINT cidl, //[in ] array size
618 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
619 * REFIID riid, //[in ] Requested Interface
620 * UINT* prgfInOut, //[ ] reserved
621 * LPVOID* ppvObject) //[out] Resulting Interface
624 HRESULT WINAPI
CDesktopFolder::GetUIObjectOf(
627 PCUITEMID_CHILD_ARRAY apidl
,
633 HRESULT hr
= E_INVALIDARG
;
635 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
636 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
643 if (cidl
== 1 && !_ILIsSpecialFolder(apidl
[0]))
645 CComPtr
<IShellFolder2
> psf
;
646 HRESULT hr
= _GetSFFromPidl(apidl
[0], &psf
);
647 if (FAILED_UNEXPECTEDLY(hr
))
650 return psf
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, ppvOut
);
653 if (IsEqualIID (riid
, IID_IContextMenu
))
655 if (_ILIsSpecialFolder(apidl
[0]))
657 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
661 /* Do not use the context menu of the CFSFolder here. */
662 /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
663 /* Otherwise operations like that involve items from both user and shared desktop will not work */
666 AddFSClassKeysToArray(apidl
[0], hKeys
, &cKeys
);
669 dcm
.hwnd
= hwndOwner
;
671 dcm
.pidlFolder
= pidlRoot
;
677 dcm
.punkAssociationInfo
= NULL
;
678 hr
= SHCreateDefaultContextMenu (&dcm
, riid
, &pObj
);
681 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
683 hr
= IDataObject_Constructor( hwndOwner
, pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
685 else if ((IsEqualIID (riid
, IID_IExtractIconA
) || IsEqualIID (riid
, IID_IExtractIconW
)) && (cidl
== 1))
687 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
692 if (SUCCEEDED(hr
) && !pObj
)
696 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
700 /**************************************************************************
701 * CDesktopFolder::GetDisplayNameOf
704 * special case: pidl = null gives desktop-name back
706 HRESULT WINAPI
CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
708 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
714 if (!_ILIsPidlSimple (pidl
))
716 return SHELL32_GetDisplayNameOfChild(this, pidl
, dwFlags
, strRet
);
718 else if (_ILIsDesktop(pidl
))
720 if ((GET_SHGDN_RELATION(dwFlags
) == SHGDN_NORMAL
) && (GET_SHGDN_FOR(dwFlags
) & SHGDN_FORPARSING
))
721 return SHSetStrRet(strRet
, sPathTarget
);
723 return m_regFolder
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
726 /* file system folder or file rooted at the desktop */
727 CComPtr
<IShellFolder2
> psf
;
728 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
729 if (FAILED_UNEXPECTEDLY(hr
))
732 return psf
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
735 /**************************************************************************
736 * CDesktopFolder::SetNameOf
737 * Changes the name of a file object or subfolder, possibly changing its item
738 * identifier in the process.
741 * HWND hwndOwner, //[in ] Owner window for output
742 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
743 * LPCOLESTR lpszName, //[in ] the items new display name
744 * DWORD dwFlags, //[in ] SHGNO formatting flags
745 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
747 HRESULT WINAPI
CDesktopFolder::SetNameOf(
749 PCUITEMID_CHILD pidl
, /* simple pidl */
752 PITEMID_CHILD
*pPidlOut
)
754 CComPtr
<IShellFolder2
> psf
;
755 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
756 if (FAILED_UNEXPECTEDLY(hr
))
759 return psf
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
762 HRESULT WINAPI
CDesktopFolder::GetDefaultSearchGUID(GUID
*pguid
)
764 FIXME ("(%p)\n", this);
768 HRESULT WINAPI
CDesktopFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
770 FIXME ("(%p)\n", this);
774 HRESULT WINAPI
CDesktopFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
776 TRACE ("(%p)\n", this);
786 HRESULT WINAPI
CDesktopFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
788 TRACE ("(%p)\n", this);
790 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
793 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
798 HRESULT WINAPI
CDesktopFolder::GetDetailsEx(
799 PCUITEMID_CHILD pidl
,
800 const SHCOLUMNID
*pscid
,
803 FIXME ("(%p)\n", this);
808 HRESULT WINAPI
CDesktopFolder::GetDetailsOf(
809 PCUITEMID_CHILD pidl
,
813 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
818 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
819 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
820 return SHSetStrRet(&psd
->str
, DesktopSFHeader
[iColumn
].colnameid
);
823 CComPtr
<IShellFolder2
> psf
;
824 HRESULT hr
= _GetSFFromPidl(pidl
, &psf
);
825 if (FAILED_UNEXPECTEDLY(hr
))
828 hr
= psf
->GetDetailsOf(pidl
, iColumn
, psd
);
829 if (FAILED_UNEXPECTEDLY(hr
))
835 HRESULT WINAPI
CDesktopFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
837 FIXME ("(%p)\n", this);
841 HRESULT WINAPI
CDesktopFolder::GetClassID(CLSID
*lpClassId
)
843 TRACE ("(%p)\n", this);
848 *lpClassId
= CLSID_ShellDesktop
;
853 HRESULT WINAPI
CDesktopFolder::Initialize(LPCITEMIDLIST pidl
)
855 TRACE ("(%p)->(%p)\n", this, pidl
);
860 HRESULT WINAPI
CDesktopFolder::GetCurFolder(LPITEMIDLIST
* pidl
)
862 TRACE ("(%p)->(%p)\n", this, pidl
);
865 return E_INVALIDARG
; /* xp doesn't have this check and crashes on NULL */
866 *pidl
= ILClone (pidlRoot
);
870 HRESULT WINAPI
CDesktopFolder::CallBack(IShellFolder
*psf
, HWND hwndOwner
, IDataObject
*pdtobj
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
872 if (uMsg
!= DFM_MERGECONTEXTMENU
&& uMsg
!= DFM_INVOKECOMMAND
)
875 /* no data object means no selection */
878 if (uMsg
== DFM_INVOKECOMMAND
&& wParam
== DFM_CMD_PROPERTIES
)
880 if (32 >= (UINT
)ShellExecuteW(hwndOwner
, L
"open", L
"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
))
884 else if (uMsg
== DFM_MERGECONTEXTMENU
)
886 QCMINFO
*pqcminfo
= (QCMINFO
*)lParam
;
887 _InsertMenuItemW(pqcminfo
->hmenu
, pqcminfo
->indexMenu
++, TRUE
, 0, MFT_SEPARATOR
, NULL
, 0);
888 _InsertMenuItemW(pqcminfo
->hmenu
, pqcminfo
->indexMenu
++, TRUE
, FCIDM_SHVIEW_PROPERTIES
, MFT_STRING
, MAKEINTRESOURCEW(IDS_PROPERTIES
), MFS_ENABLED
);
894 PIDLIST_ABSOLUTE pidlFolder
;
895 PUITEMID_CHILD
*apidl
;
897 HRESULT hr
= SH_GetApidlFromDataObject(pdtobj
, &pidlFolder
, &apidl
, &cidl
);
898 if (FAILED_UNEXPECTEDLY(hr
))
902 ERR("SHMultiFileProperties is not yet implemented\n");
905 hr
= GetDisplayNameOf(apidl
[0], SHGDN_FORPARSING
, &strFile
);
908 hr
= SH_ShowPropertiesDialog(strFile
.pOleStr
, pidlFolder
, apidl
);
910 ERR("SH_ShowPropertiesDialog failed\n");
914 ERR("Failed to get display name\n");
918 _ILFreeaPidl(apidl
, cidl
);
923 /*************************************************************************
924 * SHGetDesktopFolder [SHELL32.@]
926 HRESULT WINAPI
SHGetDesktopFolder(IShellFolder
**psf
)
931 if(!psf
) return E_INVALIDARG
;
933 hres
= CDesktopFolder::_CreatorClass::CreateInstance(NULL
, IID_PPV_ARG(IShellFolder
, psf
));
935 TRACE("-- %p->(%p)\n",psf
, *psf
);