* 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);
+#include "CMenuSite.h"
-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);
-};
+WINE_DEFAULT_DEBUG_CHANNEL(menusite);
extern "C"
-HRESULT CMenuSite_Constructor(REFIID riid, LPVOID *ppv)
+HRESULT WINAPI CMenuSite_Constructor(REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
HRESULT hr = site->QueryInterface(riid, ppv);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
site->Release();
return hr;
HRESULT STDMETHODCALLTYPE CMenuSite::AddBand(IUnknown * punk)
{
- if (SHIsSameObject(punk, m_BandObject))
- return S_OK + 0;
+ HRESULT hr;
- IUnknown_SetSite(m_BandObject, NULL);
+#define TO_HRESULT(x) ((HRESULT)(S_OK+(x)))
- if (m_BandObject)
- {
- m_BandObject->Release();
- m_BandObject = NULL;
- }
+ CComPtr<IUnknown> pUnknown;
- if (m_DeskBand)
- {
- m_DeskBand->Release();
- m_DeskBand = NULL;
- }
+ punk->QueryInterface(IID_PPV_ARG(IUnknown, &pUnknown));
- if (m_WinEventHandler)
+ if (pUnknown == m_BandObject)
+ return TO_HRESULT(0);
+
+ if (m_BandObject)
{
- m_WinEventHandler->Release();
- m_WinEventHandler = NULL;
+ hr = IUnknown_SetSite(m_BandObject, NULL);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
}
- BOOL result = m_hWndBand != NULL;
-
+ m_BandObject = NULL;
+ m_DeskBand = NULL;
+ m_WinEventHandler = NULL;
m_hWndBand = NULL;
- if (!punk)
- return result ? S_OK + 0 : E_FAIL;
+ if (!pUnknown)
+ return TO_HRESULT(0);
+
+ hr = pUnknown->QueryInterface(IID_PPV_ARG(IDeskBand, &m_DeskBand));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- DBGASSERT(SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IDeskBand, &m_DeskBand))));
- DBGASSERT(SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WinEventHandler))));
+ hr = pUnknown->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WinEventHandler));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- IUnknown_SetSite(punk, (IDeskBarClient*)this);
- IUnknown_GetWindow(punk, &m_hWndBand);
+ hr = IUnknown_SetSite(pUnknown, this->ToIUnknown());
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- m_BandObject = punk;
+ hr = IUnknown_GetWindow(pUnknown, &m_hWndBand);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- punk->AddRef();
+ m_BandObject = pUnknown;
- return S_OK + 0;
+ return TO_HRESULT(0);
}
HRESULT STDMETHODCALLTYPE CMenuSite::EnumBands(UINT uBand, DWORD* pdwBandID)
HRESULT STDMETHODCALLTYPE CMenuSite::GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv)
{
- if (!DBGASSERT(dwBandID == 0) || m_BandObject == NULL)
+ if (dwBandID != 0 || m_BandObject == NULL)
{
*ppv = NULL;
return E_NOINTERFACE;
return S_OK;
DESKBANDINFO info = { 0 };
+ info.dwMask = DBIM_MAXSIZE;
m_DeskBand->GetBandInfo(0, 0, &info);
HRESULT STDMETHODCALLTYPE CMenuSite::GetWindow(HWND *phwnd)
{
- DBGASSERT(IsWindow());
+ if (!IsWindow())
+ return E_FAIL;
*phwnd = m_hWnd;
HRESULT STDMETHODCALLTYPE CMenuSite::QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
{
- DBGASSERT(dwBandID == 0);
- DBGASSERT(!IsBadWritePtr(ppstb, sizeof(*ppstb)));
+ if (dwBandID != 0)
+ return E_FAIL;
if (!m_BandObject)
{
IsEqualGUID(guidService, SID_SMenuBandChild))
{
if (m_BandObject == NULL)
- return E_FAIL;
+ return E_NOINTERFACE;
return IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject);
}
- DBGASSERT(m_DeskBarSite);
+ if (!m_DeskBarSite)
+ return E_NOINTERFACE;
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))
+ if (!m_DeskBarSite)
return E_FAIL;
+
return IUnknown_QueryStatus(m_DeskBarSite, *pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
HRESULT STDMETHODCALLTYPE CMenuSite::SetDeskBarSite(IUnknown *punkSite)
{
- HWND hWndSite;
+ HRESULT hr;
- ((IDeskBarClient*)this)->AddRef();
+ CComPtr<IUnknown> protectThis(this->ToIUnknown());
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);
- }
+ HWND hWndSite;
- IUnknown_SetSite(m_BandObject, NULL);
+ m_DeskBarSite = NULL;
- if (m_BandObject)
- {
- m_BandObject->Release();
- m_BandObject = NULL;
- }
+ hr = IUnknown_GetWindow(punkSite, &hWndSite);
- if (m_DeskBand)
- {
- m_DeskBand->Release();
- m_DeskBand = NULL;
- }
+ if (FAILED(hr) || !hWndSite)
+ return E_FAIL;
- if (m_WinEventHandler)
+ if (!m_hWnd)
{
- m_WinEventHandler->Release();
- m_WinEventHandler = NULL;
+ Create(hWndSite, NULL, L"MenuSite");
}
- m_hWndBand = NULL;
-
- if (m_hWnd)
- {
- DestroyWindow();
- m_hWnd = NULL;
- }
+ m_DeskBarSite = punkSite;
- if (m_DeskBarSite)
- m_DeskBarSite->Release();
+ return S_OK;
+ }
- m_DeskBarSite = NULL;
+ if (m_DeskBand)
+ {
+ m_DeskBand->CloseDW(0);
}
- ((IDeskBarClient*)this)->Release();
+ hr = IUnknown_SetSite(m_BandObject, NULL);
- if (!m_hWnd)
- return E_FAIL;
+ m_BandObject = NULL;
+ m_DeskBand = NULL;
+ m_WinEventHandler = NULL;
+ m_hWndBand = NULL;
+ m_hWnd = NULL;
+ m_DeskBarSite = NULL;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateDBC(DWORD dwState)
{
- if (!DBGASSERT(m_DeskBand))
+ if (!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))))
+ if (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();
+ 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);
+ Rect.right = Rect.right;
pMenuPopup->OnPosRectChangeDB(&Rect);
- pMenuPopup->Release();
}
}
- hWndToCall = hWnd;
+ hWndTarget = hWnd;
lResult = 1;
break;
case WM_NOTIFY:
- hWndToCall = *(HWND *) lParam;
+ hWndTarget = reinterpret_cast<LPNMHDR>(lParam)->hwndFrom;
break;
case WM_COMMAND:
- hWndToCall = (HWND) lParam;
+ hWndTarget = (HWND) lParam;
break;
default:
- ((IDeskBarClient*)this)->Release();
return FALSE;
}
- if (hWndToCall)
+ if (hWndTarget && m_WinEventHandler &&
+ m_WinEventHandler->IsWindowOwner(hWndTarget) == S_OK)
{
- 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;
- }
- }
+ if (SUCCEEDED(m_WinEventHandler->OnWinEvent(hWndTarget, uMsg, wParam, lParam, &lResult)))
+ return TRUE;
}
- ((IDeskBarClient*)this)->Release();
return FALSE;
}