Author: gadamopoulos
Date: Thu Jul 25 12:54:30 2013
New Revision: 59579
URL:
http://svn.reactos.org/svn/reactos?rev=59579&view=rev
Log:
[shell32]
- Improve the execution of a shell verb in the default context menu.
- Retrieve the browse flags from the verb in order to figure out if we should actually try
to browse
- Execute all the items that were selected and not only the first one
Modified:
trunk/reactos/dll/win32/shell32/defcontextmenu.cpp
Modified: trunk/reactos/dll/win32/shell32/defcontextmenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/defconte…
==============================================================================
--- trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] Thu Jul 25 12:54:30
2013
@@ -8,10 +8,7 @@
/*
TODO:
-1. In DoStaticShellExtensions, check for "Explore" and "Open" verbs,
and for BrowserFlags or
- ExplorerFlags under those entries. These flags indicate if we should browse to the
new item
- instead of attempting to open it.
-2. The code in NotifyShellViewWindow to deliver commands to the view is broken. It is an
excellent
+ The code in NotifyShellViewWindow to deliver commands to the view is broken. It is an
excellent
example of the wrong way to do it.
*/
@@ -71,6 +68,9 @@
HRESULT DoFormat(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoDynamicShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoStaticShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
+ DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry
pEntry);
+ HRESULT TryToBrowse(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD
wFlags);
+ HRESULT InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl,
PStaticShellEntry pEntry);
public:
CDefaultContextMenu();
@@ -1484,23 +1484,64 @@
return E_FAIL;
}
-
-HRESULT
-CDefaultContextMenu::DoStaticShellExtensions(
- LPCMINVOKECOMMANDINFO lpcmi)
-{
- PStaticShellEntry pEntry = m_pStaticEntries;
- INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
+DWORD
+CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry
pEntry)
+{
+ LPSHELLBROWSER lpSB;
+ HWND hwndTree;
+ LPWSTR FlagsName;
+ WCHAR wszKey[256];
HRESULT hr;
-
- while (pEntry && (iCmd--) > 0)
- pEntry = pEntry->pNext;
-
- if (iCmd > 0)
- return E_FAIL;
-
+ DWORD wFlags;
+ DWORD cbVerb;
+
+ /* Get a pointer to the shell browser */
+ lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0);
+ if (lpSB == NULL)
+ return 0;
+
+ /* See if we are in Explore or Browse mode. If the browser's tree is present, we
are in Explore mode.*/
+ if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwndTree)) &&
hwndTree)
+ FlagsName = L"ExplorerFlags";
+ else
+ FlagsName = L"BrowserFlags";
+
+ /* Try to get the flag from the verb */
+ hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"%s\\shell\\%s",
pEntry->szClass, pEntry->szVerb);
+ if (!SUCCEEDED(hr))
+ return 0;
+
+ cbVerb = sizeof(wFlags);
+ if (RegGetValueW(HKEY_CLASSES_ROOT, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL,
&wFlags, &cbVerb) == ERROR_SUCCESS)
+ {
+ return wFlags;
+ }
+
+ return 0;
+}
+
+HRESULT
+CDefaultContextMenu::TryToBrowse(
+ LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
+{
+ LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
+ HRESULT hr;
+
+ if (lpSB == NULL)
+ return E_FAIL;
+
+ hr = lpSB->BrowseObject(ILCombine(m_Dcm.pidlFolder, pidl), wFlags);
+
+ return hr;
+}
+
+HRESULT
+CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl,
PStaticShellEntry pEntry)
+{
+ HRESULT hr;
STRRET strFile;
- hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile);
+
+ hr = m_Dcm.psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
if (hr != S_OK)
{
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
@@ -1508,7 +1549,7 @@
}
WCHAR wszPath[MAX_PATH];
- hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, MAX_PATH);
+ hr = StrRetToBufW(&strFile, pidl, wszPath, MAX_PATH);
if (hr != S_OK)
return hr;
@@ -1519,14 +1560,57 @@
SHELLEXECUTEINFOW sei;
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei);
- sei.fMask = SEE_MASK_CLASSNAME;
- sei.lpClass = pEntry->szClass;
sei.hwnd = lpcmi->hwnd;
sei.nShow = SW_SHOWNORMAL;
sei.lpVerb = pEntry->szVerb;
sei.lpFile = wszPath;
sei.lpDirectory = wszDir;
ShellExecuteExW(&sei);
+
+ return S_OK;
+}
+
+HRESULT
+CDefaultContextMenu::DoStaticShellExtensions(
+ LPCMINVOKECOMMANDINFO lpcmi)
+{
+ PStaticShellEntry pEntry = m_pStaticEntries;
+ INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
+ HRESULT hr;
+ UINT i;
+
+ while (pEntry && (iCmd--) > 0)
+ pEntry = pEntry->pNext;
+
+ if (iCmd > 0)
+ return E_FAIL;
+
+ /* Get the browse flags to see if we need to browse */
+ DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
+ BOOL bBrowsed = FALSE;
+
+ for (i=0; i < m_Dcm.cidl; i++)
+ {
+ /* Check if we need to browse */
+ if (wFlags > 0)
+ {
+ /* In xp if we have browsed, we don't open any more folders .
+ * In win7 we browse to the first folder we find and
+ * open new windows fo for each of the rest of the folders */
+ if (bBrowsed)
+ continue;
+
+ hr = TryToBrowse(lpcmi, m_Dcm.apidl[i], wFlags);
+ if (SUCCEEDED(hr))
+ {
+ bBrowsed = TRUE;
+ continue;
+ }
+ }
+
+ InvokePidl(lpcmi, m_Dcm.apidl[i], pEntry);
+ }
+
return S_OK;
}