Author: gadamopoulos
Date: Thu Aug 18 13:50:56 2016
New Revision: 72327
URL:
http://svn.reactos.org/svn/reactos?rev=72327&view=rev
Log:
[SHELL32]
- CDefView: Set the site of the context menu to the CDefView essentialy reverting r68727
which was wrong.
- CDefaultContextMenu: Implement IObjectWithSite interface. Don't use
CWM_GETISHELLBROWSER to get a pointer to the shell browser. Do a IUnknown_QueryService to
the site instead asking for either the shell browser or the shell view (and it is fine if
there is none of them).
- Rename IDefaultContextMenu_Constructor to CDefaultContextMenu_CreateInstance and use
ShellObjectCreatorInit to simplify its code.
Modified:
trunk/reactos/dll/win32/shell32/CDefView.cpp
trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp
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 Aug 18 13:50:56 2016
@@ -1210,6 +1210,8 @@
if (FAILED(hResult))
goto cleanup;
+ IUnknown_SetSite(m_pCM, (IShellView *)this);
+
hResult = m_pCM->QueryContextMenu(hMenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
if (FAILED(hResult))
goto cleanup;
@@ -1229,7 +1231,10 @@
DestroyMenu(hMenu);
if (m_pCM)
+ {
+ IUnknown_SetSite(m_pCM, NULL);
m_pCM.Release();
+ }
return hResult;
}
@@ -1262,6 +1267,8 @@
hResult = GetItemObject( m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND,
IID_PPV_ARG(IContextMenu, &m_pCM));
if (FAILED( hResult))
goto cleanup;
+
+ IUnknown_SetSite(m_pCM, (IShellView *)this);
hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
CMF_NORMAL);
if (FAILED( hResult))
@@ -1280,7 +1287,10 @@
cleanup:
if (m_pCM)
+ {
+ IUnknown_SetSite(m_pCM, NULL);
m_pCM.Release();
+ }
if (hMenu)
DestroyMenu(hMenu);
@@ -1301,6 +1311,8 @@
if (FAILED( hResult))
goto cleanup;
+ IUnknown_SetSite(m_pCM, (IShellView *)this);
+
hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
CMF_NORMAL);
if (FAILED( hResult))
goto cleanup;
@@ -1309,7 +1321,10 @@
cleanup:
if (m_pCM)
+ {
+ IUnknown_SetSite(m_pCM, NULL);
m_pCM.Release();
+ }
if (hMenu)
DestroyMenu(hMenu);
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 Aug 18
13:50:56 2016
@@ -5,12 +5,6 @@
* PURPOSE: provides default context menu implementation
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald(a)reactos.org)
*/
-
-/*
-TODO:
- The code in NotifyShellViewWindow to deliver commands to the view is broken. It is an
excellent
- example of the wrong way to do it.
-*/
#include "precomp.h"
@@ -61,9 +55,11 @@
class CDefaultContextMenu :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IContextMenu3
+ public IContextMenu3,
+ public IObjectWithSite
{
private:
+ CComPtr<IUnknown> m_site;
CComPtr<IShellFolder> m_psf;
UINT m_cidl;
PCUITEMID_CHILD_ARRAY m_apidl;
@@ -87,6 +83,7 @@
UINT BuildBackgroundContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast,
UINT uFlags);
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu);
UINT BuildShellItemContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast,
UINT uFlags);
+ HRESULT NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh);
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
@@ -121,10 +118,15 @@
// IContextMenu3
virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *plResult);
+ // IObjectWithSite
+ virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
+ virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
+
BEGIN_COM_MAP(CDefaultContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
END_COM_MAP()
};
@@ -992,21 +994,23 @@
return S_OK;
}
-static
-HRESULT
-NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh)
-{
- /* Note: CWM_GETISHELLBROWSER returns not referenced object */
- LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
- if (!lpSB)
- return E_FAIL;
-
- CComPtr<IShellView> lpSV;
- if (FAILED(lpSB->QueryActiveShellView(&lpSV)))
- return E_FAIL;
+HRESULT
+CDefaultContextMenu::NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh)
+{
+ CComPtr<IShellView> psv;
+
+ HRESULT hr;
+
+ if (!m_site)
+ return E_FAIL;;
+
+ /* Get a pointer to the shell browser */
+ hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView,
&psv));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
HWND hwndSV = NULL;
- if (SUCCEEDED(lpSV->GetWindow(&hwndSV)))
+ if (SUCCEEDED(psv->GetWindow(&hwndSV)))
SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
return S_OK;
}
@@ -1015,19 +1019,16 @@
CDefaultContextMenu::DoRefresh(
LPCMINVOKECOMMANDINFO lpcmi)
{
- CComPtr<IPersistFolder2> ppf2 = NULL;
- LPITEMIDLIST pidl;
- HRESULT hr = m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
- if (SUCCEEDED(hr))
- {
- hr = ppf2->GetCurFolder(&pidl);
- if (SUCCEEDED(hr))
- {
- SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, NULL);
- ILFree(pidl);
- }
- }
- return hr;
+ if (!m_site)
+ return E_FAIL;;
+
+ /* Get a pointer to the shell view */
+ CComPtr<IShellView> psv;
+ HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView,
&psv));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return psv->Refresh();
}
HRESULT
@@ -1208,69 +1209,44 @@
CComPtr<IDataObject> pDataObj;
HRESULT hr;
- if (SUCCEEDED(SHCreateDataObject(m_pidlFolder, m_cidl, m_apidl, NULL,
IID_PPV_ARG(IDataObject, &pDataObj))))
- {
- if (!bCopy)
- {
- FORMATETC formatetc;
- STGMEDIUM medium;
- InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT),
TYMED_HGLOBAL);
- pDataObj->GetData(&formatetc, &medium);
- DWORD * pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
- if (pdwFlag)
- *pdwFlag = DROPEFFECT_MOVE;
- GlobalUnlock(medium.hGlobal);
- pDataObj->SetData(&formatetc, &medium, TRUE);
- }
-
- hr = OleSetClipboard(pDataObj);
+ hr = SHCreateDataObject(m_pidlFolder, m_cidl, m_apidl, NULL, IID_PPV_ARG(IDataObject,
&pDataObj));
+ if(FAILED_UNEXPECTEDLY(hr))
return hr;
- }
-
- /* Note: CWM_GETISHELLBROWSER returns not referenced object */
- LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
- if (!lpSB)
- {
- ERR("failed to get shellbrowser\n");
- return E_FAIL;
- }
-
- CComPtr<IShellView> lpSV;
- hr = lpSB->QueryActiveShellView(&lpSV);
- if (FAILED(hr))
- {
- ERR("failed to query the active shellview\n");
- return hr;
- }
-
- hr = lpSV->GetItemObject(SVGIO_SELECTION, IID_PPV_ARG(IDataObject,
&pDataObj));
- if (SUCCEEDED(hr))
- {
- hr = OleSetClipboard(pDataObj);
- if (FAILED(hr))
- ERR("OleSetClipboard failed");
- pDataObj->Release();
- } else
- ERR("failed to get item object\n");
-
- return hr;
+
+ if (!bCopy)
+ {
+ FORMATETC formatetc;
+ STGMEDIUM medium;
+ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT),
TYMED_HGLOBAL);
+ pDataObj->GetData(&formatetc, &medium);
+ DWORD * pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
+ if (pdwFlag)
+ *pdwFlag = DROPEFFECT_MOVE;
+ GlobalUnlock(medium.hGlobal);
+ pDataObj->SetData(&formatetc, &medium, TRUE);
+ }
+
+ return OleSetClipboard(pDataObj);
}
HRESULT
CDefaultContextMenu::DoRename(
LPCMINVOKECOMMANDINFO lpcmi)
{
- /* get the active IShellView. Note: CWM_GETISHELLBROWSER returns not referenced
object */
- LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
- if (!lpSB)
- {
- ERR("CWM_GETISHELLBROWSER failed\n");
+ CComPtr<IShellBrowser> psb;
+ HRESULT hr;
+
+ if (!m_site)
return E_FAIL;
- }
+
+ /* Get a pointer to the shell browser */
+ hr = IUnknown_QueryService(m_site, SID_IShellBrowser, IID_PPV_ARG(IShellBrowser,
&psb));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
/* is the treeview focused */
HWND hwnd;
- if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwnd)))
+ if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwnd)))
{
HTREEITEM hItem = TreeView_GetSelection(hwnd);
if (hItem)
@@ -1278,12 +1254,9 @@
}
CComPtr<IShellView> lpSV;
- HRESULT hr = lpSB->QueryActiveShellView(&lpSV);
- if (FAILED(hr))
- {
- ERR("CWM_GETISHELLBROWSER failed\n");
+ hr = psb->QueryActiveShellView(&lpSV);
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- }
SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED
| SVSI_SELECT;
lpSV->SelectItem(m_apidl[0], selFlags);
@@ -1423,24 +1396,20 @@
return E_FAIL;
/* Show and select the new item in the def view */
- CComPtr<IShellBrowser> lpSB;
- CComPtr<IShellView> lpSV;
LPITEMIDLIST pidl;
PITEMID_CHILD pidlNewItem;
+ CComPtr<IShellView> psv;
/* Notify the view object about the new item */
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, (LPCVOID)wszName, NULL);
- /* FIXME: I think that this can be implemented using callbacks to the shell folder
*/
-
- /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */
- lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0);
- if (!lpSB)
- return E_FAIL;
-
- hr = lpSB->QueryActiveShellView(&lpSV);
- if (FAILED(hr))
- return hr;
+ if (!m_site)
+ return S_OK;
+
+ /* Get a pointer to the shell view */
+ hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView,
&psv));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return S_OK;
/* Attempt to get the pidl of the new item */
hr = SHILCreateFromPathW(wszName, &pidl, NULL);
@@ -1449,7 +1418,7 @@
pidlNewItem = ILFindLastID(pidl);
- hr = lpSV->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT |
SVSI_ENSUREVISIBLE |
+ hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT |
SVSI_ENSUREVISIBLE |
SVSI_FOCUSED | SVSI_SELECT);
SHFree(pidl);
@@ -1528,7 +1497,7 @@
DWORD
CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry
pEntry)
{
- LPSHELLBROWSER lpSB;
+ CComPtr<IShellBrowser> psb;
HWND hwndTree;
LPCWSTR FlagsName;
WCHAR wszKey[256];
@@ -1536,13 +1505,16 @@
DWORD wFlags;
DWORD cbVerb;
+ if (!m_site)
+ return 0;
+
/* Get a pointer to the shell browser */
- lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0);
- if (lpSB == NULL)
+ hr = IUnknown_QueryService(m_site, SID_IShellBrowser, IID_PPV_ARG(IShellBrowser,
&psb));
+ if (FAILED_UNEXPECTEDLY(hr))
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)
+ if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) &&
hwndTree)
FlagsName = L"ExplorerFlags";
else
FlagsName = L"BrowserFlags";
@@ -1565,15 +1537,18 @@
CDefaultContextMenu::TryToBrowse(
LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
{
- LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
+ CComPtr<IShellBrowser> psb;
HRESULT hr;
- if (lpSB == NULL)
+ if (!m_site)
return E_FAIL;
- hr = lpSB->BrowseObject(ILCombine(m_pidlFolder, pidl), wFlags);
-
- return hr;
+ /* Get a pointer to the shell browser */
+ hr = IUnknown_QueryService(m_site, SID_IShellBrowser, IID_PPV_ARG(IShellBrowser,
&psb));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return 0;
+
+ return psb->BrowseObject(ILCombine(m_pidlFolder, pidl), wFlags);
}
HRESULT
@@ -1865,42 +1840,29 @@
return S_OK;
}
+HRESULT
+WINAPI
+CDefaultContextMenu::SetSite(IUnknown *pUnkSite)
+{
+ m_site = pUnkSite;
+ return S_OK;
+}
+
+HRESULT
+WINAPI
+CDefaultContextMenu::GetSite(REFIID riid, void **ppvSite)
+{
+ if (!m_site)
+ return E_FAIL;
+
+ return m_site->QueryInterface(riid, ppvSite);
+}
+
static
HRESULT
-IDefaultContextMenu_Constructor(
- const DEFCONTEXTMENU *pdcm,
- REFIID riid,
- void **ppv)
-{
- if (ppv == NULL)
- return E_POINTER;
- *ppv = NULL;
-
- CComObject<CDefaultContextMenu> *pCM;
- HRESULT hr = CComObject<CDefaultContextMenu>::CreateInstance(&pCM);
- if (FAILED(hr))
- return hr;
- pCM->AddRef(); // CreateInstance returns object with 0 ref count */
-
- CComPtr<IUnknown> pResult;
- hr = pCM->QueryInterface(riid, (void **)&pResult);
- if (FAILED(hr))
- {
- pCM->Release();
- return hr;
- }
-
- hr = pCM->Initialize(pdcm);
- if (FAILED(hr))
- {
- pCM->Release();
- return hr;
- }
-
- *ppv = pResult.Detach();
- pCM->Release();
- TRACE("This(%p) cidl %u\n", *ppv, pdcm->cidl);
- return S_OK;
+CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
+{
+ return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, riid, ppv);
}
/*************************************************************************
@@ -1910,17 +1872,9 @@
HRESULT
WINAPI
-SHCreateDefaultContextMenu(
- const DEFCONTEXTMENU *pdcm,
- REFIID riid,
- void **ppv)
-{
- *ppv = NULL;
- HRESULT hr = IDefaultContextMenu_Constructor(pdcm, riid, ppv);
- if (FAILED(hr))
- ERR("IDefaultContextMenu_Constructor failed: %x\n", hr);
- TRACE("pcm %p hr %x\n", pdcm, hr);
- return hr;
+SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
+{
+ return CDefaultContextMenu_CreateInstance(pdcm, riid, ppv);
}
/*************************************************************************