Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367/* * 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 "shellmenu.h"#include <atlwin.h>#include <shlwapi_undoc.h>
#include "CMenuSite.h"
CMenuSite::CMenuSite() : m_DeskBarSite(NULL), m_BandObject(NULL), m_DeskBand(NULL), m_WinEventHandler(NULL), m_hWndBand(NULL){}
// Child Band management (simplified due to only supporting one single child)HRESULT STDMETHODCALLTYPE CMenuSite::AddBand(IUnknown * punk){ HRESULT hr;
// Little helper, for readability#define TO_HRESULT(x) ((HRESULT)(S_OK+(x)))
CComPtr<IUnknown> pUnknown;
punk->QueryInterface(IID_PPV_ARG(IUnknown, &pUnknown));
if (pUnknown == m_BandObject) return TO_HRESULT(0);
if (m_BandObject) { hr = IUnknown_SetSite(m_BandObject, NULL); if (FAILED_UNEXPECTEDLY(hr)) return hr; }
m_BandObject = NULL; m_DeskBand = NULL; m_WinEventHandler = NULL; m_hWndBand = NULL;
if (!pUnknown) return TO_HRESULT(0);
hr = pUnknown->QueryInterface(IID_PPV_ARG(IDeskBand, &m_DeskBand)); if (FAILED_UNEXPECTEDLY(hr)) return hr;
hr = pUnknown->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WinEventHandler)); if (FAILED_UNEXPECTEDLY(hr)) return hr;
hr = IUnknown_SetSite(pUnknown, this->ToIUnknown()); if (FAILED_UNEXPECTEDLY(hr)) return hr;
hr = IUnknown_GetWindow(pUnknown, &m_hWndBand); if (FAILED_UNEXPECTEDLY(hr)) return hr;
m_BandObject = pUnknown;
return TO_HRESULT(0);}
HRESULT STDMETHODCALLTYPE CMenuSite::EnumBands(UINT uBand, DWORD* pdwBandID){ if (uBand == UINT(-1)) return GetBandCount();
if (uBand != 0) return E_FAIL;
*pdwBandID = 0;
return S_OK;}
HRESULT STDMETHODCALLTYPE CMenuSite::GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv){ if (dwBandID != 0 || m_BandObject == NULL) { *ppv = NULL; return E_NOINTERFACE; }
return m_BandObject->QueryInterface(riid, ppv);}
HRESULT STDMETHODCALLTYPE CMenuSite::QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName){ if (dwBandID != 0) return E_FAIL;
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::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 }; info.dwMask = DBIM_MAXSIZE;
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){ if (!IsWindow()) return E_FAIL;
*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::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_NOINTERFACE;
return IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject); }
if (!m_DeskBarSite) return E_NOINTERFACE;
return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);}
HRESULT STDMETHODCALLTYPE CMenuSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut){ // Forward Exec calls directly to the parent deskbar return IUnknown_Exec(m_DeskBarSite, *pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);}
HRESULT STDMETHODCALLTYPE CMenuSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText){ // Forward QueryStatus calls directly to the parent deskbar return IUnknown_QueryStatus(m_DeskBarSite, *pguidCmdGroup, cCmds, prgCmds, pCmdText);}
HRESULT STDMETHODCALLTYPE CMenuSite::SetDeskBarSite(IUnknown *punkSite){ HRESULT hr;
CComPtr<IUnknown> protectThis(this->ToIUnknown());
// Only initialize if a parent site is being assigned if (punkSite) { HWND hWndSite;
m_DeskBarSite = NULL;
hr = IUnknown_GetWindow(punkSite, &hWndSite);
if (FAILED(hr) || !hWndSite) return E_FAIL;
if (!m_hWnd) { Create(hWndSite, NULL, L"MenuSite"); }
m_DeskBarSite = punkSite; } else { // Otherwise, deinitialize. if (m_DeskBand) { m_DeskBand->CloseDW(0); }
hr = IUnknown_SetSite(m_BandObject, NULL);
m_BandObject = NULL; m_DeskBand = NULL; m_WinEventHandler = NULL; m_hWndBand = NULL; if (m_hWnd) DestroyWindow(); m_DeskBarSite = NULL; }
return S_OK;}
HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateDBC(DWORD dwState){ if (!m_DeskBand) return S_OK;
return m_DeskBand->ShowDW(dwState != 0);}
HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateIO(BOOL fActivate, LPMSG lpMsg){ if (lpMsg) return E_FAIL;
return IUnknown_UIActivateIO(m_BandObject, fActivate, lpMsg);}
BOOL CMenuSite::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD mapId){ HWND hWndTarget = NULL; CComPtr<IUnknown> protectThis(this->ToIUnknown());
switch (uMsg) { case WM_SIZE: if (m_BandObject) { CComPtr<IMenuPopup> pMenuPopup; if (SUCCEEDED(m_BandObject->QueryInterface(IID_PPV_ARG(IMenuPopup, &pMenuPopup)))) { RECT Rect = { 0 }; GetClientRect(&Rect); pMenuPopup->OnPosRectChangeDB(&Rect); } } hWndTarget = hWnd; lResult = 1; break; case WM_NOTIFY: hWndTarget = reinterpret_cast<LPNMHDR>(lParam)->hwndFrom; break; case WM_COMMAND: hWndTarget = (HWND) lParam; break; default: return FALSE; }
if (hWndTarget && m_WinEventHandler && m_WinEventHandler->IsWindowOwner(hWndTarget) == S_OK) { if (SUCCEEDED(m_WinEventHandler->OnWinEvent(hWndTarget, uMsg, wParam, lParam, &lResult))) return TRUE; }
return FALSE;}
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;}
extern "C"HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv){ return ShellObjectCreator<CMenuSite>(riid, ppv);}