Author: dquintana
Date: Wed Feb 12 16:35:29 2014
New Revision: 62131
URL:
http://svn.reactos.org/svn/reactos?rev=62131&view=rev
Log:
[RSHELL]
* Implement CMenuSite
CORE-7879
Added:
branches/shell-experiments/base/shell/rshell/CMenuSite.cpp (with props)
Modified:
branches/shell-experiments/base/shell/rshell/CMakeLists.txt
branches/shell-experiments/base/shell/rshell/CStartMenu.cpp
branches/shell-experiments/base/shell/rshell/precomp.h
Modified: branches/shell-experiments/base/shell/rshell/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMakeLists.txt [iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMakeLists.txt [iso-8859-1] Wed Feb 12
16:35:29 2014
@@ -9,6 +9,7 @@
list(APPEND SOURCE
CDesktopBrowser.cpp
CStartMenu.cpp
+ CMenuSite.cpp
misc.cpp
${CMAKE_CURRENT_BINARY_DIR}/rshell.def)
Added: branches/shell-experiments/base/shell/rshell/CMenuSite.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuSite.cpp (added)
+++ branches/shell-experiments/base/shell/rshell/CMenuSite.cpp [iso-8859-1] Wed Feb 12
16:35:29 2014
@@ -0,0 +1,498 @@
+/*
+ * Shell Menu Site
+ *
+ * Copyright 2014 David Quintana
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "precomp.h"
+#include <atlwin.h>
+#include <shlwapi_undoc.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(menusite);
+
+bool _assert(bool cond, LPCSTR expr, LPCSTR file, DWORD line, LPCSTR func)
+{
+#if DBG
+ if (!cond)
+ {
+ wine_dbg_printf("%s(%d): Assertion failed '%s', at %s", file,
line, expr, func);
+ DebugBreak();
+ }
+#endif
+ return cond;
+}
+#define DBGASSERT(x) _assert(!!(x), #x, __FILE__, __LINE__, __FUNCSIG__)
+
+class CMenuSite :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public CWindowImpl<CMenuSite, CWindow, CControlWinTraits>,
+ public IBandSite,
+ public IDeskBarClient,
+ public IOleCommandTarget,
+ public IInputObject,
+ public IInputObjectSite,
+ public IWinEventHandler,
+ public IServiceProvider
+{
+ IUnknown * m_DeskBarSite;
+ IUnknown * m_BandObject;
+ IDeskBand * m_DeskBand;
+ IWinEventHandler * m_WinEventHandler;
+ HWND m_hWndBand;
+
+public:
+ CMenuSite();
+ ~CMenuSite() {}
+
+ DECLARE_WND_CLASS_EX(_T("MenuSite"), 0, COLOR_WINDOW)
+
+ DECLARE_NOT_AGGREGATABLE(CMenuSite)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+ BEGIN_COM_MAP(CMenuSite)
+ COM_INTERFACE_ENTRY_IID(IID_IBandSite, IBandSite)
+ COM_INTERFACE_ENTRY_IID(IID_IDeskBarClient, IDeskBarClient)
+ COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
+ COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
+ COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
+ COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite)
+ COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
+ COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
+ END_COM_MAP()
+
+ virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
+ virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
+ virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL
fSetFocus);
+ virtual HRESULT STDMETHODCALLTYPE AddBand(IUnknown * punk);
+ virtual HRESULT STDMETHODCALLTYPE EnumBands(UINT uBand, DWORD* pdwBandID);
+ virtual HRESULT STDMETHODCALLTYPE Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
+ virtual HRESULT STDMETHODCALLTYPE GetBandObject(DWORD dwBandID, REFIID riid, VOID
**ppv);
+ virtual HRESULT STDMETHODCALLTYPE GetSize(DWORD dwWhich, LPRECT prc);
+ virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
+ virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd);
+ virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam, LRESULT *theResult);
+ virtual HRESULT STDMETHODCALLTYPE QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD
*pdwState, LPWSTR pszName, int cchName);
+ virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void
**ppvObject);
+ virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID * pguidCmdGroup, ULONG
cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
+ virtual HRESULT STDMETHODCALLTYPE SetDeskBarSite(IUnknown *punkSite);
+ virtual HRESULT STDMETHODCALLTYPE UIActivateDBC(DWORD dwState);
+ virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
+
+ // Using custom message map instead
+ virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT &lResult, DWORD mapId = 0);
+
+ // UNIMPLEMENTED
+ virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
+ virtual HRESULT STDMETHODCALLTYPE GetBandSiteInfo(BANDSITEINFO *pbsinfo);
+ virtual HRESULT STDMETHODCALLTYPE RemoveBand(DWORD dwBandID);
+ virtual HRESULT STDMETHODCALLTYPE SetBandSiteInfo(const BANDSITEINFO *pbsinfo);
+ virtual HRESULT STDMETHODCALLTYPE SetBandState(DWORD dwBandID, DWORD dwMask, DWORD
dwState);
+ virtual HRESULT STDMETHODCALLTYPE SetModeDBC(DWORD dwMode);
+
+private:
+ BOOL CreateSiteWindow(HWND hWndParent);
+};
+
+extern "C"
+HRESULT CMenuSite_Constructor(REFIID riid, LPVOID *ppv)
+{
+ *ppv = NULL;
+
+ CMenuSite * site = new CComObject<CMenuSite>();
+
+ if (!site)
+ return E_OUTOFMEMORY;
+
+ HRESULT hr = site->QueryInterface(riid, ppv);
+
+ if (FAILED(hr))
+ site->Release();
+
+ return hr;
+}
+
+CMenuSite::CMenuSite() :
+ m_DeskBarSite(NULL),
+ m_BandObject(NULL),
+ m_DeskBand(NULL),
+ m_WinEventHandler(NULL),
+ m_hWndBand(NULL)
+{
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::ContextSensitiveHelp(BOOL fEnterMode)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::RemoveBand(DWORD dwBandID)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD
dwState)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::SetModeDBC(DWORD dwMode)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::TranslateAcceleratorIO(LPMSG lpMsg)
+{
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::HasFocusIO()
+{
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::AddBand(IUnknown * punk)
+{
+ if (SHIsSameObject(punk, m_BandObject))
+ return S_OK + 0;
+
+ IUnknown_SetSite(m_BandObject, NULL);
+
+ if (m_BandObject)
+ {
+ m_BandObject->Release();
+ m_BandObject = NULL;
+ }
+
+ if (m_DeskBand)
+ {
+ m_DeskBand->Release();
+ m_DeskBand = NULL;
+ }
+
+ if (m_WinEventHandler)
+ {
+ m_WinEventHandler->Release();
+ m_WinEventHandler = NULL;
+ }
+
+ BOOL result = m_hWndBand != NULL;
+
+ m_hWndBand = NULL;
+
+ if (!punk)
+ return result ? S_OK + 0 : E_FAIL;
+
+ DBGASSERT(SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IDeskBand,
&m_DeskBand))));
+ DBGASSERT(SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IWinEventHandler,
&m_WinEventHandler))));
+
+ IUnknown_SetSite(punk, (IDeskBarClient*)this);
+ IUnknown_GetWindow(punk, &m_hWndBand);
+
+ m_BandObject = punk;
+
+ punk->AddRef();
+
+ return S_OK + 0;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::EnumBands(UINT uBand, DWORD* pdwBandID)
+{
+ if (uBand != 0)
+ return E_FAIL;
+
+ *pdwBandID = 0;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, DWORD
nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
+{
+ return IUnknown_Exec(m_DeskBarSite, *pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn,
pvaOut);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::GetBandObject(DWORD dwBandID, REFIID riid, VOID
**ppv)
+{
+ if (!DBGASSERT(dwBandID == 0) || m_BandObject == NULL)
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ return m_BandObject->QueryInterface(riid, ppv);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::GetSize(DWORD dwWhich, LPRECT prc)
+{
+ memset(prc, 0, sizeof(*prc));
+
+ if (dwWhich != 0)
+ return S_OK;
+
+ if (m_DeskBand == NULL)
+ return S_OK;
+
+ DESKBANDINFO info = { 0 };
+
+ m_DeskBand->GetBandInfo(0, 0, &info);
+
+ prc->right = info.ptMaxSize.x;
+ prc->bottom = info.ptMaxSize.y;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::GetWindow(HWND *phwnd)
+{
+ DBGASSERT(IsWindow());
+
+ *phwnd = m_hWnd;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::IsWindowOwner(HWND hWnd)
+{
+ if (hWnd == m_hWnd)
+ return S_OK;
+
+ if (!m_WinEventHandler)
+ return S_FALSE;
+
+ return m_WinEventHandler->IsWindowOwner(hWnd);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam, LRESULT *theResult)
+{
+ if (!m_WinEventHandler)
+ return S_OK;
+
+ return m_WinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD
*pdwState, LPWSTR pszName, int cchName)
+{
+ DBGASSERT(dwBandID == 0);
+ DBGASSERT(!IsBadWritePtr(ppstb, sizeof(*ppstb)));
+
+ if (!m_BandObject)
+ {
+ *ppstb = NULL;
+ return E_NOINTERFACE;
+ }
+
+ HRESULT hr = m_BandObject->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
+
+ *pdwState = 1;
+
+ if (cchName > 0)
+ pszName[0] = 0;
+
+ return hr;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::QueryService(REFGUID guidService, REFIID riid, void
**ppvObject)
+{
+ *ppvObject = NULL;
+
+ if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
+ IsEqualGUID(guidService, SID_SMenuBandBottomSelected) ||
+ IsEqualGUID(guidService, SID_SMenuBandChild))
+ {
+ if (m_BandObject == NULL)
+ return E_FAIL;
+
+ return IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject);
+ }
+
+ DBGASSERT(m_DeskBarSite);
+
+ return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
OLECMD prgCmds [], OLECMDTEXT *pCmdText)
+{
+ if (!DBGASSERT(m_DeskBarSite))
+ return E_FAIL;
+ return IUnknown_QueryStatus(m_DeskBarSite, *pguidCmdGroup, cCmds, prgCmds,
pCmdText);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::SetDeskBarSite(IUnknown *punkSite)
+{
+ HWND hWndSite;
+
+ ((IDeskBarClient*)this)->AddRef();
+
+ if (punkSite)
+ {
+ if (m_DeskBarSite)
+ {
+ m_DeskBarSite->Release();
+ m_DeskBarSite = NULL;
+ }
+
+ IUnknown_GetWindow(punkSite, &hWndSite);
+
+ if (hWndSite)
+ {
+ CreateSiteWindow(hWndSite);
+
+ m_DeskBarSite = punkSite;
+
+ punkSite->AddRef();
+ }
+ }
+ else
+ {
+ if (m_DeskBand)
+ {
+ m_DeskBand->CloseDW(0);
+ }
+
+ IUnknown_SetSite(m_BandObject, NULL);
+
+ if (m_BandObject)
+ {
+ m_BandObject->Release();
+ m_BandObject = NULL;
+ }
+
+ if (m_DeskBand)
+ {
+ m_DeskBand->Release();
+ m_DeskBand = NULL;
+ }
+
+ if (m_WinEventHandler)
+ {
+ m_WinEventHandler->Release();
+ m_WinEventHandler = NULL;
+ }
+
+ m_hWndBand = NULL;
+
+ if (m_hWnd)
+ {
+ DestroyWindow();
+ m_hWnd = NULL;
+ }
+
+ if (m_DeskBarSite)
+ m_DeskBarSite->Release();
+
+ m_DeskBarSite = NULL;
+ }
+
+ ((IDeskBarClient*)this)->Release();
+
+ if (!m_hWnd)
+ return E_FAIL;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateDBC(DWORD dwState)
+{
+ if (!DBGASSERT(m_DeskBand))
+ return S_OK;
+
+ return m_DeskBand->ShowDW(dwState != 0);
+}
+
+HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
+{
+ if (lpMsg && DBGASSERT(IsBadWritePtr(lpMsg, sizeof(*lpMsg))))
+ return E_FAIL;
+
+ return IUnknown_UIActivateIO(m_BandObject, fActivate, lpMsg);
+}
+
+BOOL CMenuSite::CreateSiteWindow(HWND hWndParent)
+{
+ if (m_hWnd)
+ {
+ return DBGASSERT(IsWindow());
+ }
+
+ Create(hWndParent, NULL, L"MenuSite");
+
+ return m_hWnd != NULL;
+}
+
+BOOL CMenuSite::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT &lResult, DWORD mapId)
+{
+ HWND hWndToCall;
+ IMenuPopup * pMenuPopup;
+
+ ((IDeskBarClient*)this)->AddRef();
+
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ if (m_BandObject)
+ {
+ if (SUCCEEDED(m_BandObject->QueryInterface(IID_PPV_ARG(IMenuPopup,
&pMenuPopup))))
+ {
+ RECT Rect = { 0 };
+ GetClientRect(&Rect);
+ pMenuPopup->OnPosRectChangeDB(&Rect);
+ pMenuPopup->Release();
+ }
+ }
+ hWndToCall = hWnd;
+ lResult = 1;
+ break;
+ case WM_NOTIFY:
+ hWndToCall = *(HWND *) lParam;
+ break;
+ case WM_COMMAND:
+ hWndToCall = (HWND) lParam;
+ break;
+ default:
+ ((IDeskBarClient*)this)->Release();
+ return FALSE;
+ }
+
+ if (hWndToCall)
+ {
+ if (m_WinEventHandler)
+ {
+ if (m_WinEventHandler->IsWindowOwner(hWndToCall) == S_OK)
+ {
+ HRESULT hr = m_WinEventHandler->OnWinEvent(hWndToCall, uMsg, wParam,
lParam, &lResult);
+ ((IDeskBarClient*)this)->Release();
+ return hr == S_OK;
+ }
+ }
+ }
+
+ ((IDeskBarClient*)this)->Release();
+ return FALSE;
+}
Propchange: branches/shell-experiments/base/shell/rshell/CMenuSite.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/shell-experiments/base/shell/rshell/CStartMenu.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CStartMenu.cpp [iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CStartMenu.cpp [iso-8859-1] Wed Feb 12
16:35:29 2014
@@ -266,7 +266,7 @@
if (FAILED(hr))
return NULL;
-#if 1
+#if 0
hr = CoCreateInstance(CLSID_MenuBandSite,
NULL,
CLSCTX_INPROC_SERVER,
Modified: branches/shell-experiments/base/shell/rshell/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/precomp.h [iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/precomp.h [iso-8859-1] Wed Feb 12
16:35:29 2014
@@ -29,3 +29,5 @@
#define shell32_hInstance 0
#define SMC_EXEC 4
extern "C" INT WINAPI Shell_GetCachedImageIndex(LPCWSTR szPath, INT nIndex,
UINT bSimulateDoc);
+
+extern "C" HRESULT CMenuSite_Constructor(REFIID riid, LPVOID *ppv);