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/CDefaultC... ============================================================================== --- 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@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); }
/*************************************************************************