[RSHELL]
[reactos.git] / base / shell / rshell / CMenuDeskBar.cpp
1 /*
2 * Shell Menu Desk Bar
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 "precomp.h"
21 #include "wraplog.h"
22 #include <atlwin.h>
23 #include <shlwapi_undoc.h>
24
25 WINE_DEFAULT_DEBUG_CHANNEL(CMenuDeskBar);
26
27 #define WRAP_LOG 0
28
29 typedef CWinTraits<
30 WS_POPUP | WS_DLGFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
31 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_PALETTEWINDOW
32 > CMenuWinTraits;
33
34 class CMenuDeskBar :
35 #if !WRAP_LOG
36 public CWindowImpl<CMenuDeskBar, CWindow, CMenuWinTraits>,
37 #endif
38 public CComCoClass<CMenuDeskBar>,
39 public CComObjectRootEx<CComMultiThreadModelNoCS>,
40 public IOleCommandTarget,
41 public IServiceProvider,
42 public IInputObjectSite,
43 public IInputObject,
44 public IMenuPopup,
45 public IObjectWithSite,
46 public IBanneredBar,
47 public IInitializeObject
48 {
49 public:
50 CMenuDeskBar();
51 ~CMenuDeskBar();
52
53 private:
54 #if WRAP_LOG
55 IUnknown * m_IUnknown;
56 IMenuPopup * m_IMenuPopup;
57 IOleCommandTarget * m_IOleCommandTarget;
58 IServiceProvider * m_IServiceProvider;
59 IDeskBar * m_IDeskBar;
60 IOleWindow * m_IOleWindow;
61 IInputObjectSite * m_IInputObjectSite;
62 IInputObject * m_IInputObject;
63 IObjectWithSite * m_IObjectWithSite;
64 IBanneredBar * m_IBanneredBar;
65 IInitializeObject * m_IInitializeObject;
66 #else
67
68 CComPtr<IUnknown> m_Site;
69 CComPtr<IUnknown> m_Client;
70 HWND m_ClientWindow;
71 bool m_Vertical;
72 bool m_Visible;
73 int m_NeededSize; // width or height
74
75 DWORD m_IconSize;
76 HBITMAP m_Banner;
77
78 // used by resize tracking loop
79 bool m_Tracking;
80 POINT m_LastLocation;
81 #endif
82
83 public:
84 // *** IMenuPopup methods ***
85 virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags);
86 virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType);
87 virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet);
88
89 // *** IOleWindow methods ***
90 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
91 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
92
93 // *** IObjectWithSite methods ***
94 virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
95 virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, PVOID *ppvSite);
96
97 // *** IBanneredBar methods ***
98 virtual HRESULT STDMETHODCALLTYPE SetIconSize(DWORD iIcon);
99 virtual HRESULT STDMETHODCALLTYPE GetIconSize(DWORD* piIcon);
100 virtual HRESULT STDMETHODCALLTYPE SetBitmap(HBITMAP hBitmap);
101 virtual HRESULT STDMETHODCALLTYPE GetBitmap(HBITMAP* phBitmap);
102
103 // *** IInitializeObject methods ***
104 virtual HRESULT STDMETHODCALLTYPE Initialize(THIS);
105
106 // *** IOleCommandTarget methods ***
107 virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
108 virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
109
110 // *** IServiceProvider methods ***
111 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
112
113 // *** IInputObjectSite methods ***
114 virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(LPUNKNOWN lpUnknown, BOOL bFocus);
115
116 // *** IInputObject methods ***
117 virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL bActivating, LPMSG lpMsg);
118 virtual HRESULT STDMETHODCALLTYPE HasFocusIO(THIS);
119 virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
120
121 // *** IDeskBar methods ***
122 virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient);
123 virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown **ppunkClient);
124 virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(LPRECT prc);
125
126 DECLARE_NOT_AGGREGATABLE(CMenuDeskBar)
127 DECLARE_PROTECT_FINAL_CONSTRUCT()
128
129 #if !WRAP_LOG
130 DECLARE_WND_CLASS_EX(_T("BaseBar"), CS_SAVEBITS | CS_DROPSHADOW, COLOR_3DFACE)
131
132 BEGIN_MSG_MAP(CMenuDeskBar)
133 MESSAGE_HANDLER(WM_SIZE, OnSize)
134 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
135 MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode)
136 MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
137 MESSAGE_HANDLER(WM_PAINT, OnPaint)
138 END_MSG_MAP()
139
140 // message handlers
141 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
142 LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
143 LRESULT OnCancelMode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
144 LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
145 LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
146
147 #endif
148
149 BEGIN_COM_MAP(CMenuDeskBar)
150 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup)
151 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
152 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
153 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite)
154 COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
155 COM_INTERFACE_ENTRY_IID(IID_IDeskBar, IMenuPopup)
156 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IMenuPopup)
157 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
158 COM_INTERFACE_ENTRY_IID(IID_IBanneredBar, IBanneredBar)
159 COM_INTERFACE_ENTRY_IID(IID_IInitializeObject, IInitializeObject)
160 END_COM_MAP()
161 };
162
163 extern "C"
164 HRESULT CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv)
165 {
166 *ppv = NULL;
167
168 CMenuDeskBar * deskbar = new CComObject<CMenuDeskBar>();
169
170 if (!deskbar)
171 return E_OUTOFMEMORY;
172
173 HRESULT hr = deskbar->QueryInterface(riid, ppv);
174
175 if (FAILED(hr))
176 deskbar->Release();
177
178 return hr;
179 }
180
181 #if WRAP_LOG
182 CMenuDeskBar::CMenuDeskBar()
183 {
184 HRESULT hr;
185 WrapLogOpen();
186
187 hr = CoCreateInstance(CLSID_MenuDeskBar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IMenuPopup, &m_IMenuPopup));
188 hr = m_IMenuPopup->QueryInterface(IID_PPV_ARG(IUnknown, &m_IUnknown));
189
190 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &m_IOleCommandTarget));
191 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IServiceProvider, &m_IServiceProvider));
192 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IDeskBar, &m_IDeskBar));
193 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IOleWindow, &m_IOleWindow));
194 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IInputObjectSite, &m_IInputObjectSite));
195 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IInputObject, &m_IInputObject));
196 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IObjectWithSite, &m_IObjectWithSite));
197 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IBanneredBar, &m_IBanneredBar));
198 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IInitializeObject, &m_IInitializeObject));
199 }
200
201 CMenuDeskBar::~CMenuDeskBar()
202 {
203 m_IUnknown->Release();
204 m_IMenuPopup->Release();
205 m_IOleCommandTarget->Release();
206 m_IServiceProvider->Release();
207 m_IDeskBar->Release();
208 m_IOleWindow->Release();
209 m_IInputObjectSite->Release();
210 m_IInputObject->Release();
211 m_IObjectWithSite->Release();
212 m_IBanneredBar->Release();
213 m_IInitializeObject->Release();
214
215 WrapLogClose();
216 }
217
218 // *** IMenuPopup methods ***
219 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
220 {
221 WrapLogEnter("CMenuDeskBar<%p>::Popup(POINTL *ppt=%p, RECTL *prcExclude=%p, MP_POPUPFLAGS dwFlags=%08x)\n", this, ppt, prcExclude, dwFlags);
222 HRESULT hr = m_IMenuPopup->Popup(ppt, prcExclude, dwFlags);
223 WrapLogExit("CMenuDeskBar::Popup() = %08x\n", hr);
224 return hr;
225 }
226
227 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
228 {
229 WrapLogEnter("CMenuDeskBar<%p>::OnSelect(DWORD dwSelectType=%08x)\n", this, dwSelectType);
230 HRESULT hr = m_IMenuPopup->OnSelect(dwSelectType);
231 WrapLogExit("CMenuDeskBar::OnSelect() = %08x\n", hr);
232 return hr;
233 }
234
235 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
236 {
237 WrapLogEnter("CMenuDeskBar<%p>::SetSubMenu(IMenuPopup *pmp=%p, BOOL fSet=%d)\n", this, pmp, fSet);
238 HRESULT hr = m_IMenuPopup->SetSubMenu(pmp, fSet);
239 WrapLogExit("CMenuDeskBar::SetSubMenu() = %08x\n", hr);
240 return hr;
241 }
242
243 // *** IOleWindow methods ***
244 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetWindow(HWND *phwnd)
245 {
246 WrapLogEnter("CMenuDeskBar<%p>::GetWindow(HWND *phwnd=%p)\n", this, phwnd);
247 HRESULT hr = m_IOleWindow->GetWindow(phwnd);
248 if (phwnd) WrapLogMsg("*phwnd=%p\n", *phwnd);
249 WrapLogExit("CMenuDeskBar::GetWindow() = %08x\n", hr);
250 return hr;
251 }
252
253 HRESULT STDMETHODCALLTYPE CMenuDeskBar::ContextSensitiveHelp(BOOL fEnterMode)
254 {
255 WrapLogEnter("CMenuDeskBar<%p>::ContextSensitiveHelp(BOOL fEnterMode=%d)\n", this, fEnterMode);
256 HRESULT hr = m_IOleWindow->ContextSensitiveHelp(fEnterMode);
257 WrapLogExit("CMenuDeskBar::ContextSensitiveHelp() = %08x\n", hr);
258 return hr;
259 }
260
261 // *** IObjectWithSite methods ***
262 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
263 {
264 WrapLogEnter("CMenuDeskBar<%p>::SetSite(IUnknown *pUnkSite=%p)\n", this, pUnkSite);
265 HRESULT hr = m_IObjectWithSite->SetSite(pUnkSite);
266 WrapLogExit("CMenuDeskBar::SetSite() = %08x\n", hr);
267 return hr;
268 }
269
270 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetSite(REFIID riid, PVOID *ppvSite)
271 {
272 WrapLogEnter("CMenuDeskBar<%p>::GetSite(REFIID riid=%s, PVOID *ppvSite=%p)\n", this, Wrap(riid), ppvSite);
273 HRESULT hr = m_IObjectWithSite->GetSite(riid, ppvSite);
274 if (ppvSite) WrapLogMsg("*ppvSite=%p\n", *ppvSite);
275 WrapLogExit("CMenuDeskBar::GetSite() = %08x\n", hr);
276 return hr;
277 }
278
279 // *** IBanneredBar methods ***
280 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetIconSize(DWORD iIcon)
281 {
282 WrapLogEnter("CMenuDeskBar<%p>::SetIconSize(DWORD iIcon=%d)\n", this, iIcon);
283 HRESULT hr = m_IBanneredBar->SetIconSize(iIcon);
284 WrapLogExit("CMenuDeskBar::SetIconSize() = %08x\n", hr);
285 return hr;
286 }
287
288 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetIconSize(DWORD* piIcon)
289 {
290 WrapLogEnter("CMenuDeskBar<%p>::GetIconSize(DWORD* piIcon=%p)\n", this, piIcon);
291 HRESULT hr = m_IBanneredBar->GetIconSize(piIcon);
292 if (piIcon) WrapLogMsg("*piIcon=%d\n", *piIcon);
293 WrapLogExit("CMenuDeskBar::GetIconSize() = %08x\n", hr);
294 return hr;
295 }
296
297 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetBitmap(HBITMAP hBitmap)
298 {
299 WrapLogEnter("CMenuDeskBar<%p>::SetBitmap(HBITMAP hBitmap=%p)\n", this, hBitmap);
300 HRESULT hr = m_IBanneredBar->SetBitmap(hBitmap);
301 WrapLogExit("CMenuDeskBar::SetBitmap() = %08x\n", hr);
302 return hr;
303 }
304
305 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetBitmap(HBITMAP* phBitmap)
306 {
307 WrapLogEnter("CMenuDeskBar<%p>::GetBitmap(HBITMAP* phBitmap=%p)\n", this, phBitmap);
308 HRESULT hr = m_IBanneredBar->GetBitmap(phBitmap);
309 if (phBitmap) WrapLogMsg("*phBitmap=%p\n", *phBitmap);
310 WrapLogExit("CMenuDeskBar::GetBitmap() = %08x\n", hr);
311 return hr;
312 }
313
314
315 // *** IInitializeObject methods ***
316 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
317 {
318 WrapLogEnter("CMenuDeskBar<%p>::Initialize()\n", this);
319 HRESULT hr = m_IInitializeObject->Initialize();
320 WrapLogExit("CMenuDeskBar::Initialize() = %08x\n", hr);
321 return hr;
322 }
323
324 // *** IOleCommandTarget methods ***
325 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
326 {
327 WrapLogEnter("CMenuDeskBar<%p>::QueryStatus(const GUID *pguidCmdGroup=%p, ULONG cCmds=%u, prgCmds=%p, pCmdText=%p)\n", this, pguidCmdGroup, cCmds, prgCmds, pCmdText);
328 HRESULT hr = m_IOleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
329 if (pguidCmdGroup) WrapLogMsg("*pguidCmdGroup=%s\n", Wrap(*pguidCmdGroup));
330 WrapLogExit("CMenuDeskBar::QueryStatus() = %08x\n", hr);
331 return hr;
332 }
333
334 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
335 {
336 //bool b;
337
338 WrapLogEnter("CMenuDeskBar<%p>::Exec(const GUID *pguidCmdGroup=%p, DWORD nCmdID=%d, DWORD nCmdexecopt=%d, VARIANT *pvaIn=%p, VARIANT *pvaOut=%p)\n", this, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
339
340 //if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
341 //{
342 // if (nCmdID == 19) // popup
343 // {
344 // b = true;
345 // }
346 //}
347
348
349 if (pguidCmdGroup) WrapLogMsg("*pguidCmdGroup=%s\n", Wrap(*pguidCmdGroup));
350 HRESULT hr = m_IOleCommandTarget->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
351 WrapLogExit("CMenuDeskBar::Exec() = %08x\n", hr);
352 return hr;
353 }
354
355 // *** IServiceProvider methods ***
356 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
357 {
358 WrapLogEnter("CMenuDeskBar<%p>::QueryService(REFGUID guidService=%s, REFIID riid=%s, void **ppvObject=%p)\n", this, Wrap(guidService), Wrap(riid), ppvObject);
359
360 //if (IsEqualIID(guidService, SID_SMenuBandChild))
361 //{
362 // WrapLogMsg("SID is SID_SMenuBandChild. Using QueryInterface of self instead of wrapped object.\n");
363 // HRESULT hr = this->QueryInterface(riid, ppvObject);
364 // if (ppvObject) WrapLogMsg("*ppvObject=%p\n", *ppvObject);
365 // WrapLogExit("CMenuDeskBar::QueryService() = %08x\n", hr);
366 // return hr;
367 //}
368 //else
369 {
370 WrapLogMsg("SID not identified.\n");
371 }
372 HRESULT hr = m_IServiceProvider->QueryService(guidService, riid, ppvObject);
373 if (ppvObject) WrapLogMsg("*ppvObject=%p\n", *ppvObject);
374 WrapLogExit("CMenuDeskBar::QueryService() = %08x\n", hr);
375 return hr;
376 }
377
378 // *** IInputObjectSite methods ***
379 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnFocusChangeIS(LPUNKNOWN lpUnknown, BOOL bFocus)
380 {
381 WrapLogEnter("CMenuDeskBar<%p>::OnFocusChangeIS(LPUNKNOWN lpUnknown=%p, BOOL bFocus=%d)\n", this, lpUnknown, bFocus);
382 HRESULT hr = m_IInputObjectSite->OnFocusChangeIS(lpUnknown, bFocus);
383 WrapLogExit("CMenuDeskBar::OnFocusChangeIS() = %08x\n", hr);
384 return hr;
385 }
386
387 // *** IInputObject methods ***
388 HRESULT STDMETHODCALLTYPE CMenuDeskBar::UIActivateIO(BOOL bActivating, LPMSG lpMsg)
389 {
390 WrapLogEnter("CMenuDeskBar<%p>::UIActivateIO(BOOL bActivating=%d, LPMSG lpMsg=%p)\n", this, bActivating, lpMsg);
391 HRESULT hr = m_IInputObject->UIActivateIO(bActivating, lpMsg);
392 WrapLogExit("CMenuDeskBar::UIActivateIO() = %08x\n", hr);
393 return hr;
394 }
395
396 HRESULT STDMETHODCALLTYPE CMenuDeskBar::HasFocusIO(THIS)
397 {
398 WrapLogEnter("CMenuDeskBar<%p>::HasFocusIO()\n", this);
399 HRESULT hr = m_IInputObject->HasFocusIO();
400 WrapLogExit("CMenuDeskBar::HasFocusIO() = %08x\n", hr);
401 return hr;
402 }
403
404 HRESULT STDMETHODCALLTYPE CMenuDeskBar::TranslateAcceleratorIO(LPMSG lpMsg)
405 {
406 WrapLogEnter("CMenuDeskBar<%p>::TranslateAcceleratorIO(LPMSG lpMsg=%p)\n", this, lpMsg);
407 if (lpMsg) WrapLogMsg("*lpMsg=%s\n", Wrap(*lpMsg));
408 HRESULT hr = m_IInputObject->TranslateAcceleratorIO(lpMsg);
409 WrapLogExit("CMenuDeskBar::TranslateAcceleratorIO() = %08x\n", hr);
410 return hr;
411 }
412
413 // *** IDeskBar methods ***
414 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
415 {
416 WrapLogEnter("CMenuDeskBar<%p>::SetClient(IUnknown *punkClient=%p)\n", this, punkClient);
417 HRESULT hr = m_IDeskBar->SetClient(punkClient);
418 WrapLogExit("CMenuDeskBar::SetClient() = %08x\n", hr);
419 return hr;
420 }
421
422 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetClient(IUnknown **ppunkClient)
423 {
424 WrapLogEnter("CMenuDeskBar<%p>::GetClient(IUnknown **ppunkClient=%p)\n", this, ppunkClient);
425 HRESULT hr = m_IDeskBar->GetClient(ppunkClient);
426 if (ppunkClient) WrapLogMsg("*ppunkClient=%p\n", *ppunkClient);
427 WrapLogExit("CMenuDeskBar::GetClient() = %08x\n", hr);
428 return hr;
429 }
430
431 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnPosRectChangeDB(LPRECT prc)
432 {
433 WrapLogEnter("CMenuDeskBar<%p>::OnPosRectChangeDB(RECT *prc=%p)\n", this, prc);
434 HRESULT hr = m_IDeskBar->OnPosRectChangeDB(prc);
435 if (prc) WrapLogMsg("*prc=%s\n", Wrap(*prc));
436 WrapLogExit("CMenuDeskBar::OnPosRectChangeDB() = %08x\n", hr);
437 return hr;
438 }
439 #else
440
441 CMenuDeskBar::CMenuDeskBar() :
442 m_Client(NULL),
443 m_ClientWindow(NULL),
444 m_Vertical(true),
445 m_Visible(false),
446 m_NeededSize(200),
447 m_Tracking(false),
448 m_Banner(NULL)
449 {
450 }
451
452 CMenuDeskBar::~CMenuDeskBar()
453 {
454 }
455
456 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetWindow(HWND *lphwnd)
457 {
458 if (lphwnd == NULL)
459 return E_POINTER;
460 *lphwnd = m_hWnd;
461 return S_OK;
462 }
463
464 HRESULT STDMETHODCALLTYPE CMenuDeskBar::ContextSensitiveHelp(BOOL fEnterMode)
465 {
466 return E_NOTIMPL;
467 }
468
469 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
470 {
471 CComPtr<IInputObjectSite> ios;
472
473 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObjectSite, &ios));
474 if (FAILED(hr))
475 return hr;
476
477 return ios->OnFocusChangeIS(punkObj, fSetFocus);
478 }
479
480 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
481 OLECMD prgCmds [], OLECMDTEXT *pCmdText)
482 {
483 return E_NOTIMPL;
484 }
485
486 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
487 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
488 {
489 if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
490 {
491 }
492 else if (IsEqualIID(*pguidCmdGroup, IID_IDeskBarClient))
493 {
494 switch (nCmdID)
495 {
496 case 0:
497 // hide current band
498 break;
499 case 2:
500 break;
501 case 3:
502 break;
503 }
504 }
505 return E_NOTIMPL;
506 }
507
508 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
509 {
510 if (m_Site == NULL)
511 return E_FAIL;
512
513 if (IsEqualGUID(guidService, SID_SMenuPopup))
514 {
515 return this->QueryInterface(riid, ppvObject);
516 }
517
518 return IUnknown_QueryService(m_Site, guidService, riid, ppvObject);
519 }
520
521 HRESULT STDMETHODCALLTYPE CMenuDeskBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
522 {
523 return IUnknown_UIActivateIO(m_Client, fActivate, lpMsg);
524 }
525
526 HRESULT STDMETHODCALLTYPE CMenuDeskBar::HasFocusIO()
527 {
528 CComPtr<IInputObject> io;
529
530 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObject, &io));
531 if (FAILED(hr))
532 return hr;
533
534 return io->HasFocusIO();
535 }
536
537 HRESULT STDMETHODCALLTYPE CMenuDeskBar::TranslateAcceleratorIO(LPMSG lpMsg)
538 {
539 CComPtr<IInputObject> io;
540
541 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObject, &io));
542 if (FAILED(hr))
543 return hr;
544
545 return io->TranslateAcceleratorIO(lpMsg);
546 }
547
548 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
549 {
550 CComPtr<IDeskBarClient> pDeskBandClient;
551 HRESULT hResult;
552
553 m_Client.Release();
554
555 if (punkClient == NULL)
556 return S_OK;
557
558 if (m_hWnd == NULL)
559 {
560 Create(NULL);
561 }
562
563 hResult = punkClient->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&m_Client));
564 if (FAILED(hResult))
565 return hResult;
566
567 hResult = m_Client->QueryInterface(IID_IDeskBarClient, (VOID**) &pDeskBandClient);
568 if (FAILED(hResult))
569 return hResult;
570
571 return pDeskBandClient->SetDeskBarSite(static_cast<IDeskBar*>(this));
572 }
573
574 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetClient(IUnknown **ppunkClient)
575 {
576 if (ppunkClient == NULL)
577 return E_POINTER;
578
579 if (!m_Client)
580 return E_FAIL;
581
582 return m_Client->QueryInterface(IID_PPV_ARG(IUnknown, ppunkClient));
583 }
584
585 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnPosRectChangeDB(LPRECT prc)
586 {
587 if (prc == NULL)
588 return E_POINTER;
589 return S_OK;
590 }
591
592 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
593 {
594 m_Site = pUnkSite;
595
596 return S_OK;
597 }
598
599 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetSite(REFIID riid, void **ppvSite)
600 {
601 if (m_Site == NULL)
602 return E_FAIL;
603
604 return m_Site->QueryInterface(riid, ppvSite);
605 }
606
607 LRESULT CMenuDeskBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
608 {
609 HRESULT hr;
610
611 if (m_Client)
612 {
613 CComPtr<IOleWindow> pOw;
614 hr = m_Client->QueryInterface(IID_PPV_ARG(IOleWindow, &pOw));
615 if (FAILED(hr))
616 {
617 ERR("IUnknown_QueryInterface pBs failed: %x\n", hr);
618 return 0;
619 }
620
621 HWND clientWnd;
622 pOw->GetWindow(&clientWnd);
623
624 RECT rc;
625
626 GetClientRect(&rc);
627
628 if (m_Banner != NULL)
629 {
630 BITMAP bm;
631 ::GetObject(m_Banner, sizeof(bm), &bm);
632 rc.left += bm.bmWidth;
633 }
634
635 ::SetWindowPos(clientWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 0);
636 }
637
638 return 0;
639 }
640
641 LRESULT CMenuDeskBar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
642 {
643 CComPtr<IWinEventHandler> winEventHandler;
644 LRESULT result;
645 HRESULT hResult;
646
647 result = 0;
648 if (m_Client.p != NULL)
649 {
650 hResult = m_Client->QueryInterface(IID_IWinEventHandler, reinterpret_cast<void **>(&winEventHandler));
651 if (SUCCEEDED(hResult) && winEventHandler.p != NULL)
652 hResult = winEventHandler->OnWinEvent(NULL, uMsg, wParam, lParam, &result);
653 }
654 return result;
655 }
656
657 LRESULT CMenuDeskBar::OnCancelMode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
658 {
659 m_Tracking = false;
660 return 0;
661 }
662
663 LRESULT CMenuDeskBar::OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
664 {
665 return 0;
666 }
667
668 LRESULT CMenuDeskBar::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
669 {
670 TRACE("OnPaint\n");
671
672 if (m_Banner && !m_IconSize)
673 {
674 BITMAP bm;
675 PAINTSTRUCT ps;
676 HDC hdc = BeginPaint(&ps);
677
678 HDC hdcMem = ::CreateCompatibleDC(hdc);
679 HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_Banner);
680
681 ::GetObject(m_Banner, sizeof(bm), &bm);
682
683 RECT rc;
684 if (!GetClientRect(&rc))
685 WARN("GetClientRect failed\n");
686
687 const int bx = bm.bmWidth;
688 const int by = bm.bmHeight;
689 const int cx = rc.right;
690 const int cy = rc.bottom;
691
692 TRACE("Painting banner: %d by %d\n", bm.bmWidth, bm.bmHeight);
693
694 if (!::StretchBlt(hdc, 0, 0, bx, cy - by, hdcMem, 0, 0, bx, 1, SRCCOPY))
695 WARN("StretchBlt failed\n");
696
697 if (!::BitBlt(hdc, 0, cy - by, bx, by, hdcMem, 0, 0, SRCCOPY))
698 WARN("BitBlt failed\n");
699
700 ::SelectObject(hdcMem, hbmOld);
701 ::DeleteDC(hdcMem);
702
703 EndPaint(&ps);
704 }
705
706 return 0;
707 }
708
709 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
710 {
711 HRESULT hr;
712 CComPtr<IOleCommandTarget> oct;
713 CComPtr<IInputObject> io;
714 CComPtr<IDeskBand> band;
715 CComPtr<IDeskBarClient> dbc;
716
717 if (m_hWnd == NULL)
718 return E_FAIL;
719
720 hr = IUnknown_QueryService(m_Client, SID_SMenuBandChild, IID_PPV_ARG(IOleCommandTarget, &oct));
721 if (FAILED(hr))
722 return hr;
723
724 hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
725 if (FAILED(hr))
726 return hr;
727
728 // No clue about the arg, using anything != 0
729 hr = dbc->UIActivateDBC(TRUE);
730 if (FAILED(hr))
731 return hr;
732
733 RECT rc = { 0 };
734 hr = dbc->GetSize(0, &rc);
735 if (FAILED(hr))
736 return hr;
737
738 // Unknown meaning
739 const int CMD = 19;
740 const int CMD_EXEC_OPT = 0;
741
742 hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
743 if (FAILED(hr))
744 return hr;
745
746 ::AdjustWindowRect(&rc, ::GetWindowLong(m_hWnd, GWL_STYLE), FALSE);
747 rc.right -= rc.left;
748 rc.bottom -= rc.top;
749
750 if (m_Banner != NULL)
751 {
752 BITMAP bm;
753 ::GetObject(m_Banner, sizeof(bm), &bm);
754 rc.right += bm.bmWidth;
755 }
756
757 int x = ppt->x;
758 int y = ppt->y - rc.bottom;
759 int cx = rc.right;
760 int cy = rc.bottom;
761
762 if (y < 0)
763 {
764 y = 0;
765 }
766
767 // if (y+cy > work area height) cy = work area height - y
768
769 this->SetWindowPos(HWND_TOPMOST, x, y, cx, cy, SWP_SHOWWINDOW);
770
771 // HACK: The bar needs to be notified of the size AFTER it is shown.
772 // Quick & dirty way of getting it done.
773 BOOL bHandled;
774 OnSize(WM_SIZE, 0, 0, bHandled);
775
776 UIActivateIO(TRUE, NULL);
777
778 return S_OK;
779 }
780
781 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetIconSize(THIS_ DWORD iIcon)
782 {
783 HRESULT hr;
784 m_IconSize = iIcon;
785
786 // Unknown meaning (set flags? set icon size?)
787 const int CMD = 16;
788 const int CMD_EXEC_OPT = iIcon ? 0 : 2; // seems to work
789
790 hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
791 if (FAILED(hr))
792 return hr;
793
794 BOOL bHandled;
795 OnSize(WM_SIZE, 0, 0, bHandled);
796
797 return hr;
798 }
799
800 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetIconSize(THIS_ DWORD* piIcon)
801 {
802 if (piIcon)
803 *piIcon = m_IconSize;
804 return S_OK;
805 }
806
807 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetBitmap(THIS_ HBITMAP hBitmap)
808 {
809 m_Banner = hBitmap;
810
811 BOOL bHandled;
812 OnSize(WM_SIZE, 0, 0, bHandled);
813
814 return S_OK;
815 }
816
817 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetBitmap(THIS_ HBITMAP* phBitmap)
818 {
819 if (phBitmap)
820 *phBitmap = m_Banner;
821 return S_OK;
822 }
823
824 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(
825 DWORD dwSelectType)
826 {
827 if (dwSelectType == MPOS_FULLCANCEL)
828 {
829 CComPtr<IDeskBarClient> dbc;
830
831 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
832 if (FAILED(hr))
833 return hr;
834
835 hr = dbc->UIActivateDBC(FALSE);
836 if (FAILED(hr))
837 return hr;
838
839 SetWindowPos(m_hWnd, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
840
841 UIActivateIO(FALSE, NULL);
842 }
843
844 return S_OK;
845 }
846
847 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(
848 IMenuPopup *pmp,
849 BOOL fSet)
850 {
851 return S_OK;
852 }
853
854 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
855 {
856 return S_OK;
857 }
858
859 #endif