ReactOS 0.4.15-dev-7994-gb388cb6
CMenuSite.cpp
Go to the documentation of this file.
1/*
2 * Shell Menu Site
3 *
4 * Copyright 2014 David Quintana
5 *
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.
10 *
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.
15 *
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
19 */
20#include "shellmenu.h"
21#include <atlwin.h>
22#include <shlwapi_undoc.h>
23
24#include "CMenuSite.h"
25
27 m_DeskBarSite(NULL),
28 m_BandObject(NULL),
29 m_DeskBand(NULL),
30 m_WinEventHandler(NULL),
31 m_hWndBand(NULL)
32{
33}
34
35// Child Band management (simplified due to only supporting one single child)
37{
38 HRESULT hr;
39
40 // Little helper, for readability
41#define TO_HRESULT(x) ((HRESULT)(S_OK+(x)))
42
43 CComPtr<IUnknown> pUnknown;
44
46
48 return TO_HRESULT(0);
49
50 if (m_BandObject)
51 {
54 return hr;
55 }
56
61
62 if (!pUnknown)
63 return TO_HRESULT(0);
64
67 return hr;
68
71 return hr;
72
74 if (FAILED_UNEXPECTEDLY(hr))
75 return hr;
76
79 return hr;
80
82
83 return TO_HRESULT(0);
84}
85
87{
88 if (uBand != 0)
89 return E_FAIL;
90
91 *pdwBandID = 0;
92
93 return S_OK;
94}
95
97{
98 if (dwBandID != 0 || m_BandObject == NULL)
99 {
100 *ppv = NULL;
101 return E_NOINTERFACE;
102 }
103
104 return m_BandObject->QueryInterface(riid, ppv);
105}
106
108{
109 if (dwBandID != 0)
110 return E_FAIL;
111
112 if (!m_BandObject)
113 {
114 *ppstb = NULL;
115 return E_NOINTERFACE;
116 }
117
118 HRESULT hr = m_BandObject->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
119
120 *pdwState = 1;
121
122 if (cchName > 0)
123 pszName[0] = 0;
124
125 return hr;
126}
127
129{
130 memset(prc, 0, sizeof(*prc));
131
132 if (dwWhich != 0)
133 return S_OK;
134
135 if (m_DeskBand == NULL)
136 return S_OK;
137
138 DESKBANDINFO info = { 0 };
139 info.dwMask = DBIM_MAXSIZE;
140
141 m_DeskBand->GetBandInfo(0, 0, &info);
142
143 prc->right = info.ptMaxSize.x;
144 prc->bottom = info.ptMaxSize.y;
145
146 return S_OK;
147}
148
150{
151 if (!IsWindow())
152 return E_FAIL;
153
154 *phwnd = m_hWnd;
155
156 return S_OK;
157}
158
160{
161 if (hWnd == m_hWnd)
162 return S_OK;
163
165 return S_FALSE;
166
167 return m_WinEventHandler->IsWindowOwner(hWnd);
168}
169
171{
173 return S_OK;
174
175 return m_WinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
176}
177
179{
180 *ppvObject = NULL;
181
182 if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
183 IsEqualGUID(guidService, SID_SMenuBandBottomSelected) ||
184 IsEqualGUID(guidService, SID_SMenuBandChild))
185 {
186 if (m_BandObject == NULL)
187 return E_NOINTERFACE;
188
189 return IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject);
190 }
191
192 if (!m_DeskBarSite)
193 return E_NOINTERFACE;
194
195 return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);
196}
197
198HRESULT STDMETHODCALLTYPE CMenuSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
199{
200 // Forward Exec calls directly to the parent deskbar
201 return IUnknown_Exec(m_DeskBarSite, *pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
202}
203
204HRESULT STDMETHODCALLTYPE CMenuSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
205{
206 // Forward QueryStatus calls directly to the parent deskbar
207 return IUnknown_QueryStatus(m_DeskBarSite, *pguidCmdGroup, cCmds, prgCmds, pCmdText);
208}
209
211{
212 HRESULT hr;
213
214 CComPtr<IUnknown> protectThis(this->ToIUnknown());
215
216 // Only initialize if a parent site is being assigned
217 if (punkSite)
218 {
219 HWND hWndSite;
220
222
223 hr = IUnknown_GetWindow(punkSite, &hWndSite);
224
225 if (FAILED(hr) || !hWndSite)
226 return E_FAIL;
227
228 if (!m_hWnd)
229 {
230 Create(hWndSite, NULL, L"MenuSite");
231 }
232
233 m_DeskBarSite = punkSite;
234 }
235 else
236 {
237 // Otherwise, deinitialize.
238 if (m_DeskBand)
239 {
240 m_DeskBand->CloseDW(0);
241 }
242
244
249 if (m_hWnd)
252 }
253
254 return S_OK;
255}
256
258{
259 if (!m_DeskBand)
260 return S_OK;
261
262 return m_DeskBand->ShowDW(dwState != 0);
263}
264
266{
267 if (lpMsg)
268 return E_FAIL;
269
270 return IUnknown_UIActivateIO(m_BandObject, fActivate, lpMsg);
271}
272
274{
275 HWND hWndTarget = NULL;
276 CComPtr<IUnknown> protectThis(this->ToIUnknown());
277
278 switch (uMsg)
279 {
280 case WM_SIZE:
281 if (m_BandObject)
282 {
283 CComPtr<IMenuPopup> pMenuPopup;
284 if (SUCCEEDED(m_BandObject->QueryInterface(IID_PPV_ARG(IMenuPopup, &pMenuPopup))))
285 {
286 RECT Rect = { 0 };
288 pMenuPopup->OnPosRectChangeDB(&Rect);
289 }
290 }
291 hWndTarget = hWnd;
292 lResult = 1;
293 break;
294 case WM_NOTIFY:
295 hWndTarget = reinterpret_cast<LPNMHDR>(lParam)->hwndFrom;
296 break;
297 case WM_COMMAND:
298 hWndTarget = (HWND) lParam;
299 break;
300 default:
301 return FALSE;
302 }
303
304 if (hWndTarget && m_WinEventHandler &&
305 m_WinEventHandler->IsWindowOwner(hWndTarget) == S_OK)
306 {
307 if (SUCCEEDED(m_WinEventHandler->OnWinEvent(hWndTarget, uMsg, wParam, lParam, &lResult)))
308 return TRUE;
309 }
310
311 return FALSE;
312}
313
315{
316 return E_NOTIMPL;
317}
318
320{
321 return E_NOTIMPL;
322}
323
325{
326 return E_NOTIMPL;
327}
328
330{
331 return E_NOTIMPL;
332}
333
335{
336 return E_NOTIMPL;
337}
338
340{
341 return E_NOTIMPL;
342}
343
345{
346 return S_FALSE;
347}
348
350{
351 return S_FALSE;
352}
353
355{
356 return S_OK;
357}
358
359extern "C"
361{
362 return ShellObjectCreator<CMenuSite>(riid, ppv);
363}
#define TO_HRESULT(x)
HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv)
Definition: CMenuSite.cpp:360
HWND hWnd
Definition: settings.c:17
@ Create
Definition: registry.c:563
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
STDMETHOD() SetDeskBarSite(IUnknown *punkSite) override
Definition: CMenuSite.cpp:210
STDMETHOD() QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) override
Definition: CMenuSite.cpp:204
STDMETHOD() GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv) override
Definition: CMenuSite.cpp:96
STDMETHOD() QueryService(REFGUID guidService, REFIID riid, void **ppvObject) override
Definition: CMenuSite.cpp:178
STDMETHOD() ContextSensitiveHelp(BOOL fEnterMode) override
Definition: CMenuSite.cpp:314
STDMETHOD() GetSize(DWORD dwWhich, LPRECT prc) override
Definition: CMenuSite.cpp:128
STDMETHOD() OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) override
Definition: CMenuSite.cpp:170
STDMETHOD() HasFocusIO() override
Definition: CMenuSite.cpp:349
STDMETHOD() UIActivateIO(BOOL fActivate, LPMSG lpMsg) override
Definition: CMenuSite.cpp:265
STDMETHOD() SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState) override
Definition: CMenuSite.cpp:334
STDMETHOD() UIActivateDBC(DWORD dwState) override
Definition: CMenuSite.cpp:257
STDMETHOD() EnumBands(UINT uBand, DWORD *pdwBandID) override
Definition: CMenuSite.cpp:86
STDMETHOD() GetBandSiteInfo(BANDSITEINFO *pbsinfo) override
Definition: CMenuSite.cpp:319
virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD mapId=0)
Definition: CMenuSite.cpp:273
STDMETHOD() SetBandSiteInfo(const BANDSITEINFO *pbsinfo) override
Definition: CMenuSite.cpp:329
STDMETHOD() GetWindow(HWND *phwnd) override
Definition: CMenuSite.cpp:149
CComPtr< IDeskBand > m_DeskBand
Definition: CMenuSite.h:37
IUnknown * ToIUnknown()
Definition: CMenuSite.h:106
STDMETHOD() RemoveBand(DWORD dwBandID) override
Definition: CMenuSite.cpp:324
STDMETHOD() SetModeDBC(DWORD dwMode) override
Definition: CMenuSite.cpp:339
HWND m_hWndBand
Definition: CMenuSite.h:39
CComPtr< IUnknown > m_DeskBarSite
Definition: CMenuSite.h:35
STDMETHOD() QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName) override
Definition: CMenuSite.cpp:107
STDMETHOD() OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus) override
Definition: CMenuSite.cpp:354
STDMETHOD() AddBand(IUnknown *punk) override
Definition: CMenuSite.cpp:36
STDMETHOD() IsWindowOwner(HWND hWnd) override
Definition: CMenuSite.cpp:159
CComPtr< IUnknown > m_BandObject
Definition: CMenuSite.h:36
STDMETHOD() Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override
Definition: CMenuSite.cpp:198
STDMETHOD() TranslateAcceleratorIO(LPMSG lpMsg) override
Definition: CMenuSite.cpp:344
CComPtr< IWinEventHandler > m_WinEventHandler
Definition: CMenuSite.h:38
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HANDLE HWND
Definition: compat.h:19
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT WINAPI IUnknown_UIActivateIO(IUnknown *unknown, BOOL activate, LPMSG msg)
Definition: ordinal.c:1629
HRESULT WINAPI IUnknown_QueryStatus(IUnknown *lpUnknown, REFGUID pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
Definition: ordinal.c:1044
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
HRESULT WINAPI IUnknown_Exec(IUnknown *lpUnknown, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: ordinal.c:1083
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1332
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define L(x)
Definition: ntvdm.h:50
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define WM_NOTIFY
Definition: richedit.h:61
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
uint32_t ULONG
Definition: typedefs.h:59
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2767
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_SIZE
Definition: winuser.h:1611
#define WM_COMMAND
Definition: winuser.h:1740
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI DestroyWindow(_In_ HWND)
#define IID_PPV_ARG(Itype, ppType)
WCHAR * LPWSTR
Definition: xmlstorage.h:184