4 * Copyright 2014 David Quintana
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <shlwapi_undoc.h>
24 #include "CMenuSite.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(menusite
);
29 HRESULT WINAPI
CMenuSite_Constructor(REFIID riid
, LPVOID
*ppv
)
32 #if USE_SYSTEM_MENUSITE
33 hr
= CoCreateInstance(CLSID_MenuBandSite
,
40 CMenuSite
* site
= new CComObject
<CMenuSite
>();
45 hr
= site
->QueryInterface(riid
, ppv
);
47 if (FAILED_UNEXPECTEDLY(hr
))
54 CMenuSite::CMenuSite() :
58 m_WinEventHandler(NULL
),
63 HRESULT STDMETHODCALLTYPE
CMenuSite::ContextSensitiveHelp(BOOL fEnterMode
)
68 HRESULT STDMETHODCALLTYPE
CMenuSite::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
73 HRESULT STDMETHODCALLTYPE
CMenuSite::RemoveBand(DWORD dwBandID
)
78 HRESULT STDMETHODCALLTYPE
CMenuSite::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
83 HRESULT STDMETHODCALLTYPE
CMenuSite::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
88 HRESULT STDMETHODCALLTYPE
CMenuSite::SetModeDBC(DWORD dwMode
)
93 HRESULT STDMETHODCALLTYPE
CMenuSite::TranslateAcceleratorIO(LPMSG lpMsg
)
98 HRESULT STDMETHODCALLTYPE
CMenuSite::HasFocusIO()
103 HRESULT STDMETHODCALLTYPE
CMenuSite::OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
)
108 HRESULT STDMETHODCALLTYPE
CMenuSite::AddBand(IUnknown
* punk
)
112 #define TO_HRESULT(x) ((HRESULT)(S_OK+(x)))
114 CComPtr
<IUnknown
> pUnknown
;
116 punk
->QueryInterface(IID_PPV_ARG(IUnknown
, &pUnknown
));
118 if (pUnknown
== m_BandObject
)
119 return TO_HRESULT(0);
123 hr
= IUnknown_SetSite(m_BandObject
, NULL
);
124 if (FAILED_UNEXPECTEDLY(hr
))
130 m_WinEventHandler
= NULL
;
134 return TO_HRESULT(0);
136 hr
= pUnknown
->QueryInterface(IID_PPV_ARG(IDeskBand
, &m_DeskBand
));
137 if (FAILED_UNEXPECTEDLY(hr
))
140 hr
= pUnknown
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &m_WinEventHandler
));
141 if (FAILED_UNEXPECTEDLY(hr
))
144 hr
= IUnknown_SetSite(pUnknown
, this->ToIUnknown());
145 if (FAILED_UNEXPECTEDLY(hr
))
148 hr
= IUnknown_GetWindow(pUnknown
, &m_hWndBand
);
149 if (FAILED_UNEXPECTEDLY(hr
))
152 m_BandObject
= pUnknown
;
154 return TO_HRESULT(0);
157 HRESULT STDMETHODCALLTYPE
CMenuSite::EnumBands(UINT uBand
, DWORD
* pdwBandID
)
167 HRESULT STDMETHODCALLTYPE
CMenuSite::Exec(const GUID
* pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
169 return IUnknown_Exec(m_DeskBarSite
, *pguidCmdGroup
, nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
172 HRESULT STDMETHODCALLTYPE
CMenuSite::GetBandObject(DWORD dwBandID
, REFIID riid
, VOID
**ppv
)
174 if (dwBandID
!= 0 || m_BandObject
== NULL
)
177 return E_NOINTERFACE
;
180 return m_BandObject
->QueryInterface(riid
, ppv
);
183 HRESULT STDMETHODCALLTYPE
CMenuSite::GetSize(DWORD dwWhich
, LPRECT prc
)
185 memset(prc
, 0, sizeof(*prc
));
190 if (m_DeskBand
== NULL
)
193 DESKBANDINFO info
= { 0 };
194 info
.dwMask
= DBIM_MAXSIZE
;
196 m_DeskBand
->GetBandInfo(0, 0, &info
);
198 prc
->right
= info
.ptMaxSize
.x
;
199 prc
->bottom
= info
.ptMaxSize
.y
;
204 HRESULT STDMETHODCALLTYPE
CMenuSite::GetWindow(HWND
*phwnd
)
214 HRESULT STDMETHODCALLTYPE
CMenuSite::IsWindowOwner(HWND hWnd
)
219 if (!m_WinEventHandler
)
222 return m_WinEventHandler
->IsWindowOwner(hWnd
);
225 HRESULT STDMETHODCALLTYPE
CMenuSite::OnWinEvent(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
227 if (!m_WinEventHandler
)
230 return m_WinEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
233 HRESULT STDMETHODCALLTYPE
CMenuSite::QueryBand(DWORD dwBandID
, IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
241 return E_NOINTERFACE
;
244 HRESULT hr
= m_BandObject
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
254 HRESULT STDMETHODCALLTYPE
CMenuSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
258 if (IsEqualGUID(guidService
, SID_SMenuBandBottom
) ||
259 IsEqualGUID(guidService
, SID_SMenuBandBottomSelected
) ||
260 IsEqualGUID(guidService
, SID_SMenuBandChild
))
262 if (m_BandObject
== NULL
)
263 return E_NOINTERFACE
;
265 return IUnknown_QueryService(m_BandObject
, guidService
, riid
, ppvObject
);
269 return E_NOINTERFACE
;
271 return IUnknown_QueryService(m_DeskBarSite
, guidService
, riid
, ppvObject
);
274 HRESULT STDMETHODCALLTYPE
CMenuSite::QueryStatus(const GUID
* pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
279 return IUnknown_QueryStatus(m_DeskBarSite
, *pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
282 HRESULT STDMETHODCALLTYPE
CMenuSite::SetDeskBarSite(IUnknown
*punkSite
)
286 CComPtr
<IUnknown
> protectThis(this->ToIUnknown());
292 m_DeskBarSite
= NULL
;
294 hr
= IUnknown_GetWindow(punkSite
, &hWndSite
);
296 if (FAILED(hr
) || !hWndSite
)
301 Create(hWndSite
, NULL
, L
"MenuSite");
304 m_DeskBarSite
= punkSite
;
311 m_DeskBand
->CloseDW(0);
314 hr
= IUnknown_SetSite(m_BandObject
, NULL
);
318 m_WinEventHandler
= NULL
;
321 m_DeskBarSite
= NULL
;
326 HRESULT STDMETHODCALLTYPE
CMenuSite::UIActivateDBC(DWORD dwState
)
331 return m_DeskBand
->ShowDW(dwState
!= 0);
334 HRESULT STDMETHODCALLTYPE
CMenuSite::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
339 return IUnknown_UIActivateIO(m_BandObject
, fActivate
, lpMsg
);
342 BOOL
CMenuSite::ProcessWindowMessage(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
&lResult
, DWORD mapId
)
344 HWND hWndTarget
= NULL
;
345 CComPtr
<IUnknown
> protectThis(this->ToIUnknown());
352 CComPtr
<IMenuPopup
> pMenuPopup
;
353 if (SUCCEEDED(m_BandObject
->QueryInterface(IID_PPV_ARG(IMenuPopup
, &pMenuPopup
))))
356 GetClientRect(&Rect
);
357 Rect
.right
= Rect
.right
;
358 pMenuPopup
->OnPosRectChangeDB(&Rect
);
365 hWndTarget
= reinterpret_cast<LPNMHDR
>(lParam
)->hwndFrom
;
368 hWndTarget
= (HWND
) lParam
;
374 if (hWndTarget
&& m_WinEventHandler
&&
375 m_WinEventHandler
->IsWindowOwner(hWndTarget
) == S_OK
)
377 if (SUCCEEDED(m_WinEventHandler
->OnWinEvent(hWndTarget
, uMsg
, wParam
, lParam
, &lResult
)))