shell32: Use SHFileOperationW to delete files.

This commit is contained in:
Mikołaj Zalewski 2006-06-29 21:03:41 +02:00 committed by Alexandre Julliard
parent 48374cf630
commit 86fe1a0d5f

View File

@ -1154,6 +1154,36 @@ ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCWSTR pwszName,
return hres; return hres;
} }
/****************************************************************************
* build_paths_list
*
* Builds a list of paths like the one used in SHFileOperation from a table of
* PIDLs relative to the given base folder
*/
WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
{
WCHAR *wszPathsList;
WCHAR *wszListPos;
int iPathLen;
int i;
iPathLen = lstrlenW(wszBasePath);
wszPathsList = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)*cidl+1);
wszListPos = wszPathsList;
for (i = 0; i < cidl; i++) {
if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i]))
continue;
lstrcpynW(wszListPos, wszBasePath, MAX_PATH);
/* FIXME: abort if path too long */
_ILSimpleGetTextW(pidls[i], wszListPos+iPathLen, MAX_PATH-iPathLen);
wszListPos += lstrlenW(wszListPos)+1;
}
*wszListPos=0;
return wszPathsList;
}
/**************************************************************************** /****************************************************************************
* ISFHelper_fnDeleteItems * ISFHelper_fnDeleteItems
* *
@ -1164,59 +1194,60 @@ ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
{ {
IGenericSFImpl *This = impl_from_ISFHelper(iface); IGenericSFImpl *This = impl_from_ISFHelper(iface);
UINT i; UINT i;
SHFILEOPSTRUCTW op;
WCHAR wszPath[MAX_PATH]; WCHAR wszPath[MAX_PATH];
int iPathLen; WCHAR *wszPathsList;
BOOL bConfirm = TRUE; HRESULT ret;
WCHAR *wszCurrentPath;
TRACE ("(%p)(%u %p)\n", This, cidl, apidl); TRACE ("(%p)(%u %p)\n", This, cidl, apidl);
if (cidl==0) return S_OK;
/* deleting multiple items so give a slightly different warning */
if (cidl != 1) {
WCHAR tmp[8];
static const WCHAR format[] = {'%','d',0};
wnsprintfW (tmp, sizeof(tmp)/sizeof(tmp[0]), format, cidl);
if (!SHELL_ConfirmDialogW(ASK_DELETE_MULTIPLE_ITEM, tmp))
return E_FAIL;
bConfirm = FALSE;
}
if (This->sPathTarget) if (This->sPathTarget)
lstrcpynW(wszPath, This->sPathTarget, MAX_PATH); lstrcpynW(wszPath, This->sPathTarget, MAX_PATH);
else else
wszPath[0] = '\0'; wszPath[0] = '\0';
PathAddBackslashW(wszPath); PathAddBackslashW(wszPath);
iPathLen = lstrlenW(wszPath); wszPathsList = build_paths_list(wszPath, cidl, apidl);
for (i = 0; i < cidl; i++) { ZeroMemory(&op, sizeof(op));
_ILSimpleGetTextW (apidl[i], wszPath+iPathLen, MAX_PATH-iPathLen); op.hwnd = GetActiveWindow();
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
op.fFlags = 0;
if (SHFileOperationW(&op))
{
WARN("SHFileOperation failed\n");
ret = E_FAIL;
}
else
ret = S_OK;
if (_ILIsFolder (apidl[i])) { /* we currently need to manually send the notifies */
LPITEMIDLIST pidl; wszCurrentPath = wszPathsList;
for (i = 0; i < cidl; i++)
{
LONG wEventId;
TRACE ("delete %s\n", debugstr_w(wszPath)); if (_ILIsFolder(apidl[i]))
if (!SHELL_DeleteDirectoryW (wszPath, bConfirm)) { wEventId = SHCNE_RMDIR;
TRACE ("delete %s failed, bConfirm=%d\n", debugstr_w(wszPath), bConfirm); else if (_ILIsValue(apidl[i]))
return E_FAIL; wEventId = SHCNE_DELETE;
} else
pidl = ILCombine (This->pidlRoot, apidl[i]); continue;
SHChangeNotify (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
SHFree (pidl);
} else if (_ILIsValue (apidl[i])) {
LPITEMIDLIST pidl;
TRACE ("delete %s\n", debugstr_w(wszPath)); /* check if file exists */
if (!SHELL_DeleteFileW (wszPath, bConfirm)) { if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
TRACE ("delete %s failed, bConfirm=%d\n", debugstr_w(wszPath), bConfirm); {
return E_FAIL; LPITEMIDLIST pidl = ILCombine(This->pidlRoot, apidl[i]);
} SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
pidl = ILCombine (This->pidlRoot, apidl[i]); SHFree(pidl);
SHChangeNotify (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
SHFree (pidl);
} }
wszCurrentPath += lstrlenW(wszCurrentPath)+1;
} }
return S_OK; HeapFree(GetProcessHeap(), 0, wszPathsList);
return ret;
} }
/**************************************************************************** /****************************************************************************