From fe8535447f3b196be34e147d4c923df59faae2ed Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 1 Nov 2007 00:42:06 +0000 Subject: [PATCH] - implement IPersistFolder2 interface for desktop object - add a backslash when required - fixes deleting of objects on desktop svn path=/trunk/; revision=30032 --- reactos/dll/win32/shell32/shfldr_desktop.c | 95 +++++++++++++++++++++- reactos/dll/win32/shell32/shv_item_cmenu.c | 21 +++-- 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/shell32/shfldr_desktop.c b/reactos/dll/win32/shell32/shfldr_desktop.c index 9c6a57edd24..4ccf0f61608 100644 --- a/reactos/dll/win32/shell32/shfldr_desktop.c +++ b/reactos/dll/win32/shell32/shfldr_desktop.c @@ -61,6 +61,7 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); typedef struct { const IShellFolder2Vtbl *lpVtbl; + const IPersistFolder2Vtbl *lpPF2; LONG ref; /* both paths are parsible from the desktop */ @@ -104,7 +105,11 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface( { *ppvObj = This; } - + else if (IsEqualIID (riid, &IID_IPersistFolder) || + IsEqualIID (riid, &IID_IPersistFolder2)) + { + *ppvObj = &This->lpPF2; + } if (*ppvObj) { IUnknown_AddRef ((IUnknown *) (*ppvObj)); @@ -843,6 +848,93 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 = ISF_Desktop_fnMapColumnToSCID }; +static inline IGenericSFImpl *impl_from_IPersistFolder2( IPersistFolder2 *iface ) +{ + return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpPF2)); +} + +static HRESULT WINAPI +ISF_Desktop_PersistFolder2_fnQueryInterface (IPersistFolder2 * iface, REFIID iid, + LPVOID * ppvObj) +{ + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)\n", This); + + return ISF_Desktop_fnQueryInterface ((IShellFolder2*)This, iid, ppvObj); +} + +static ULONG WINAPI +ISF_Desktop_PersistFolder2_fnAddRef (IPersistFolder2 * iface) +{ + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)->(count=%u)\n", This, This->ref); + + return ISF_Desktop_fnAddRef((IShellFolder2*)This); +} + +static ULONG WINAPI +ISF_Desktop_PersistFolder2_fnRelease (IPersistFolder2 * iface) +{ + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)->(count=%u)\n", This, This->ref); + + return ISF_Desktop_fnRelease ((IShellFolder2*)This); +} + +static HRESULT WINAPI +ISF_Desktop_PersistFolder2_fnGetClassID (IPersistFolder2 * iface, CLSID * lpClassId) +{ + static GUID const CLSID_Desktop = + { 0x00021400, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)\n", This); + + if (!lpClassId) + return E_POINTER; + + memcpy(lpClassId, &CLSID_Desktop, sizeof(GUID)); + + return S_OK; +} +static HRESULT WINAPI +ISF_Desktop_PersistFolder2_fnInitialize (IPersistFolder2 * iface, LPCITEMIDLIST pidl) +{ + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)->(%p)\n", This, pidl); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +ISF_Desktop_PersistFolder2_fnGetCurFolder (IPersistFolder2 * iface, + LPITEMIDLIST * pidl) +{ + IGenericSFImpl *This = impl_from_IPersistFolder2(iface); + + TRACE ("(%p)->(%p)\n", This, pidl); + + if (!pidl) return E_POINTER; + *pidl = ILClone (This->pidlRoot); + return S_OK; +} + +static const IPersistFolder2Vtbl vt_FSFldr_PersistFolder2 = +{ + ISF_Desktop_PersistFolder2_fnQueryInterface, + ISF_Desktop_PersistFolder2_fnAddRef, + ISF_Desktop_PersistFolder2_fnRelease, + ISF_Desktop_PersistFolder2_fnGetClassID, + ISF_Desktop_PersistFolder2_fnInitialize, + ISF_Desktop_PersistFolder2_fnGetCurFolder, +}; + + /************************************************************************** * ISF_Desktop_Constructor */ @@ -872,6 +964,7 @@ HRESULT WINAPI ISF_Desktop_Constructor ( sf->ref = 1; sf->lpVtbl = &vt_MCFldr_ShellFolder2; + sf->lpPF2 = &vt_FSFldr_PersistFolder2; sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */ sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) ); lstrcpyW( sf->sPathTarget, szMyPath ); diff --git a/reactos/dll/win32/shell32/shv_item_cmenu.c b/reactos/dll/win32/shell32/shv_item_cmenu.c index eff86c68090..87e0a42fa71 100644 --- a/reactos/dll/win32/shell32/shv_item_cmenu.c +++ b/reactos/dll/win32/shell32/shv_item_cmenu.c @@ -34,6 +34,7 @@ #include "shlobj.h" #include "objbase.h" +#include "shlwapi.h" #include "shell32_main.h" #include "shellfolder.h" #include "debughlp.h" @@ -513,36 +514,39 @@ static void DoRename( */ static void DoDelete(IContextMenu2 *iface, HWND hwnd) { - ItemCmImpl *This = (ItemCmImpl *)iface; WCHAR szPath[MAX_PATH]; WCHAR * szTarget; SHFILEOPSTRUCTW op; - LPSHELLBROWSER lpSB; - LPSHELLVIEW lpSV; - IPersistFolder3 * psf; + LPSHELLBROWSER lpSB; + LPSHELLVIEW lpSV; + IPersistFolder2 * psf; LPITEMIDLIST pidl; STRRET strTemp; - + ItemCmImpl *This = (ItemCmImpl *)iface; + if (IShellFolder2_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&psf) != S_OK) { ERR("Failed to get interface IID_IPersistFolder2\n"); return; } + if (IPersistFolder2_GetCurFolder(psf, &pidl) != S_OK) { ERR("IPersistFolder2_GetCurFolder failed\n"); - IShellFolder2_Release(psf); + IPersistFolder2_Release(psf); return; } if (IShellFolder2_GetDisplayNameOf(This->pSFParent, pidl, SHGDN_FORPARSING, &strTemp) != S_OK) { ERR("IShellFolder_GetDisplayNameOf failed\n"); - IShellFolder2_Release(psf); + IPersistFolder2_Release(psf); return; } + szPath[MAX_PATH-1] = 0; StrRetToBufW(&strTemp, pidl, szPath, MAX_PATH); - IShellFolder2_Release(psf); + PathAddBackslashW(szPath); + IPersistFolder2_Release(psf); szTarget = build_paths_list(szPath, This->cidl, This->apidl); @@ -557,6 +561,7 @@ static void DoDelete(IContextMenu2 *iface, HWND hwnd) op.fFlags = FOF_ALLOWUNDO; SHFileOperationW(&op); } + ILFree(pidl); } if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0)))