/* Undocumented functions from shdocvw */
extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
-/***********************************************************************
-* Desktopfolder implementation
-*/
-
-class CDesktopFolder;
-
-class CDesktopFolderEnum :
- public CEnumIDListBase
-{
- private:
-// CComPtr fDesktopEnumerator;
-// CComPtr fCommonDesktopEnumerator;
- public:
- CDesktopFolderEnum();
- ~CDesktopFolderEnum();
- HRESULT WINAPI Initialize(CDesktopFolder *desktopFolder, HWND hwndOwner, DWORD dwFlags);
-
- BEGIN_COM_MAP(CDesktopFolderEnum)
- COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
- END_COM_MAP()
-};
-
-int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
-
-static const shvheader DesktopSFHeader[] = {
- {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
- {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
- {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
- {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
- {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
-};
-
-#define DESKTOPSHELLVIEWCOLUMNS 5
-
-CDesktopFolderEnum::CDesktopFolderEnum()
-{
-}
-
-CDesktopFolderEnum::~CDesktopFolderEnum()
-{
-}
-
static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
return Result;
}
-static VOID
-SetNamespaceExtensionVisibleStatus(const WCHAR * iid, DWORD dwStatus)
+static INT IsNamespaceExtensionHidden(LPCITEMIDLIST pidl)
{
- HKEY hKey;
+ GUID const *clsid = _ILGetGUIDPointer (pidl);
+ if (!clsid)
+ return -1;
- if (RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
- {
- RegSetValueExW(hKey, iid, 0, REG_DWORD, (LPBYTE)&dwStatus, sizeof(DWORD));
- RegCloseKey(hKey);
- }
+ WCHAR pwszGuid[CHARS_IN_GUID];
+ SHELL32_GUIDToStringW(*clsid, pwszGuid);
+ return IsNamespaceExtensionHidden(pwszGuid);
}
-/**************************************************************************
- * CreateDesktopEnumList()
- */
-
-HRESULT WINAPI CDesktopFolderEnum::Initialize(CDesktopFolder *desktopFolder, HWND hwndOwner, DWORD dwFlags)
+class CDesktopFolderEnum :
+ public CEnumIDListBase
{
- BOOL ret = TRUE;
- WCHAR szPath[MAX_PATH];
-
- static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
- static const WCHAR Desktop_NameSpaceW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
-
- TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
-
- /* enumerate the root folders */
- if (dwFlags & SHCONTF_FOLDERS)
- {
- HKEY hkey;
- UINT i;
- DWORD dwResult;
-
- /* create the pidl for This item */
- if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
+ private:
+// CComPtr fDesktopEnumerator;
+// CComPtr fCommonDesktopEnumerator;
+ public:
+ HRESULT WINAPI Initialize(DWORD dwFlags,IEnumIDList * pRegEnumerator, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
{
- ret = AddToEnumList(_ILCreateMyDocuments());
- }
- ret = AddToEnumList(_ILCreateMyComputer());
+ BOOL ret = TRUE;
+ LPITEMIDLIST pidl;
- for (i = 0; i < 2; i++)
- {
- if (i == 0)
- dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
- else
- dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
+ static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
- if (dwResult == ERROR_SUCCESS)
- {
- WCHAR iid[50];
- LPITEMIDLIST pidl;
- int i = 0;
+ TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
- while (ret)
- {
- DWORD size;
- LONG r;
-
- size = sizeof (iid) / sizeof (iid[0]);
- r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
- if (ERROR_SUCCESS == r)
- {
- if (IsNamespaceExtensionHidden(iid) < 1)
- {
- pidl = _ILCreateGuidFromStrW(iid);
- if (pidl != NULL)
- {
- if (!HasItemWithCLSID(pidl))
- {
- ret = AddToEnumList(pidl);
- }
- else
- {
- SHFree(pidl);
- }
- }
- }
- }
- else if (ERROR_NO_MORE_ITEMS == r)
- break;
- else
- ret = FALSE;
- i++;
- }
- RegCloseKey(hkey);
- }
- }
- for (i = 0; i < 2; i++)
- {
- if (i == 0)
- dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ClassicStartMenuW, 0, KEY_READ, &hkey);
- else
- dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_READ, &hkey);
-
- if (dwResult == ERROR_SUCCESS)
+ /* enumerate the root folders */
+ if (dwFlags & SHCONTF_FOLDERS)
{
- DWORD j = 0, dwVal, Val, dwType, dwIID;
- LONG r;
- WCHAR iid[50];
+ AddToEnumList(_ILCreateMyComputer());
+ if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
+ AddToEnumList(_ILCreateMyDocuments());
- while(ret)
+ DWORD dwFetched;
+ while((S_OK == pRegEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
{
- dwVal = sizeof(Val);
- dwIID = sizeof(iid) / sizeof(WCHAR);
-
- r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
- if (r == ERROR_SUCCESS)
+ if (IsNamespaceExtensionHidden(pidl) < 1)
{
- if (Val == 0 && dwType == REG_DWORD)
- {
- LPITEMIDLIST pidl = _ILCreateGuidFromStrW(iid);
- if (pidl != NULL)
- {
- if (!HasItemWithCLSID(pidl))
- {
- AddToEnumList(pidl);
- }
- else
- {
- SHFree(pidl);
- }
- }
- }
+ if (!HasItemWithCLSID(pidl))
+ AddToEnumList(pidl);
+ else
+ SHFree(pidl);
}
- else if (ERROR_NO_MORE_ITEMS == r)
- break;
- else
- ret = FALSE;
}
- RegCloseKey(hkey);
}
+ /* Enumerate the items in the two fs folders */
+ AppendItemsFromEnumerator(pDesktopEnumerator);
+ AppendItemsFromEnumerator(pCommonDesktopEnumerator);
+
+ return ret ? S_OK : E_FAIL;
}
- }
- /* enumerate the elements in %windir%\desktop */
- ret = ret && SHGetSpecialFolderPathW(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);
- ret = ret && CreateFolderEnumList(szPath, dwFlags);
- ret = ret && SHGetSpecialFolderPathW(0, szPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
- ret = ret && CreateFolderEnumList(szPath, dwFlags);
+ BEGIN_COM_MAP(CDesktopFolderEnum)
+ COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+ END_COM_MAP()
+};
- return ret ? S_OK : E_FAIL;
-}
+int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
-void CDesktopFolder::SF_RegisterClipFmt()
-{
- TRACE ("(%p)\n", this);
+static const shvheader DesktopSFHeader[] = {
+ {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
+ {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
+ {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
+ {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+ {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
+ {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
+};
- if (!cfShellIDList)
- cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
-}
+#define DESKTOPSHELLVIEWCOLUMNS 6
+
+static const DWORD dwDesktopAttributes =
+ SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
+ SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
+static const DWORD dwMyComputerAttributes =
+ SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
+ SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
+static DWORD dwMyNetPlacesAttributes =
+ SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
+ SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
-CDesktopFolder::CDesktopFolder()
+CDesktopFolder::CDesktopFolder() :
+ sPathTarget(NULL),
+ pidlRoot(NULL)
{
- pidlRoot = NULL;
- sPathTarget = NULL;
- cfShellIDList = 0;
- SF_RegisterClipFmt();
- fAcceptFmt = FALSE;
}
CDesktopFolder::~CDesktopFolder()
HRESULT WINAPI CDesktopFolder::FinalConstruct()
{
- WCHAR szMyPath[MAX_PATH];
+ WCHAR szMyPath[MAX_PATH];
+ HRESULT hr;
+ /* Create the root pidl */
+ pidlRoot = _ILCreateDesktop();
+ if (!pidlRoot)
+ return E_OUTOFMEMORY;
+
+ /* Create the inner fs folder */
+ hr = SHELL32_CoCreateInitSF(pidlRoot,
+ &CLSID_ShellFSFolder,
+ CSIDL_DESKTOPDIRECTORY,
+ IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* Create the inner shared fs folder. Dont fail on failure. */
+ hr = SHELL32_CoCreateInitSF(pidlRoot,
+ &CLSID_ShellFSFolder,
+ CSIDL_COMMON_DESKTOPDIRECTORY,
+ IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* Create the inner reg folder */
+ hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
+ pidlRoot,
+ L"",
+ L"Desktop",
+ IID_PPV_ARG(IShellFolder2, &m_regFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* Cache the path to the user desktop directory */
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
return E_UNEXPECTED;
- pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
+ if (!sPathTarget)
+ return E_OUTOFMEMORY;
+
wcscpy(sPathTarget, szMyPath);
return S_OK;
}
+HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf)
+{
+ 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 (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen))
+ return E_FAIL;
+
+ if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES)
+ return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
+ else
+ return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
+}
+
/**************************************************************************
* CDesktopFolder::ParseDisplayName
*
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes)
{
- WCHAR szElement[MAX_PATH];
LPCWSTR szNext = NULL;
LPITEMIDLIST pidlTemp = NULL;
PARSEDURLW urldata;
HRESULT hr = S_OK;
- CLSID clsid;
TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
if (!ppidl)
return E_INVALIDARG;
+ *ppidl = NULL;
+
if (!lpszDisplayName)
- {
- *ppidl = NULL;
return E_INVALIDARG;
- }
-
- *ppidl = NULL;
if (pchEaten)
*pchEaten = 0; /* strange but like the original */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
- szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
- TRACE ("-- element: %s\n", debugstr_w (szElement));
- CLSIDFromString (szElement + 2, &clsid);
- pidlTemp = _ILCreateGuid (PT_GUID, clsid);
+ return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
{
if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */
{
TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix));
- SHCLSIDFromStringW (urldata.pszSuffix + 2, &clsid);
- pidlTemp = _ILCreateGuid (PT_GUID, clsid);
+ pidlTemp = _ILCreateGuidFromStrW(urldata.pszSuffix + 2);
}
else
return IEParseDisplayNameWithBCW(CP_ACP, lpszDisplayName, pbc, ppidl);
}
else
{
- /* it's a filesystem path on the desktop. Let a FSFolder parse it */
-
if (*lpszDisplayName)
{
- WCHAR szPath[MAX_PATH];
- LPWSTR pathPtr;
+ /* it's a filesystem path on the desktop. Let a FSFolder parse it */
+ hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
+ if (SUCCEEDED(hr))
+ return hr;
- /* build a complete path to create a simple pidl */
- lstrcpynW(szPath, sPathTarget, MAX_PATH);
- pathPtr = PathAddBackslashW(szPath);
- if (pathPtr)
- {
- lstrcpynW(pathPtr, lpszDisplayName, MAX_PATH - (pathPtr - szPath));
- hr = _ILCreateFromPathW(szPath, &pidlTemp);
- }
- else
- {
- /* should never reach here, but for completeness */
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- }
+ return m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
else
pidlTemp = _ILCreateMyComputer();
else
{
if (pdwAttributes && *pdwAttributes)
- hr = SHELL32_GetItemAttributes((IShellFolder *)this,
- pidlTemp, pdwAttributes);
+ {
+ GetAttributesOf(1, &pidlTemp, pdwAttributes);
+ }
}
}
*/
HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
- return ShellObjectCreatorInit<CDesktopFolderEnum>(this, hwndOwner, dwFlags, IID_IEnumIDList, ppEnumIDList);
+ CComPtr<IEnumIDList> pRegEnumerator;
+ CComPtr<IEnumIDList> pDesktopEnumerator;
+ CComPtr<IEnumIDList> pCommonDesktopEnumerator;
+ HRESULT hr;
+
+ hr = m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
+ if (FAILED(hr))
+ ERR("EnumObjects for reg folder failed\n");
+
+ hr = m_DesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pDesktopEnumerator);
+ if (FAILED(hr))
+ ERR("EnumObjects for desktop fs folder failed\n");
+
+ hr = m_SharedDesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pCommonDesktopEnumerator);
+ if (FAILED(hr))
+ ERR("EnumObjects for shared desktop fs folder failed\n");
+
+ return ShellObjectCreatorInit<CDesktopFolderEnum>(dwFlags,pRegEnumerator, pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
}
/**************************************************************************
REFIID riid,
LPVOID *ppvOut)
{
- TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
- this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
+ if (!pidl)
+ return E_INVALIDARG;
+
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(pidl, &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- return SHELL32_BindToChild( pidlRoot, sPathTarget, pidl, riid, ppvOut );
+ return psf->BindToObject(pidl, pbcReserved, riid, ppvOut);
}
/**************************************************************************
*/
HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
- int nReturn;
+ bool bIsDesktopFolder1, bIsDesktopFolder2;
+
+ if (!pidl1 || !pidl2)
+ {
+ ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
+ return E_INVALIDARG;
+ }
+
+ bIsDesktopFolder1 = _ILIsDesktop(pidl1);
+ bIsDesktopFolder2 = _ILIsDesktop(pidl2);
+ if (bIsDesktopFolder1 || bIsDesktopFolder2)
+ return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
- TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
- nReturn = SHELL32_CompareIDs ((IShellFolder *)this, lParam, pidl1, pidl2);
- TRACE ("-- %i\n", nReturn);
- return nReturn;
+ if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
+ return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
+
+ return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
}
/**************************************************************************
REFIID riid,
LPVOID *ppvOut)
{
- CComPtr<IShellView> pShellView;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
if (IsEqualIID (riid, IID_IDropTarget))
{
- hr = this->QueryInterface (IID_IDropTarget, ppvOut);
+ hr = m_DesktopFSFolder->CreateViewObject(hwndOwner, riid, ppvOut);
}
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))
{
- hr = IShellView_Constructor((IShellFolder *)this, &pShellView);
- if (pShellView)
- hr = pShellView->QueryInterface(riid, ppvOut);
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
}
TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
return hr;
DWORD *rgfInOut)
{
HRESULT hr = S_OK;
- static const DWORD dwDesktopAttributes =
- SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
- SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
- static const DWORD dwMyComputerAttributes =
- SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
- SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
- static DWORD dwMyNetPlacesAttributes =
- SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
- SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
*rgfInOut &= dwMyComputerAttributes;
else if (_ILIsNetHood(apidl[i]))
*rgfInOut &= dwMyNetPlacesAttributes;
+ else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
+ {
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
+ continue;
+
+ psf->GetAttributesOf(1, &apidl[i], rgfInOut);
+ }
else
- SHELL32_GetItemAttributes((IShellFolder *)this, apidl[i], rgfInOut);
+ ERR("Got an unknown pidl type!!!\n");
}
}
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
UINT *prgfInOut,
LPVOID *ppvOut)
{
- LPITEMIDLIST pidl;
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
*ppvOut = NULL;
+ if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]))
+ {
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(apidl[0], &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return psf->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
+ }
+
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))
{
hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
}
- else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
- {
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconA_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
- }
- else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
+ else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconW_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
- }
- else if (IsEqualIID (riid, IID_IDropTarget))
- {
- /* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
- if (cidl != 1 || FAILED(hr = this->_GetDropTarget(apidl[0], (LPVOID*) &pObj)))
- {
- IDropTarget * pDt = NULL;
- hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
- pObj = pDt;
- }
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
- else if ((IsEqualIID(riid, IID_IShellLinkW) ||
- IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
+ else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
{
- pidl = ILCombine (pidlRoot, apidl[0]);
- hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
- SHFree (pidl);
+ 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;
*/
HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
{
- HRESULT hr = S_OK;
- LPWSTR pszPath;
-
TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
pdump (pidl);
if (!strRet)
return E_INVALIDARG;
- pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
- if (!pszPath)
- return E_OUTOFMEMORY;
-
- if (_ILIsDesktop (pidl))
+ if (!_ILIsPidlSimple (pidl))
{
- if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
- (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
- wcscpy(pszPath, sPathTarget);
- else
- HCR_GetClassNameW(CLSID_ShellDesktop, pszPath, MAX_PATH);
+ return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
- else if (_ILIsPidlSimple (pidl))
+ else if (_ILIsDesktop(pidl))
{
- GUID const *clsid;
-
- if ((clsid = _ILGetGUIDPointer (pidl)))
- {
- if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
- {
- int bWantsForParsing;
-
- /*
- * We can only get a filesystem path from a shellfolder if the
- * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
- *
- * Exception: The MyComputer folder doesn't have this key,
- * but any other filesystem backed folder it needs it.
- */
- if (IsEqualIID (*clsid, CLSID_MyComputer))
- {
- bWantsForParsing = TRUE;
- }
- else
- {
- /* get the "WantsFORPARSING" flag from the registry */
- static const WCHAR clsidW[] =
- { 'C', 'L', 'S', 'I', 'D', '\\', 0 };
- static const WCHAR shellfolderW[] =
- { '\\', 's', 'h', 'e', 'l', 'l', 'f', 'o', 'l', 'd', 'e', 'r', 0 };
- static const WCHAR wantsForParsingW[] =
- { 'W', 'a', 'n', 't', 's', 'F', 'o', 'r', 'P', 'a', 'r', 's', 'i', 'n',
- 'g', 0
- };
- WCHAR szRegPath[100];
- LONG r;
-
- wcscpy (szRegPath, clsidW);
- SHELL32_GUIDToStringW (*clsid, &szRegPath[6]);
- wcscat (szRegPath, shellfolderW);
- r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
- wantsForParsingW, NULL, NULL, NULL);
- if (r == ERROR_SUCCESS)
- bWantsForParsing = TRUE;
- else
- bWantsForParsing = FALSE;
- }
-
- if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
- bWantsForParsing)
- {
- /*
- * we need the filesystem path to the destination folder.
- * Only the folder itself can know it
- */
- hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
- pszPath,
- MAX_PATH);
- }
- else
- {
- /* parsing name like ::{...} */
- pszPath[0] = ':';
- pszPath[1] = ':';
- SHELL32_GUIDToStringW (*clsid, &pszPath[2]);
- }
- }
- else
- {
- /* user friendly name */
- HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
- }
- }
+ if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING))
+ return SHSetStrRet(strRet, sPathTarget);
else
- {
- int cLen = 0;
-
- /* file system folder or file rooted at the desktop */
- if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
- {
- lstrcpynW(pszPath, sPathTarget, MAX_PATH - 1);
- PathAddBackslashW(pszPath);
- cLen = wcslen(pszPath);
- }
-
- _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
- if (!_ILIsFolder(pidl))
- SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
-
- if (GetFileAttributes(pszPath) == INVALID_FILE_ATTRIBUTES)
- {
- /* file system folder or file rooted at the AllUsers desktop */
- if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
- {
- SHGetSpecialFolderPathW(0, pszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
- PathAddBackslashW(pszPath);
- cLen = wcslen(pszPath);
- }
-
- _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
- if (!_ILIsFolder(pidl))
- SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
- }
- }
- }
- else
- {
- /* a complex pidl, let the subfolder do the work */
- hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
- pszPath, MAX_PATH);
+ return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
}
- if (SUCCEEDED(hr))
- {
- /* Win9x always returns ANSI strings, NT always returns Unicode strings */
- if (GetVersion() & 0x80000000)
- {
- strRet->uType = STRRET_CSTR;
- if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->cStr, MAX_PATH,
- NULL, NULL))
- strRet->cStr[0] = '\0';
- CoTaskMemFree(pszPath);
- }
- else
- {
- strRet->uType = STRRET_WSTR;
- strRet->pOleStr = pszPath;
- }
- }
- else
- CoTaskMemFree(pszPath);
+ /* file system folder or file rooted at the desktop */
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(pidl, &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- TRACE ("-- (%p)->(%s,0x%08x)\n", this,
- strRet->uType == STRRET_CSTR ? strRet->cStr :
- debugstr_w(strRet->pOleStr), hr);
- return hr;
+ return psf->GetDisplayNameOf(pidl, dwFlags, strRet);
}
/**************************************************************************
DWORD dwFlags,
PITEMID_CHILD *pPidlOut)
{
- CComPtr<IShellFolder2> psf;
- HRESULT hr;
- WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1];
- LPWSTR ptr;
- BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));
-
- TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl,
- debugstr_w (lpName), dwFlags, pPidlOut);
-
- if (_ILGetGUIDPointer(pidl))
- {
- if (SUCCEEDED(BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psf))))
- {
- hr = psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
- return hr;
- }
- }
-
- /* build source path */
- lstrcpynW(szSrc, sPathTarget, MAX_PATH);
- ptr = PathAddBackslashW (szSrc);
- if (ptr)
- _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc));
-
- /* build destination path */
- if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) {
- lstrcpynW(szDest, sPathTarget, MAX_PATH);
- ptr = PathAddBackslashW (szDest);
- if (ptr)
- lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest));
- } else
- lstrcpynW(szDest, lpName, MAX_PATH);
-
- if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
- WCHAR *ext = PathFindExtensionW(szSrc);
- if(*ext != '\0') {
- INT len = wcslen(szDest);
- lstrcpynW(szDest + len, ext, MAX_PATH - len);
- }
- }
-
- if (!memcmp(szSrc, szDest, (wcslen(szDest) + 1) * sizeof(WCHAR)))
- {
- /* src and destination is the same */
- hr = S_OK;
- if (pPidlOut)
- hr = _ILCreateFromPathW(szDest, pPidlOut);
-
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(pidl, &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- }
-
- TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
- if (MoveFileW (szSrc, szDest))
- {
- hr = S_OK;
- if (pPidlOut)
- hr = _ILCreateFromPathW(szDest, pPidlOut);
-
- SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM,
- SHCNF_PATHW, szSrc, szDest);
-
- return hr;
- }
- return E_FAIL;
+ return psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
}
HRESULT WINAPI CDesktopFolder::GetDefaultSearchGUID(GUID *pguid)
UINT iColumn,
SHELLDETAILS *psd)
{
- HRESULT hr = S_OK;
-
- TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
-
if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
return E_INVALIDARG;
{
psd->fmt = DesktopSFHeader[iColumn].fmt;
psd->cxChar = DesktopSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTR;
- LoadStringA (shell32_hInstance, DesktopSFHeader[iColumn].colnameid,
- psd->str.cStr, MAX_PATH);
- return S_OK;
+ return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
}
- /* the data from the pidl */
- psd->str.uType = STRRET_CSTR;
- switch (iColumn)
- {
- case 0: /* name */
- hr = GetDisplayNameOf(pidl,
- SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
- break;
- case 1: /* size */
- _ILGetFileSize (pidl, psd->str.cStr, MAX_PATH);
- break;
- case 2: /* type */
- _ILGetFileType (pidl, psd->str.cStr, MAX_PATH);
- break;
- case 3: /* date */
- _ILGetFileDate (pidl, psd->str.cStr, MAX_PATH);
- break;
- case 4: /* attributes */
- _ILGetFileAttributes (pidl, psd->str.cStr, MAX_PATH);
- break;
- }
+ CComPtr<IShellFolder2> psf;
+ HRESULT hr = _GetSFFromPidl(pidl, &psf);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = psf->GetDetailsOf(pidl, iColumn, psd);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
return hr;
}
{
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::GetUniqueName(LPWSTR pwszName, UINT uLen)
+HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- CComPtr<IEnumIDList> penum;
- HRESULT hr;
- WCHAR wszText[MAX_PATH];
- WCHAR wszNewFolder[25];
- const WCHAR wszFormat[] = {'%', 's', ' ', '%', 'd', 0 };
-
- LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, sizeof(wszNewFolder) / sizeof(WCHAR));
-
- TRACE ("(%p)(%p %u)\n", this, pwszName, uLen);
-
- if (uLen < sizeof(wszNewFolder) / sizeof(WCHAR) + 3)
- return E_POINTER;
-
- lstrcpynW (pwszName, wszNewFolder, uLen);
-
- hr = EnumObjects(0,
- SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
- if (penum) {
- LPITEMIDLIST pidl;
- DWORD dwFetched;
- int i = 1;
-
-next:
- penum->Reset ();
- while (S_OK == penum->Next(1, &pidl, &dwFetched) &&
- dwFetched) {
- _ILSimpleGetTextW (pidl, wszText, MAX_PATH);
- if (0 == lstrcmpiW (wszText, pwszName)) {
- _snwprintf (pwszName, uLen, wszFormat, wszNewFolder, i++);
- if (i > 99) {
- hr = E_FAIL;
- break;
- }
- goto next;
- }
- }
-
- }
- return hr;
-}
-
-HRESULT WINAPI CDesktopFolder::AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut)
-{
- WCHAR wszNewDir[MAX_PATH];
- DWORD bRes;
- HRESULT hres = E_FAIL;
-
- TRACE ("(%p)(%s %p)\n", this, debugstr_w(pwszName), ppidlOut);
-
- wszNewDir[0] = 0;
- if (sPathTarget)
- lstrcpynW(wszNewDir, sPathTarget, MAX_PATH);
- PathAppendW(wszNewDir, pwszName);
- bRes = CreateDirectoryW (wszNewDir, NULL);
- if (bRes)
- {
- SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHW, wszNewDir, NULL);
- hres = S_OK;
- if (ppidlOut)
- hres = _ILCreateFromPathW(wszNewDir, ppidlOut);
- }
-
- return hres;
-}
-
-HRESULT WINAPI CDesktopFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl)
-{
- UINT i;
- SHFILEOPSTRUCTW op;
- WCHAR wszPath[MAX_PATH];
- WCHAR wszCaption[50];
- WCHAR *wszPathsList;
- HRESULT ret;
- WCHAR *wszCurrentPath;
- UINT bRestoreWithDeskCpl = FALSE;
- int res;
-
- TRACE ("(%p)(%u %p)\n", this, cidl, apidl);
- if (cidl == 0) return S_OK;
-
- for(i = 0; i < cidl; i++)
- {
- if (_ILIsMyComputer(apidl[i]))
- bRestoreWithDeskCpl++;
- else if (_ILIsNetHood(apidl[i]))
- bRestoreWithDeskCpl++;
- else if (_ILIsMyDocuments(apidl[i]))
- bRestoreWithDeskCpl++;
- }
-
- if (bRestoreWithDeskCpl)
- {
- /* FIXME use FormatMessage
- * use a similar message resource as in windows
- */
- LoadStringW(shell32_hInstance, IDS_DELETEMULTIPLE_TEXT, wszPath, sizeof(wszPath) / sizeof(WCHAR));
- wszPath[(sizeof(wszPath)/sizeof(WCHAR))-1] = 0;
-
- LoadStringW(shell32_hInstance, IDS_DELETEITEM_CAPTION, wszCaption, sizeof(wszCaption) / sizeof(WCHAR));
- wszCaption[(sizeof(wszCaption)/sizeof(WCHAR))-1] = 0;
-
- res = SHELL_ConfirmMsgBox(GetActiveWindow(), wszPath, wszCaption, NULL, cidl > 1);
- if (res == IDC_YESTOALL || res == IDYES)
- {
- for(i = 0; i < cidl; i++)
- {
- if (_ILIsMyComputer(apidl[i]))
- SetNamespaceExtensionVisibleStatus(L"{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0x1);
- else if (_ILIsNetHood(apidl[i]))
- SetNamespaceExtensionVisibleStatus(L"{208D2C60-3AEA-1069-A2D7-08002B30309D}", 0x1);
- else if (_ILIsMyDocuments(apidl[i]))
- SetNamespaceExtensionVisibleStatus(L"{450D8FBA-AD25-11D0-98A8-0800361B1103}", 0x1);
- }
- }
- }
- if (sPathTarget)
- lstrcpynW(wszPath, sPathTarget, MAX_PATH);
- else
- wszPath[0] = '\0';
-
- PathAddBackslashW(wszPath);
- wszPathsList = BuildPathsList(wszPath, cidl, apidl);
-
- ZeroMemory(&op, sizeof(op));
- op.hwnd = GetActiveWindow();
- op.wFunc = FO_DELETE;
- op.pFrom = wszPathsList;
- op.fFlags = FOF_ALLOWUNDO;
- if (SHFileOperationW(&op))
- {
- WARN("SHFileOperation failed\n");
- ret = E_FAIL;
- }
- else
- ret = S_OK;
-
- /* we currently need to manually send the notifies */
- wszCurrentPath = wszPathsList;
- for (i = 0; i < cidl; i++)
- {
- LONG wEventId;
-
- if (_ILIsFolder(apidl[i]))
- wEventId = SHCNE_RMDIR;
- else if (_ILIsValue(apidl[i]))
- wEventId = SHCNE_DELETE;
- else
- continue;
-
- /* check if file exists */
- if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
- {
- LPITEMIDLIST pidl = ILCombine(pidlRoot, apidl[i]);
- SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
- SHFree(pidl);
- }
-
- wszCurrentPath += wcslen(wszCurrentPath) + 1;
- }
- HeapFree(GetProcessHeap(), 0, wszPathsList);
- return ret;
-}
+ if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
+ return S_OK;
-HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy)
-{
- CComPtr<IPersistFolder2> ppf2;
- WCHAR szSrcPath[MAX_PATH];
- WCHAR szTargetPath[MAX_PATH];
- SHFILEOPSTRUCTW op;
- LPITEMIDLIST pidl;
- LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
- int res, length;
- STRRET strRet;
-
- TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
-
- pSFFrom->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
- if (ppf2)
+ /* no data object means no selection */
+ if (!pdtobj)
{
- if (FAILED(ppf2->GetCurFolder(&pidl)))
- return E_FAIL;
-
- if (FAILED(pSFFrom->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strRet)))
- {
- SHFree (pidl);
- return E_FAIL;
- }
-
- if (FAILED(StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH)))
- {
- SHFree (pidl);
- return E_FAIL;
- }
- SHFree (pidl);
-
- pszSrc = PathAddBackslashW (szSrcPath);
-
- wcscpy(szTargetPath, sPathTarget);
- pszTarget = PathAddBackslashW (szTargetPath);
-
- pszSrcList = BuildPathsList(szSrcPath, cidl, apidl);
- pszTargetList = BuildPathsList(szTargetPath, cidl, apidl);
-
- if (!pszSrcList || !pszTargetList)
- {
- if (pszSrcList)
- HeapFree(GetProcessHeap(), 0, pszSrcList);
-
- if (pszTargetList)
- HeapFree(GetProcessHeap(), 0, pszTargetList);
-
- SHFree (pidl);
- return E_OUTOFMEMORY;
- }
- ZeroMemory(&op, sizeof(op));
- if (!pszSrcList[0])
- {
- /* remove trailing backslash */
- pszSrc--;
- pszSrc[0] = L'\0';
- op.pFrom = szSrcPath;
- }
- else
- {
- op.pFrom = pszSrcList;
- }
-
- if (!pszTargetList[0])
+ if (uMsg == DFM_INVOKECOMMAND && wParam == DFM_CMD_PROPERTIES)
{
- /* remove trailing backslash */
- if (pszTarget - szTargetPath > 3)
- {
- pszTarget--;
- pszTarget[0] = L'\0';
- }
- else
- {
- pszTarget[1] = L'\0';
- }
-
- op.pTo = szTargetPath;
- op.fFlags = 0;
+ 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
+ else if (uMsg == DFM_MERGECONTEXTMENU)
{
- op.pTo = pszTargetList;
- op.fFlags = FOF_MULTIDESTFILES;
+ 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);
}
- op.hwnd = GetActiveWindow();
- op.wFunc = bCopy ? FO_COPY : FO_MOVE;
- op.fFlags |= FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
-
- res = SHFileOperationW(&op);
-
- if (res == DE_SAMEFILE)
- {
- length = wcslen(szTargetPath);
-
-
- pszFileName = wcsrchr(pszSrcList, '\\');
- pszFileName++;
-
- if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length))
- {
- wcscat(szTargetPath, L" ");
- }
-
- wcscat(szTargetPath, pszFileName);
- op.pTo = szTargetPath;
-
- res = SHFileOperationW(&op);
- }
-
-
- HeapFree(GetProcessHeap(), 0, pszSrcList);
- HeapFree(GetProcessHeap(), 0, pszTargetList);
-
- if (res)
- return E_FAIL;
- else
- return S_OK;
- }
- return E_FAIL;
-}
-/****************************************************************************
- * IDropTarget implementation
- *
- * This should allow two somewhat separate things, copying files to the users directory,
- * as well as allowing icons to be moved anywhere and updating the registry to save.
- *
- * The first thing I think is best done using fs.cpp to prevent WET code. So we'll simulate
- * a drop to the user's home directory. The second will look at the pointer location and
- * set sensible places for the icons to live.
- *
- */
-BOOL CDesktopFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
-{
- /* TODO Windows does different drop effects if dragging across drives.
- i.e., it will copy instead of move if the directories are on different disks. */
-
- DWORD dwEffect = DROPEFFECT_MOVE;
-
- *pdwEffect = DROPEFFECT_NONE;
-
- if (fAcceptFmt) { /* Does our interpretation of the keystate ... */
- *pdwEffect = KeyStateToDropEffect (dwKeyState);
-
- if (*pdwEffect == DROPEFFECT_NONE)
- *pdwEffect = dwEffect;
-
- /* ... matches the desired effect ? */
- if (dwEffect & *pdwEffect) {
- return TRUE;
- }
+ return S_OK;
}
- return FALSE;
-}
-
-HRESULT WINAPI CDesktopFolder::DragEnter(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
- FORMATETC fmt;
- FORMATETC fmt2;
- fAcceptFmt = FALSE;
-
- InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
- InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
-
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
- fAcceptFmt = TRUE;
- else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
- fAcceptFmt = TRUE;
-
- QueryDrop(dwKeyState, pdwEffect);
- return S_OK;
-}
-
-HRESULT WINAPI CDesktopFolder::DragOver(DWORD dwKeyState, POINTL pt,
- DWORD *pdwEffect)
-{
- TRACE("(%p)\n", this);
-
- if (!pdwEffect)
- return E_INVALIDARG;
- QueryDrop(dwKeyState, pdwEffect);
-
- 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;
-HRESULT WINAPI CDesktopFolder::DragLeave()
-{
- TRACE("(%p)\n", this);
- fAcceptFmt = FALSE;
- return S_OK;
-}
+ if (cidl > 1)
+ ERR("SHMultiFileProperties is not yet implemented\n");
-HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("(%p) object dropped desktop\n", this);
-
- STGMEDIUM medium;
- bool passthroughtofs = FALSE;
- FORMATETC formatetc;
- InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
-
- HRESULT hr = pDataObject->GetData(&formatetc, &medium);
+ STRRET strFile;
+ hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
if (SUCCEEDED(hr))
{
- /* lock the handle */
- LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
- if (!lpcida)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* convert the clipboard data into pidl (pointer to id list) */
- LPITEMIDLIST pidl;
- LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
- if (!apidl)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
- passthroughtofs = !_ILIsDesktop(pidl) || (dwKeyState & MK_CONTROL);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
+ hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
+ if (FAILED(hr))
+ ERR("SH_ShowPropertiesDialog failed\n");
}
else
{
- InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
- if (SUCCEEDED(pDataObject->QueryGetData(&formatetc)))
- {
- passthroughtofs = TRUE;
- }
+ ERR("Failed to get display name\n");
}
- /* We only want to really move files around if they don't already
- come from the desktop, or we're linking or copying */
- if (passthroughtofs)
- {
- LPITEMIDLIST pidl = NULL;
-
- WCHAR szPath[MAX_PATH];
- //LPWSTR pathPtr;
-
- /* build a complete path to create a simple pidl */
- lstrcpynW(szPath, sPathTarget, MAX_PATH);
- /*pathPtr = */PathAddBackslashW(szPath);
- //hr = _ILCreateFromPathW(szPath, &pidl);
- hr = this->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL);
- if (SUCCEEDED(hr))
- {
- CComPtr<IDropTarget> pDT;
- hr = this->BindToObject(pidl, NULL, IID_PPV_ARG(IDropTarget, &pDT));
- CoTaskMemFree(pidl);
- if (SUCCEEDED(hr))
- SHSimulateDrop(pDT, pDataObject, dwKeyState, NULL, pdwEffect);
- else
- ERR("Error Binding");
- }
- else
- ERR("Error creating from %s\n", debugstr_w(szPath));
- }
-
- /* Todo, rewrite the registry such that the icons are well placed.
- Blocked by no bags implementation. */
- return hr;
-}
-
-HRESULT WINAPI CDesktopFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
- HRESULT hr;
-
- TRACE("CFSFolder::_GetDropTarget entered\n");
-
- if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
- return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
-
- LPITEMIDLIST pidlNext = NULL;
-
- STRRET strFile;
- hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
- if (SUCCEEDED(hr))
- {
- WCHAR wszPath[MAX_PATH];
- hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
-
- if (SUCCEEDED(hr))
- {
- PathRemoveFileSpecW (wszPath);
- hr = this->ParseDisplayName(NULL, NULL, wszPath, NULL, &pidlNext, NULL);
-
- if (SUCCEEDED(hr))
- {
- CComPtr<IShellFolder> psf;
- hr = this->BindToObject(pidlNext, NULL, IID_PPV_ARG(IShellFolder, &psf));
- CoTaskMemFree(pidlNext);
- if (SUCCEEDED(hr))
- {
- hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IDropTarget, NULL, ppvOut);
- if (FAILED(hr))
- ERR("FS GetUIObjectOf failed: %x\n", hr);
- }
- else
- ERR("BindToObject failed: %x\n", hr);
- }
- else
- ERR("ParseDisplayName failed: %x\n", hr);
- }
- else
- ERR("StrRetToBufW failed: %x\n", hr);
- }
- else
- ERR("GetDisplayNameOf failed: %x\n", hr);
+ SHFree(pidlFolder);
+ _ILFreeaPidl(apidl, cidl);
return hr;
}