Author: gadamopoulos
Date: Thu Oct 22 15:23:21 2015
New Revision: 69647
URL:
http://svn.reactos.org/svn/reactos?rev=69647&view=rev
Log:
[SHELL32]
- Add DoDeleteAsync method that takes the data object and the fMask parameter from
IContextMenu in order to distinguish if we need a permanent delete.
- CDefView: Properly add CMIC_MASK_SHIFT_DOWN and CMIC_MASK_CONTROL_DOWN flags when
calling Invoke.
- CDefaultContextMenu: use DoDeleteAsync and pass fmask so as to make Shift+Delete
shortcut to permanently delete files.
Note: GetKeyState sometimes returns wrong results but this doesn't concern the shell.
CORE-4365
Modified:
trunk/reactos/dll/win32/shell32/CDefView.cpp
trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp
trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp
trunk/reactos/dll/win32/shell32/folders/CRecycleBin.h
Modified: trunk/reactos/dll/win32/shell32/CDefView.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CDefView…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CDefView.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CDefView.cpp [iso-8859-1] Thu Oct 22 15:23:21 2015
@@ -151,6 +151,7 @@
void OnDeactivate();
void DoActivate(UINT uState);
HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
+ HRESULT InvokeContextMenuCommand(UINT uCommand);
LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
// *** IOleWindow methods ***
@@ -1250,13 +1251,30 @@
return m_cidl;
}
+HRESULT CDefView::InvokeContextMenuCommand(UINT uCommand)
+{
+ CMINVOKECOMMANDINFO cmi;
+
+ ZeroMemory(&cmi, sizeof(cmi));
+ cmi.cbSize = sizeof(cmi);
+ cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
+ cmi.hwnd = m_hWnd;
+
+ if (GetKeyState(VK_SHIFT) & 0x8000)
+ cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
+
+ if (GetKeyState(VK_CONTROL) & 0x8000)
+ cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
+
+ return m_pCM->InvokeCommand(&cmi);
+}
+
/**********************************************************
* ShellView_OpenSelectedItems()
*/
HRESULT CDefView::OpenSelectedItems()
{
HMENU hMenu;
- CMINVOKECOMMANDINFO cmi;
UINT uCommand;
HRESULT hResult;
@@ -1287,12 +1305,7 @@
goto cleanup;
}
- ZeroMemory(&cmi, sizeof(cmi));
- cmi.cbSize = sizeof(cmi);
- cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
- cmi.hwnd = m_hWnd;
-
- hResult = m_pCM->InvokeCommand(&cmi);
+ InvokeContextMenuCommand(uCommand);
cleanup:
@@ -1314,7 +1327,6 @@
WORD y;
UINT uCommand;
HMENU hMenu;
- CMINVOKECOMMANDINFO cmi;
HRESULT hResult;
// for some reason I haven't figured out, we sometimes recurse into this method
@@ -1339,9 +1351,6 @@
hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
CMF_NORMAL);
if (FAILED( hResult))
goto cleanup;
-
- if (m_FolderSettings.fFlags & FWF_DESKTOP)
- SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
uCommand = TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON |
TPM_RIGHTBUTTON,
@@ -1352,14 +1361,9 @@
if (uCommand == FCIDM_SHVIEW_OPEN && OnDefaultCommand() == S_OK)
goto cleanup;
- ZeroMemory(&cmi, sizeof(cmi));
- cmi.cbSize = sizeof(cmi);
- cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
- cmi.hwnd = m_hWnd;
- m_pCM->InvokeCommand(&cmi);
+ InvokeContextMenuCommand(uCommand);
cleanup:
-
if (m_pCM)
m_pCM.Release();
@@ -1372,7 +1376,6 @@
LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection)
{
HRESULT hResult;
- CMINVOKECOMMANDINFO cmi;
HMENU hMenu;
hMenu = CreatePopupMenu();
@@ -1387,14 +1390,9 @@
if (FAILED( hResult))
goto cleanup;
- ZeroMemory(&cmi, sizeof(cmi));
- cmi.cbSize = sizeof(cmi);
- cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
- cmi.hwnd = m_hWnd;
- m_pCM->InvokeCommand(&cmi);
+ InvokeContextMenuCommand(uCommand);
cleanup:
-
if (m_pCM)
m_pCM.Release();
Modified: trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CDefault…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] Thu Oct 22
15:23:21 2015
@@ -1165,19 +1165,9 @@
return S_OK;
}
-HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFO lpcmi) {
- TRACE("(%p) Deleting\n", this);
-
- CComPtr<IDataObject> pDataObject;
-
- if (SUCCEEDED(SHCreateDataObject(m_pidlFolder, m_cidl, m_apidl, NULL,
IID_PPV_ARG(IDataObject, &pDataObject))))
- {
- IStream *s;
- CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObject, &s);
- SHCreateThread(DoDeleteThreadProc, s, NULL, NULL);
- }
- else
- return E_FAIL;
+HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFO lpcmi)
+{
+ DoDeleteAsync(m_pDataObj, lpcmi->fMask);
return S_OK;
}
Modified: trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp [iso-8859-1] Thu Oct 22
15:23:21 2015
@@ -1030,10 +1030,14 @@
InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
/* Handle cfShellIDList Drop objects here, otherwise send the approriate message to
other software */
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) {
- IStream *s;
- CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObject, &s);
- SHCreateThread(DoDeleteThreadProc, s, NULL, NULL);
+ if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
+ {
+ DWORD fMask = 0;
+
+ if ((dwKeyState & MK_SHIFT) == MK_SHIFT)
+ fMask |= CMIC_MASK_SHIFT_DOWN;
+
+ DoDeleteAsync(pDataObject, fMask);
}
else
{
@@ -1045,20 +1049,7 @@
return S_OK;
}
-DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter)
-{
- CoInitialize(NULL);
- CComPtr<IDataObject> pDataObject;
- HRESULT hr = CoGetInterfaceAndReleaseStream
(static_cast<IStream*>(lpParameter), IID_PPV_ARG(IDataObject, &pDataObject));
- if (SUCCEEDED(hr))
- {
- DoDeleteDataObject(pDataObject);
- }
- CoUninitialize();
- return 0;
-}
-
-HRESULT WINAPI DoDeleteDataObject(IDataObject *pda)
+HRESULT WINAPI DoDeleteDataObject(IDataObject *pda, DWORD fMask)
{
TRACE("performing delete");
HRESULT hr;
@@ -1160,7 +1151,8 @@
ZeroMemory(&FileOp, sizeof(FileOp));
FileOp.wFunc = FO_DELETE;
FileOp.pFrom = pwszPaths;
- FileOp.fFlags = FOF_ALLOWUNDO;
+ if ((fMask & CMIC_MASK_SHIFT_DOWN) == 0)
+ FileOp.fFlags = FOF_ALLOWUNDO;
if (SHFileOperationW(&FileOp) != 0)
{
@@ -1174,6 +1166,35 @@
ReleaseStgMedium(&medium);
return hr;
+}
+
+struct DeleteThreadData {
+ IStream *s;
+ DWORD fMask;
+};
+
+DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter)
+{
+ DeleteThreadData *data = static_cast<DeleteThreadData*>(lpParameter);
+ CoInitialize(NULL);
+ IDataObject *pDataObject;
+ HRESULT hr = CoGetInterfaceAndReleaseStream (data->s, IID_PPV_ARG(IDataObject,
&pDataObject));
+ if (SUCCEEDED(hr))
+ {
+ DoDeleteDataObject(pDataObject, data->fMask);
+ }
+ pDataObject->Release();
+ CoUninitialize();
+ HeapFree(GetProcessHeap(), 0, data);
+ return 0;
+}
+
+void DoDeleteAsync(IDataObject *pda, DWORD fMask)
+{
+ DeleteThreadData *data =
static_cast<DeleteThreadData*>(HeapAlloc(GetProcessHeap(), 0,
sizeof(DeleteThreadData)));
+ data->fMask = fMask;
+ CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pda, &data->s);
+ SHCreateThread(DoDeleteThreadProc, data, NULL, NULL);
}
/*************************************************************************
Modified: trunk/reactos/dll/win32/shell32/folders/CRecycleBin.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CRecycleBin.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CRecycleBin.h [iso-8859-1] Thu Oct 22 15:23:21
2015
@@ -22,8 +22,7 @@
#ifndef _SHFLDR_RECYCLEBIN_H_
#define _SHFLDR_RECYCLEBIN_H_
-DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter);
-HRESULT WINAPI DoDeleteDataObject(IDataObject *pda);
+void DoDeleteAsync(IDataObject *pda, DWORD fMask);
BOOL TRASH_CanTrashFile(LPCWSTR wszPath);
BOOL TRASH_TrashFile(LPCWSTR wszPath);