[SHELL32] Remove unused debug channels and comment out unused variables. Silences...
[reactos.git] / dll / win32 / shell32 / shellmenu / CMenuSite.cpp
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
26 CMenuSite::CMenuSite() :
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)
36 HRESULT STDMETHODCALLTYPE CMenuSite::AddBand(IUnknown * punk)
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
45 punk->QueryInterface(IID_PPV_ARG(IUnknown, &pUnknown));
46
47 if (pUnknown == m_BandObject)
48 return TO_HRESULT(0);
49
50 if (m_BandObject)
51 {
52 hr = IUnknown_SetSite(m_BandObject, NULL);
53 if (FAILED_UNEXPECTEDLY(hr))
54 return hr;
55 }
56
57 m_BandObject = NULL;
58 m_DeskBand = NULL;
59 m_WinEventHandler = NULL;
60 m_hWndBand = NULL;
61
62 if (!pUnknown)
63 return TO_HRESULT(0);
64
65 hr = pUnknown->QueryInterface(IID_PPV_ARG(IDeskBand, &m_DeskBand));
66 if (FAILED_UNEXPECTEDLY(hr))
67 return hr;
68
69 hr = pUnknown->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_WinEventHandler));
70 if (FAILED_UNEXPECTEDLY(hr))
71 return hr;
72
73 hr = IUnknown_SetSite(pUnknown, this->ToIUnknown());
74 if (FAILED_UNEXPECTEDLY(hr))
75 return hr;
76
77 hr = IUnknown_GetWindow(pUnknown, &m_hWndBand);
78 if (FAILED_UNEXPECTEDLY(hr))
79 return hr;
80
81 m_BandObject = pUnknown;
82
83 return TO_HRESULT(0);
84 }
85
86 HRESULT STDMETHODCALLTYPE CMenuSite::EnumBands(UINT uBand, DWORD* pdwBandID)
87 {
88 if (uBand != 0)
89 return E_FAIL;
90
91 *pdwBandID = 0;
92
93 return S_OK;
94 }
95
96 HRESULT STDMETHODCALLTYPE CMenuSite::GetBandObject(DWORD dwBandID, REFIID riid, VOID **ppv)
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
107 HRESULT STDMETHODCALLTYPE CMenuSite::QueryBand(DWORD dwBandID, IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
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
128 HRESULT STDMETHODCALLTYPE CMenuSite::GetSize(DWORD dwWhich, LPRECT prc)
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
149 HRESULT STDMETHODCALLTYPE CMenuSite::GetWindow(HWND *phwnd)
150 {
151 if (!IsWindow())
152 return E_FAIL;
153
154 *phwnd = m_hWnd;
155
156 return S_OK;
157 }
158
159 HRESULT STDMETHODCALLTYPE CMenuSite::IsWindowOwner(HWND hWnd)
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
170 HRESULT STDMETHODCALLTYPE CMenuSite::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
171 {
172 if (!m_WinEventHandler)
173 return S_OK;
174
175 return m_WinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
176 }
177
178 HRESULT STDMETHODCALLTYPE CMenuSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
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
210 HRESULT STDMETHODCALLTYPE CMenuSite::SetDeskBarSite(IUnknown *punkSite)
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
221 m_DeskBarSite = NULL;
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
243 hr = IUnknown_SetSite(m_BandObject, NULL);
244
245 m_BandObject = NULL;
246 m_DeskBand = NULL;
247 m_WinEventHandler = NULL;
248 m_hWndBand = NULL;
249 m_hWnd = NULL;
250 m_DeskBarSite = NULL;
251 }
252
253 return S_OK;
254 }
255
256 HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateDBC(DWORD dwState)
257 {
258 if (!m_DeskBand)
259 return S_OK;
260
261 return m_DeskBand->ShowDW(dwState != 0);
262 }
263
264 HRESULT STDMETHODCALLTYPE CMenuSite::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
265 {
266 if (lpMsg)
267 return E_FAIL;
268
269 return IUnknown_UIActivateIO(m_BandObject, fActivate, lpMsg);
270 }
271
272 BOOL CMenuSite::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD mapId)
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 };
286 GetClientRect(&Rect);
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
313 HRESULT STDMETHODCALLTYPE CMenuSite::ContextSensitiveHelp(BOOL fEnterMode)
314 {
315 return E_NOTIMPL;
316 }
317
318 HRESULT STDMETHODCALLTYPE CMenuSite::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
319 {
320 return E_NOTIMPL;
321 }
322
323 HRESULT STDMETHODCALLTYPE CMenuSite::RemoveBand(DWORD dwBandID)
324 {
325 return E_NOTIMPL;
326 }
327
328 HRESULT STDMETHODCALLTYPE CMenuSite::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
329 {
330 return E_NOTIMPL;
331 }
332
333 HRESULT STDMETHODCALLTYPE CMenuSite::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
334 {
335 return E_NOTIMPL;
336 }
337
338 HRESULT STDMETHODCALLTYPE CMenuSite::SetModeDBC(DWORD dwMode)
339 {
340 return E_NOTIMPL;
341 }
342
343 HRESULT STDMETHODCALLTYPE CMenuSite::TranslateAcceleratorIO(LPMSG lpMsg)
344 {
345 return S_FALSE;
346 }
347
348 HRESULT STDMETHODCALLTYPE CMenuSite::HasFocusIO()
349 {
350 return S_FALSE;
351 }
352
353 HRESULT STDMETHODCALLTYPE CMenuSite::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
354 {
355 return S_OK;
356 }
357
358 extern "C"
359 HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv)
360 {
361 return ShellObjectCreator<CMenuSite>(riid, ppv);
362 }