ReactOS  0.4.13-dev-687-g023794c
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 
47  if (pUnknown == m_BandObject)
48  return TO_HRESULT(0);
49 
50  if (m_BandObject)
51  {
54  return hr;
55  }
56 
58  m_DeskBand = NULL;
60  m_hWndBand = NULL;
61 
62  if (!pUnknown)
63  return TO_HRESULT(0);
64 
67  return hr;
68 
69  hr = pUnknown->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WinEventHandler));
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 
164  if (!m_WinEventHandler)
165  return S_FALSE;
166 
167  return m_WinEventHandler->IsWindowOwner(hWnd);
168 }
169 
171 {
172  if (!m_WinEventHandler)
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 
198 HRESULT 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 
204 HRESULT 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 
245  m_BandObject = NULL;
246  m_DeskBand = NULL;
248  m_hWndBand = NULL;
249  m_hWnd = NULL;
251  }
252 
253  return S_OK;
254 }
255 
257 {
258  if (!m_DeskBand)
259  return S_OK;
260 
261  return m_DeskBand->ShowDW(dwState != 0);
262 }
263 
265 {
266  if (lpMsg)
267  return E_FAIL;
268 
269  return IUnknown_UIActivateIO(m_BandObject, fActivate, lpMsg);
270 }
271 
273 {
274  HWND hWndTarget = NULL;
275  CComPtr<IUnknown> protectThis(this->ToIUnknown());
276 
277  switch (uMsg)
278  {
279  case WM_SIZE:
280  if (m_BandObject)
281  {
282  CComPtr<IMenuPopup> pMenuPopup;
283  if (SUCCEEDED(m_BandObject->QueryInterface(IID_PPV_ARG(IMenuPopup, &pMenuPopup))))
284  {
285  RECT Rect = { 0 };
287  pMenuPopup->OnPosRectChangeDB(&Rect);
288  }
289  }
290  hWndTarget = hWnd;
291  lResult = 1;
292  break;
293  case WM_NOTIFY:
294  hWndTarget = reinterpret_cast<LPNMHDR>(lParam)->hwndFrom;
295  break;
296  case WM_COMMAND:
297  hWndTarget = (HWND) lParam;
298  break;
299  default:
300  return FALSE;
301  }
302 
303  if (hWndTarget && m_WinEventHandler &&
304  m_WinEventHandler->IsWindowOwner(hWndTarget) == S_OK)
305  {
306  if (SUCCEEDED(m_WinEventHandler->OnWinEvent(hWndTarget, uMsg, wParam, lParam, &lResult)))
307  return TRUE;
308  }
309 
310  return FALSE;
311 }
312 
314 {
315  return E_NOTIMPL;
316 }
317 
319 {
320  return E_NOTIMPL;
321 }
322 
324 {
325  return E_NOTIMPL;
326 }
327 
329 {
330  return E_NOTIMPL;
331 }
332 
334 {
335  return E_NOTIMPL;
336 }
337 
339 {
340  return E_NOTIMPL;
341 }
342 
344 {
345  return S_FALSE;
346 }
347 
349 {
350  return S_FALSE;
351 }
352 
354 {
355  return S_OK;
356 }
357 
358 extern "C"
360 {
361  return ShellObjectCreator<CMenuSite>(riid, ppv);
362 }
DBIM_BKCOLOR struct tagDESKBANDINFO DESKBANDINFO
HRESULT WINAPI IUnknown_UIActivateIO(IUnknown *unknown, BOOL activate, LPMSG msg)
Definition: ordinal.c:1580
virtual HRESULT STDMETHODCALLTYPE GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv)
Definition: CMenuSite.cpp:96
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
Definition: CMenuSite.cpp:178
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
BOOL WINAPI IsWindow(_In_opt_ HWND)
virtual HRESULT STDMETHODCALLTYPE HasFocusIO()
Definition: CMenuSite.cpp:348
REFIID riid
Definition: precomp.h:44
_In_ BOOLEAN Create
Definition: pstypes.h:511
CComPtr< IUnknown > m_BandObject
Definition: CMenuSite.h:36
CComPtr< IWinEventHandler > m_WinEventHandler
Definition: CMenuSite.h:38
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
Definition: CMenuSite.cpp:204
HWND hWnd
Definition: settings.c:17
REFIID LPVOID * ppv
Definition: atlbase.h:39
virtual HRESULT STDMETHODCALLTYPE SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
Definition: CMenuSite.cpp:333
HANDLE HWND
Definition: compat.h:13
UINT_PTR WPARAM
Definition: windef.h:207
#define TO_HRESULT(x)
LONG right
Definition: windef.h:293
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1283
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1448
WPARAM wParam
Definition: combotst.c:138
virtual HRESULT STDMETHODCALLTYPE AddBand(IUnknown *punk)
Definition: CMenuSite.cpp:36
virtual HRESULT STDMETHODCALLTYPE UIActivateDBC(DWORD dwState)
Definition: CMenuSite.cpp:256
virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd)
Definition: CMenuSite.cpp:159
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2706
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd)
Definition: CMenuSite.cpp:149
HWND m_hWndBand
Definition: CMenuSite.h:39
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1358
CComPtr< IUnknown > m_DeskBarSite
Definition: CMenuSite.h:35
virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
Definition: CMenuSite.cpp:353
#define S_FALSE
Definition: winerror.h:2357
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
virtual HRESULT STDMETHODCALLTYPE QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
Definition: CMenuSite.cpp:107
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
virtual HRESULT STDMETHODCALLTYPE GetBandSiteInfo(BANDSITEINFO *pbsinfo)
Definition: CMenuSite.cpp:318
#define WM_SIZE
Definition: winuser.h:1593
LONG HRESULT
Definition: typedefs.h:77
virtual HRESULT STDMETHODCALLTYPE SetModeDBC(DWORD dwMode)
Definition: CMenuSite.cpp:338
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:35
#define WINAPI
Definition: msvc.h:8
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg)
Definition: CMenuSite.cpp:264
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: CMenuSite.cpp:198
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg)
Definition: CMenuSite.cpp:343
CComPtr< IDeskBand > m_DeskBand
Definition: CMenuSite.h:37
static const WCHAR L[]
Definition: oid.c:1250
HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv)
Definition: CMenuSite.cpp:359
REFIID LPVOID * ppvObject
Definition: precomp.h:44
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
Definition: CMenuSite.cpp:313
virtual HRESULT STDMETHODCALLTYPE GetSize(DWORD dwWhich, LPRECT prc)
Definition: CMenuSite.cpp:128
#define WM_COMMAND
Definition: winuser.h:1722
IUnknown * ToIUnknown()
Definition: CMenuSite.h:107
virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
Definition: CMenuSite.cpp:170
virtual HRESULT STDMETHODCALLTYPE SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
Definition: CMenuSite.cpp:328
virtual HRESULT STDMETHODCALLTYPE EnumBands(UINT uBand, DWORD *pdwBandID)
Definition: CMenuSite.cpp:86
virtual HRESULT STDMETHODCALLTYPE RemoveBand(DWORD dwBandID)
Definition: CMenuSite.cpp:323
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define S_OK
Definition: intsafe.h:59
#define E_NOTIMPL
Definition: ddrawi.h:99
virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD mapId=0)
Definition: CMenuSite.cpp:272
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
unsigned int ULONG
Definition: retypes.h:1
LONG bottom
Definition: windef.h:294
HRESULT WINAPI IUnknown_QueryStatus(IUnknown *lpUnknown, REFGUID pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
Definition: ordinal.c:995
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define memset(x, y, z)
Definition: compat.h:39
virtual HRESULT STDMETHODCALLTYPE SetDeskBarSite(IUnknown *punkSite)
Definition: CMenuSite.cpp:210
LPARAM lParam
Definition: combotst.c:139
#define WM_NOTIFY
Definition: richedit.h:61
#define SUCCEEDED(hr)
Definition: intsafe.h:57
HRESULT WINAPI IUnknown_Exec(IUnknown *lpUnknown, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: ordinal.c:1034