HRESULT WINAPI CDesktopFolder::FinalConstruct()
{
- WCHAR szMyPath[MAX_PATH];
+ WCHAR szMyPath[MAX_PATH];
HRESULT hr;
- CComPtr<IPersistFolder3> ppf3;
/* Create the root pidl */
pidlRoot = _ILCreateDesktop();
+ if (!pidlRoot)
+ return E_OUTOFMEMORY;
/* Create the inner fs folder */
- hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
- if (FAILED(hr))
- return hr;
-
- hr = m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
- if (FAILED(hr))
+ hr = SHELL32_CoCreateInitSF(pidlRoot,
+ NULL,
+ NULL,
+ &CLSID_ShellFSFolder,
+ CSIDL_DESKTOPDIRECTORY,
+ IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- PERSIST_FOLDER_TARGET_INFO info;
- ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
- info.csidl = CSIDL_DESKTOPDIRECTORY;
- hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
-
- /* Create the inner shared fs folder */
- hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
- if (FAILED(hr))
+ /* Create the inner shared fs folder. Dont fail on failure. */
+ hr = SHELL32_CoCreateInitSF(pidlRoot,
+ NULL,
+ NULL,
+ &CLSID_ShellFSFolder,
+ CSIDL_COMMON_DESKTOPDIRECTORY,
+ IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- hr = m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
- if (FAILED(hr))
+ /* Create the inner reg folder */
+ hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
+ pidlRoot,
+ L"",
+ IID_PPV_ARG(IShellFolder2, &m_regFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- info.csidl = CSIDL_COMMON_DESKTOPDIRECTORY;
- hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
-
+ /* Cache the path to the user desktop directory */
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
return E_UNEXPECTED;
sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
+ if (!sPathTarget)
+ return E_OUTOFMEMORY;
+
wcscpy(sPathTarget, szMyPath);
return S_OK;
}
{
WCHAR szFileName[MAX_PATH];
+ if (_ILIsSpecialFolder(pidl))
+ return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
+
lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1);
PathAddBackslashW(szFileName);
int cLen = wcslen(szFileName);
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
- return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
+ return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
{
if (!pidl)
return E_INVALIDARG;
- if (_ILIsSpecialFolder(pidl))
- return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
-
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);
if (FAILED_UNEXPECTEDLY(hr))
return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
- return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
+ return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
}
}
else if (IsEqualIID (riid, IID_IContextMenu))
{
- WARN ("IContextMenu not implemented\n");
- hr = E_NOTIMPL;
+ HKEY hKeys[16];
+ UINT cKeys = 0;
+ AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
+
+ DEFCONTEXTMENU dcm;
+ dcm.hwnd = hwndOwner;
+ dcm.pcmcb = this;
+ dcm.pidlFolder = pidlRoot;
+ dcm.psf = this;
+ dcm.cidl = 0;
+ dcm.apidl = NULL;
+ dcm.cKeys = cKeys;
+ dcm.aKeys = hKeys;
+ dcm.punkAssociationInfo = NULL;
+ hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
}
else if (IsEqualIID (riid, IID_IShellView))
{
*rgfInOut &= dwMyComputerAttributes;
else if (_ILIsNetHood(apidl[i]))
*rgfInOut &= dwMyNetPlacesAttributes;
- else if (_ILIsSpecialFolder(apidl[i]))
- SHELL32_GetGuidItemAttributes(this, apidl[i], rgfInOut);
- else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]))
+ else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
{
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
if (IsEqualIID (riid, IID_IContextMenu))
{
- hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu **)&pObj);
+ if (_ILIsSpecialFolder(apidl[0]))
+ {
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
+ }
+ else
+ {
+ /* Do not use the context menu of the CFSFolder here. */
+ /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
+ /* Otherwise operations like that involve items from both user and shared desktop will not work */
+ HKEY hKeys[16];
+ UINT cKeys = 0;
+ AddFSClassKeysToArray(apidl[0], hKeys, &cKeys);
+
+ DEFCONTEXTMENU dcm;
+ dcm.hwnd = hwndOwner;
+ dcm.pcmcb = this;
+ dcm.pidlFolder = pidlRoot;
+ dcm.psf = this;
+ dcm.cidl = cidl;
+ dcm.apidl = apidl;
+ dcm.cKeys = cKeys;
+ dcm.aKeys = hKeys;
+ dcm.punkAssociationInfo = NULL;
+ hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
+ }
}
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
{
}
else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
- hr = GenericExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
+ }
+ else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
+ {
+ CComPtr<IShellFolder> psfChild;
+ hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return psfChild->CreateViewObject(NULL, riid, ppvOut);
}
else
hr = E_NOINTERFACE;
{
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
- else if (!_ILIsDesktop(pidl) && _ILIsSpecialFolder(pidl))
- {
- return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet);
- }
else if (_ILIsDesktop(pidl))
{
if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING))
return SHSetStrRet(strRet, sPathTarget);
else
- return HCR_GetClassName(CLSID_ShellDesktop, strRet);
+ return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
}
/* file system folder or file rooted at the desktop */
DWORD dwFlags,
PITEMID_CHILD *pPidlOut)
{
- if (_ILGetGUIDPointer(pidl))
- return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
-
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);
if (FAILED_UNEXPECTEDLY(hr))
psd->cxChar = DesktopSFHeader[iColumn].cxChar;
return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
}
- else if (_ILIsSpecialFolder(pidl))
- {
- return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
- }
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);
{
TRACE ("(%p)->(%p)\n", this, pidl);
- return E_NOTIMPL;
+ return E_INVALIDARG;
}
HRESULT WINAPI CDesktopFolder::GetCurFolder(LPITEMIDLIST * pidl)
{
TRACE ("(%p)->(%p)\n", this, pidl);
- if (!pidl) return E_POINTER;
+ if (!pidl)
+ return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
*pidl = ILClone (pidlRoot);
return S_OK;
}
+HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
+ return S_OK;
+
+ /* no data object means no selection */
+ if (!pdtobj)
+ {
+ if (uMsg == DFM_INVOKECOMMAND && wParam == DFM_CMD_PROPERTIES)
+ {
+ if (32 >= (UINT)ShellExecuteW(hwndOwner, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL))
+ return E_FAIL;
+ return S_OK;
+ }
+ else if (uMsg == DFM_MERGECONTEXTMENU)
+ {
+ QCMINFO *pqcminfo = (QCMINFO *)lParam;
+ _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+ _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
+ }
+
+ return S_OK;
+ }
+
+ PIDLIST_ABSOLUTE pidlFolder;
+ PUITEMID_CHILD *apidl;
+ UINT cidl;
+ HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (cidl > 1)
+ ERR("SHMultiFileProperties is not yet implemented\n");
+
+ STRRET strFile;
+ hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
+ if (SUCCEEDED(hr))
+ {
+ hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
+ if (FAILED(hr))
+ ERR("SH_ShowPropertiesDialog failed\n");
+ }
+ else
+ {
+ ERR("Failed to get display name\n");
+ }
+
+ SHFree(pidlFolder);
+ _ILFreeaPidl(apidl, cidl);
+
+ return hr;
+}
+
/*************************************************************************
* SHGetDesktopFolder [SHELL32.@]
*/