1 /*
2 * Shell Menu Band
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 <windowsx.h>
22 #include <commoncontrols.h>
23 #include <shlwapi_undoc.h>
24
25 #include "CMenuBand.h"
26 #include "CMenuToolbars.h"
27 #include "CMenuFocusManager.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand);
30
31 #undef UNIMPLEMENTED
32
33 #define UNIMPLEMENTED TRACE("%s is UNIMPLEMENTED!\n", __FUNCTION__)
34
CMenuBand()35 CMenuBand::CMenuBand() :
36 m_staticToolbar(NULL),
37 m_SFToolbar(NULL),
38 m_site(NULL),
39 m_psmc(NULL),
40 m_subMenuChild(NULL),
41 m_subMenuParent(NULL),
42 m_childBand(NULL),
43 m_parentBand(NULL),
44 m_hmenu(NULL),
45 m_menuOwner(NULL),
46 m_useBigIcons(FALSE),
47 m_topLevelWindow(NULL),
48 m_hotBar(NULL),
49 m_hotItem(-1),
50 m_popupBar(NULL),
51 m_popupItem(-1),
52 m_Show(FALSE),
53 m_shellBottom(FALSE),
54 m_trackedPopup(NULL),
55 m_trackedHwnd(NULL)
56 {
57 m_focusManager = CMenuFocusManager::AcquireManager();
58 }
59
~CMenuBand()60 CMenuBand::~CMenuBand()
61 {
62 CMenuFocusManager::ReleaseManager(m_focusManager);
63
64 delete m_staticToolbar;
65 delete m_SFToolbar;
66
67 if (m_hmenu)
68 DestroyMenu(m_hmenu);
69 }
70
Initialize(IShellMenuCallback * psmc,UINT uId,UINT uIdAncestor,DWORD dwFlags)71 HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
72 IShellMenuCallback *psmc,
73 UINT uId,
74 UINT uIdAncestor,
75 DWORD dwFlags)
76 {
77 if (m_psmc != psmc)
78 m_psmc = psmc;
79 m_uId = uId;
80 m_uIdAncestor = uIdAncestor;
81 m_dwFlags = dwFlags;
82
83 if (m_psmc)
84 {
85 _CallCB(SMC_CREATE, 0, reinterpret_cast<LPARAM>(&m_UserData));
86 }
87
88 return S_OK;
89 }
90
GetMenuInfo(IShellMenuCallback ** ppsmc,UINT * puId,UINT * puIdAncestor,DWORD * pdwFlags)91 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
92 IShellMenuCallback **ppsmc,
93 UINT *puId,
94 UINT *puIdAncestor,
95 DWORD *pdwFlags)
96 {
97 if (!pdwFlags) // maybe?
98 return E_INVALIDARG;
99
100 if (ppsmc)
101 {
102 *ppsmc = m_psmc;
103 if (*ppsmc)
104 (*ppsmc)->AddRef();
105 }
106
107 if (puId)
108 *puId = m_uId;
109
110 if (puIdAncestor)
111 *puIdAncestor = m_uIdAncestor;
112
113 *pdwFlags = m_dwFlags;
114
115 return S_OK;
116 }
117
SetMenu(HMENU hmenu,HWND hwnd,DWORD dwFlags)118 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(
119 HMENU hmenu,
120 HWND hwnd,
121 DWORD dwFlags)
122 {
123 HRESULT hr;
124
125 TRACE("CMenuBand::SetMenu called, hmenu=%p; hwnd=%p, flags=%x\n", hmenu, hwnd, dwFlags);
126
127 BOOL created = FALSE;
128
129 if (m_hmenu && m_hmenu != hmenu)
130 {
131 DestroyMenu(m_hmenu);
132 m_hmenu = NULL;
133 }
134
135 m_hmenu = hmenu;
136 m_menuOwner = hwnd;
137
138 if (m_hmenu && m_staticToolbar == NULL)
139 {
140 m_staticToolbar = new CMenuStaticToolbar(this);
141 created = true;
142 }
143
144 if (m_staticToolbar)
145 {
146 hr = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
147 if (FAILED_UNEXPECTEDLY(hr))
148 return hr;
149 }
150
151 if (m_site)
152 {
153 HWND hwndParent;
154
155 hr = m_site->GetWindow(&hwndParent);
156 if (FAILED_UNEXPECTEDLY(hr))
157 return hr;
158
159 if (created)
160 {
161 hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
162 if (FAILED_UNEXPECTEDLY(hr))
163 return hr;
164
165 hr = m_staticToolbar->FillToolbar();
166 }
167 else
168 {
169 hr = m_staticToolbar->FillToolbar(TRUE);
170 }
171 }
172
173 return hr;
174 }
175
GetMenu(HMENU * phmenu,HWND * phwnd,DWORD * pdwFlags)176 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(
177 HMENU *phmenu,
178 HWND *phwnd,
179 DWORD *pdwFlags)
180 {
181 if (m_staticToolbar == NULL)
182 return E_FAIL;
183
184 return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags);
185 }
186
SetSite(IUnknown * pUnkSite)187 HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
188 {
189 HWND hwndParent;
190 HRESULT hr;
191
192 m_site = NULL;
193
194 if (pUnkSite == NULL)
195 return S_OK;
196
197 hwndParent = NULL;
198 hr = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
199 if (FAILED_UNEXPECTEDLY(hr))
200 return hr;
201
202 hr = m_site->GetWindow(&hwndParent);
203 if (FAILED_UNEXPECTEDLY(hr))
204 return hr;
205
206 if (!::IsWindow(hwndParent))
207 return E_FAIL;
208
209 if (m_staticToolbar != NULL)
210 {
211 hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
212 if (FAILED_UNEXPECTEDLY(hr))
213 return hr;
214
215 hr = m_staticToolbar->FillToolbar();
216 if (FAILED_UNEXPECTEDLY(hr))
217 return hr;
218 }
219
220 if (m_SFToolbar != NULL)
221 {
222 hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
223 if (FAILED_UNEXPECTEDLY(hr))
224 return hr;
225
226 hr = m_SFToolbar->FillToolbar();
227 if (FAILED_UNEXPECTEDLY(hr))
228 return hr;
229 }
230
231 hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_subMenuParent));
232 if (hr != E_NOINTERFACE && FAILED_UNEXPECTEDLY(hr))
233 return hr;
234
235 CComPtr<IOleWindow> pTopLevelWindow;
236 hr = IUnknown_QueryService(m_site, SID_STopLevelBrowser, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
237 if (SUCCEEDED(hr))
238 {
239 hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
240 if (FAILED_UNEXPECTEDLY(hr))
241 return hr;
242 }
243 else
244 {
245 m_topLevelWindow = hwndParent;
246 }
247
248 return S_OK;
249 }
250
GetSite(REFIID riid,PVOID * ppvSite)251 HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
252 {
253 if (m_site == NULL)
254 return E_FAIL;
255
256 return m_site->QueryInterface(riid, ppvSite);
257 }
258
GetWindow(HWND * phwnd)259 HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(HWND *phwnd)
260 {
261 if (m_SFToolbar != NULL)
262 return m_SFToolbar->GetWindow(phwnd);
263
264 if (m_staticToolbar != NULL)
265 return m_staticToolbar->GetWindow(phwnd);
266
267 if (phwnd) *phwnd = NULL;
268
269 return E_FAIL;
270 }
271
OnPosRectChangeDB(RECT * prc)272 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
273 {
274 SIZE maxStatic = { 0 };
275 SIZE maxShlFld = { 0 };
276 HRESULT hr = S_OK;
277
278 if (m_staticToolbar != NULL)
279 hr = m_staticToolbar->GetSizes(NULL, &maxStatic, NULL);
280 if (FAILED_UNEXPECTEDLY(hr))
281 return hr;
282
283 if (m_SFToolbar != NULL)
284 hr = m_SFToolbar->GetSizes(NULL, &maxShlFld, NULL);
285 if (FAILED_UNEXPECTEDLY(hr))
286 return hr;
287
288 if (m_staticToolbar == NULL && m_SFToolbar == NULL)
289 return E_FAIL;
290
291 int sy = min(prc->bottom - prc->top, maxStatic.cy + maxShlFld.cy);
292
293 int syStatic = maxStatic.cy;
294 int syShlFld = sy - syStatic;
295
296 // TODO: Windows has a more complex system to decide ordering.
297 // Because we only support two toolbars at once, this is enough for us.
298 if (m_shellBottom)
299 {
300 // Static menu on top
301 if (m_SFToolbar)
302 {
303 m_SFToolbar->SetPosSize(
304 prc->left,
305 prc->top + syStatic,
306 prc->right - prc->left,
307 syShlFld);
308 }
309 if (m_staticToolbar)
310 {
311 m_staticToolbar->SetPosSize(
312 prc->left,
313 prc->top,
314 prc->right - prc->left,
315 syStatic);
316 }
317 }
318 else
319 {
320 // Folder menu on top
321 if (m_SFToolbar)
322 {
323 m_SFToolbar->SetPosSize(
324 prc->left,
325 prc->top,
326 prc->right - prc->left,
327 syShlFld);
328 }
329 if (m_staticToolbar)
330 {
331 m_staticToolbar->SetPosSize(
332 prc->left,
333 prc->top + syShlFld,
334 prc->right - prc->left,
335 syStatic);
336 }
337 }
338
339 return S_OK;
340 }
341
GetBandInfo(DWORD dwBandID,DWORD dwViewMode,DESKBANDINFO * pdbi)342 HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
343 DWORD dwBandID,
344 DWORD dwViewMode,
345 DESKBANDINFO *pdbi)
346 {
347 SIZE minStatic = { 0 };
348 SIZE minShlFld = { 0 };
349 SIZE maxStatic = { 0 };
350 SIZE maxShlFld = { 0 };
351 SIZE intStatic = { 0 };
352 SIZE intShlFld = { 0 };
353
354 HRESULT hr = S_OK;
355
356 if (m_staticToolbar != NULL)
357 hr = m_staticToolbar->GetSizes(&minStatic, &maxStatic, &intStatic);
358 if (FAILED_UNEXPECTEDLY(hr))
359 return hr;
360
361 if (m_SFToolbar != NULL)
362 hr = m_SFToolbar->GetSizes(&minShlFld, &maxShlFld, &intShlFld);
363 if (FAILED_UNEXPECTEDLY(hr))
364 return hr;
365
366 if (m_staticToolbar == NULL && m_SFToolbar == NULL)
367 return E_FAIL;
368
369 if (m_dwFlags & SMINIT_VERTICAL)
370 {
371 pdbi->ptMinSize.x = max(minStatic.cx, minShlFld.cx) + 20;
372 pdbi->ptMinSize.y = minStatic.cy + minShlFld.cy;
373 pdbi->ptMaxSize.x = max(maxStatic.cx, maxShlFld.cx) + 20;
374 pdbi->ptMaxSize.y = maxStatic.cy + maxShlFld.cy;
375 pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
376 }
377 else
378 {
379 pdbi->ptMinSize.x = minStatic.cx + minShlFld.cx;
380 pdbi->ptMinSize.y = max(minStatic.cy, minShlFld.cy);
381 pdbi->ptMaxSize.x = maxStatic.cx + maxShlFld.cx;
382 pdbi->ptMaxSize.y = max(maxStatic.cy, maxShlFld.cy);
383 }
384 pdbi->ptIntegral.x = max(intStatic.cx, intShlFld.cx);
385 pdbi->ptIntegral.y = max(intStatic.cy, intShlFld.cy);
386 pdbi->ptActual = pdbi->ptMinSize;
387
388 return S_OK;
389 }
390
ShowDW(BOOL fShow)391 HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
392 {
393 HRESULT hr = S_OK;
394
395 if (m_Show == fShow)
396 return S_OK;
397
398 m_Show = fShow;
399
400 if (m_staticToolbar != NULL)
401 {
402 hr = m_staticToolbar->ShowDW(fShow);
403 if (FAILED_UNEXPECTEDLY(hr))
404 return hr;
405 }
406
407 if (m_SFToolbar != NULL)
408 {
409 hr = m_SFToolbar->ShowDW(fShow);
410 if (FAILED_UNEXPECTEDLY(hr))
411 return hr;
412 }
413
414 if (fShow)
415 {
416 hr = _CallCB(SMC_INITMENU, 0, 0);
417 if (FAILED_UNEXPECTEDLY(hr))
418 return hr;
419 }
420 else if (m_parentBand)
421 {
422 m_parentBand->SetClient(NULL);
423 }
424
425 if (_IsPopup() == S_OK)
426 {
427 if (fShow)
428 hr = m_focusManager->PushMenuPopup(this);
429 else
430 hr = m_focusManager->PopMenuPopup(this);
431 }
432 else
433 {
434 if (fShow)
435 hr = m_focusManager->PushMenuBar(this);
436 else
437 hr = m_focusManager->PopMenuBar(this);
438 }
439
440 return S_OK;
441 }
442
CloseDW(DWORD dwReserved)443 HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
444 {
445 if (m_subMenuChild)
446 {
447 m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
448 }
449
450 if (m_subMenuChild)
451 {
452 TRACE("Child object should have removed itself.\n");
453 }
454
455 ShowDW(FALSE);
456
457 if (m_staticToolbar != NULL)
458 {
459 m_staticToolbar->Close();
460 }
461
462 if (m_SFToolbar != NULL)
463 {
464 m_SFToolbar->Close();
465 }
466
467 if (m_site) m_site.Release();
468 if (m_subMenuChild) m_subMenuChild.Release();
469 if (m_subMenuParent) m_subMenuParent.Release();
470 if (m_childBand) m_childBand.Release();
471 if (m_parentBand) m_parentBand.Release();
472
473 return S_OK;
474 }
475
UIActivateIO(BOOL fActivate,LPMSG lpMsg)476 HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
477 {
478 HRESULT hr;
479
480 if (m_subMenuParent)
481 {
482 hr = m_subMenuParent->SetSubMenu(this, fActivate);
483 if (FAILED_UNEXPECTEDLY(hr))
484 return hr;
485 }
486
487 if (fActivate)
488 {
489 CComPtr<IOleWindow> pTopLevelWindow;
490 hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
491 if (FAILED_UNEXPECTEDLY(hr))
492 return hr;
493
494 hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
495 if (FAILED_UNEXPECTEDLY(hr))
496 return hr;
497 }
498 else
499 {
500 m_topLevelWindow = NULL;
501 }
502
503 return S_FALSE;
504 }
505
Exec(const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)506 HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
507 {
508 if (!pguidCmdGroup)
509 return E_FAIL;
510
511 if (IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
512 {
513 if (nCmdID == 16) // set (big) icon size
514 {
515 this->m_useBigIcons = nCmdexecopt == 2;
516 return S_OK;
517 }
518 else if (nCmdID == 19) // popup-related
519 {
520 return S_FALSE;
521 }
522 else if (nCmdID == 5) // select an item
523 {
524 if (nCmdexecopt == 0) // first
525 {
526 _KeyboardItemChange(VK_HOME);
527 }
528 else // last
529 {
530 _KeyboardItemChange(VK_END);
531 }
532 return S_FALSE;
533 }
534
535 return S_FALSE;
536 }
537
538 UNIMPLEMENTED;
539 return S_OK;
540 }
541
QueryService(REFGUID guidService,REFIID riid,void ** ppvObject)542 HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
543 {
544 if (IsEqualIID(guidService, SID_SMenuBandChild) ||
545 IsEqualIID(guidService, SID_SMenuBandBottom) ||
546 IsEqualIID(guidService, SID_SMenuBandBottomSelected))
547 return this->QueryInterface(riid, ppvObject);
548 WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService));
549 return E_NOINTERFACE;
550 }
551
Popup(POINTL * ppt,RECTL * prcExclude,MP_POPUPFLAGS dwFlags)552 HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
553 {
554 UNIMPLEMENTED;
555 return S_OK;
556 }
557
OnSelect(DWORD dwSelectType)558 HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
559 {
560 // When called from outside, this is straightforward:
561 // Things that a submenu needs to know, are spread down, and
562 // things that the parent needs to know, are spread up. No drama.
563 // The fun is in _MenuItemSelect (internal method).
564 switch (dwSelectType)
565 {
566 case MPOS_CHILDTRACKING:
567 if (!m_subMenuParent)
568 break;
569 // TODO: Cancel timers?
570 return m_subMenuParent->OnSelect(dwSelectType);
571 case MPOS_SELECTLEFT:
572 if (m_subMenuChild)
573 m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
574 if (!m_subMenuParent)
575 break;
576 return m_subMenuParent->OnSelect(dwSelectType);
577 case MPOS_SELECTRIGHT:
578 if (!m_subMenuParent)
579 break;
580 return m_subMenuParent->OnSelect(dwSelectType);
581 case MPOS_EXECUTE:
582 case MPOS_FULLCANCEL:
583 if (m_subMenuChild)
584 m_subMenuChild->OnSelect(dwSelectType);
585 if (!m_subMenuParent)
586 break;
587 return m_subMenuParent->OnSelect(dwSelectType);
588 case MPOS_CANCELLEVEL:
589 if (m_subMenuChild)
590 m_subMenuChild->OnSelect(dwSelectType);
591 break;
592 }
593 return S_FALSE;
594 }
595
SetSubMenu(IMenuPopup * pmp,BOOL fSet)596 HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
597 {
598 UNIMPLEMENTED;
599 return S_OK;
600 }
601
602 // Used by the focus manager to update the child band pointer
_SetChildBand(CMenuBand * child)603 HRESULT CMenuBand::_SetChildBand(CMenuBand * child)
604 {
605 m_childBand = child;
606 if (!child)
607 {
608 _ChangePopupItem(NULL, -1);
609 }
610 return S_OK;
611 }
612
613 // User by the focus manager to update the parent band pointer
_SetParentBand(CMenuBand * parent)614 HRESULT CMenuBand::_SetParentBand(CMenuBand * parent)
615 {
616 m_parentBand = parent;
617 return S_OK;
618 }
619
_IsPopup()620 HRESULT CMenuBand::_IsPopup()
621 {
622 return !(m_dwFlags & SMINIT_VERTICAL);
623 }
624
_IsTracking()625 HRESULT CMenuBand::_IsTracking()
626 {
627 return m_popupBar != NULL;
628 }
629
SetClient(IUnknown * punkClient)630 HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
631 {
632 CComPtr<IMenuPopup> child = m_subMenuChild;
633
634 m_subMenuChild = NULL;
635
636 if (child)
637 {
638 IUnknown_SetSite(child, NULL);
639 child.Release();
640 }
641
642 if (!punkClient)
643 {
644 return S_OK;
645 }
646
647 return punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild));
648 }
649
GetClient(IUnknown ** ppunkClient)650 HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
651 {
652 if (!ppunkClient)
653 return E_POINTER;
654 *ppunkClient = NULL;
655
656 if (m_subMenuChild)
657 {
658 *ppunkClient = m_subMenuChild;
659 (*ppunkClient)->AddRef();
660 }
661
662 return S_OK;
663 }
664
IsMenuMessage(MSG * pmsg)665 HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
666 {
667 return S_FALSE;
668 }
669
TranslateMenuMessage(MSG * pmsg,LRESULT * plRet)670 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
671 {
672 if (pmsg->message == WM_ACTIVATE && _IsPopup() == S_FALSE)
673 {
674 if (m_staticToolbar)
675 m_staticToolbar->Invalidate();
676 if (m_SFToolbar)
677 m_SFToolbar->Invalidate();
678 }
679
680 return S_FALSE;
681 }
682
SetShellFolder(IShellFolder * psf,LPCITEMIDLIST pidlFolder,HKEY hKey,DWORD dwFlags)683 HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
684 {
685 if (!psf)
686 return E_INVALIDARG;
687
688 if (m_SFToolbar == NULL)
689 {
690 m_SFToolbar = new CMenuSFToolbar(this);
691 }
692
693 HRESULT hr = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
694 if (FAILED_UNEXPECTEDLY(hr))
695 return hr;
696
697 m_shellBottom = (dwFlags & SMSET_BOTTOM) != 0;
698
699 if (m_site)
700 {
701 HWND hwndParent;
702
703 hr = m_site->GetWindow(&hwndParent);
704 if (FAILED_UNEXPECTEDLY(hr))
705 return hr;
706
707 hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
708 if (FAILED_UNEXPECTEDLY(hr))
709 return hr;
710
711 hr = m_SFToolbar->FillToolbar();
712 }
713
714 return hr;
715 }
716
GetShellFolder(DWORD * pdwFlags,LPITEMIDLIST * ppidl,REFIID riid,void ** ppv)717 HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
718 {
719 if (m_SFToolbar)
720 return m_SFToolbar->GetShellFolder(pdwFlags, ppidl, riid, ppv);
721 return E_FAIL;
722 }
723
OnWinEvent(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT * theResult)724 HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
725 {
726 if (theResult)
727 *theResult = 0;
728
729 if (uMsg == WM_WININICHANGE && wParam == SPI_SETFLATMENU)
730 {
731 BOOL bFlatMenus;
732 SystemParametersInfo(SPI_GETFLATMENU, 0, &bFlatMenus, 0);
733 AdjustForTheme(bFlatMenus);
734
735 if (m_staticToolbar)
736 m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
737
738 if (m_SFToolbar)
739 m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
740
741 return S_OK;
742 }
743
744 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
745 {
746 return m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
747 }
748
749 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
750 {
751 return m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
752 }
753
754 return S_FALSE;
755 }
756
IsWindowOwner(HWND hWnd)757 HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
758 {
759 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
760 return S_OK;
761
762 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
763 return S_OK;
764
765 return S_FALSE;
766 }
767
_CallCBWithItemId(UINT id,UINT uMsg,WPARAM wParam,LPARAM lParam)768 HRESULT CMenuBand::_CallCBWithItemId(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam)
769 {
770 return _CallCB(uMsg, wParam, lParam, id);
771 }
772
_CallCBWithItemPidl(LPITEMIDLIST pidl,UINT uMsg,WPARAM wParam,LPARAM lParam)773 HRESULT CMenuBand::_CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam)
774 {
775 return _CallCB(uMsg, wParam, lParam, 0, pidl);
776 }
777
_CallCB(UINT uMsg,WPARAM wParam,LPARAM lParam,UINT id,LPITEMIDLIST pidl)778 HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPITEMIDLIST pidl)
779 {
780 if (!m_psmc)
781 return S_FALSE;
782
783 SMDATA smData = { 0 };
784 smData.punk = static_cast<IShellMenu2*>(this);
785 smData.uId = id;
786 smData.uIdParent = m_uId;
787 smData.uIdAncestor = m_uIdAncestor;
788 smData.pidlItem = pidl;
789 smData.hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
790 smData.hmenu = m_hmenu;
791 if (m_SFToolbar)
792 m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
793 HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
794 ILFree(smData.pidlFolder);
795 if (smData.psf)
796 smData.psf->Release();
797 return hr;
798 }
799
_TrackSubMenu(HMENU popup,INT x,INT y,RECT & rcExclude)800 HRESULT CMenuBand::_TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
801 {
802 TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
803 UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
804 HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
805
806 m_trackedPopup = popup;
807 m_trackedHwnd = hwnd;
808
809 m_focusManager->PushTrackedPopup(popup);
810 ::TrackPopupMenuEx(popup, flags, x, y, hwnd, ¶ms);
811 m_focusManager->PopTrackedPopup(popup);
812
813 m_trackedPopup = NULL;
814 m_trackedHwnd = NULL;
815
816 _DisableMouseTrack(FALSE);
817
818 return S_OK;
819 }
820
_TrackContextMenu(IContextMenu * contextMenu,INT x,INT y)821 HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y)
822 {
823 HRESULT hr;
824 UINT uCommand;
825
826 // Ensure that the menu doesn't disappear on us
827 CComPtr<IContextMenu> ctxMenu = contextMenu;
828
829 HMENU popup = CreatePopupMenu();
830
831 if (popup == NULL)
832 return E_FAIL;
833
834 TRACE("Before Query\n");
835 UINT cmf = CMF_NORMAL;
836 if (GetKeyState(VK_SHIFT) < 0)
837 cmf |= CMF_EXTENDEDVERBS;
838
839 const UINT idCmdFirst = 100, idCmdLast = 0xffff;
840 hr = contextMenu->QueryContextMenu(popup, 0, idCmdFirst, idCmdLast, cmf);
841 if (FAILED_UNEXPECTEDLY(hr))
842 {
843 TRACE("Query failed\n");
844 DestroyMenu(popup);
845 return hr;
846 }
847
848 HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
849
850 m_focusManager->PushTrackedPopup(popup);
851
852 TRACE("Before Tracking\n");
853 uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, hwnd, NULL);
854
855 m_focusManager->PopTrackedPopup(popup);
856
857 if (uCommand != 0)
858 {
859 _MenuItemSelect(MPOS_FULLCANCEL);
860
861 TRACE("Before InvokeCommand\n");
862 CMINVOKECOMMANDINFO cmi = { sizeof(cmi), 0, hwnd };
863 cmi.lpVerb = MAKEINTRESOURCEA(uCommand - idCmdFirst);
864 if (GetKeyState(VK_SHIFT) < 0)
865 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
866 if (GetKeyState(VK_CONTROL) < 0)
867 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
868 hr = contextMenu->InvokeCommand(&cmi);
869 TRACE("InvokeCommand returned hr=%08x\n", hr);
870 }
871 else
872 {
873 TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
874 hr = S_FALSE;
875 }
876
877 DestroyMenu(popup);
878 return hr;
879 }
880
_GetTopLevelWindow(HWND * topLevel)881 HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
882 {
883 *topLevel = m_topLevelWindow;
884 return S_OK;
885 }
886
_ChangeHotItem(CMenuToolbarBase * tb,INT id,DWORD dwFlags)887 HRESULT CMenuBand::_ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags)
888 {
889 if (m_hotBar == tb && m_hotItem == id)
890 return S_FALSE;
891
892 TRACE("Hot item changed from %p %p, to %p %p\n", m_hotBar, m_hotItem, tb, id);
893
894 _KillPopupTimers();
895
896 m_hotBar = tb;
897 m_hotItem = id;
898 if (m_staticToolbar) m_staticToolbar->ChangeHotItem(tb, id, dwFlags);
899 if (m_SFToolbar) m_SFToolbar->ChangeHotItem(tb, id, dwFlags);
900
901 _MenuItemSelect(MPOS_CHILDTRACKING);
902
903 return S_OK;
904 }
905
_ChangePopupItem(CMenuToolbarBase * tb,INT id)906 HRESULT CMenuBand::_ChangePopupItem(CMenuToolbarBase * tb, INT id)
907 {
908 TRACE("Popup item changed from %p %p, to %p %p\n", m_popupBar, m_popupItem, tb, id);
909
910 m_popupBar = tb;
911 m_popupItem = id;
912 if (m_staticToolbar) m_staticToolbar->ChangePopupItem(tb, id);
913 if (m_SFToolbar) m_SFToolbar->ChangePopupItem(tb, id);
914
915 return S_OK;
916 }
917
_KeyboardItemChange(DWORD change)918 HRESULT CMenuBand::_KeyboardItemChange(DWORD change)
919 {
920 HRESULT hr;
921 CMenuToolbarBase *tb = m_hotBar;
922
923 if (!tb)
924 {
925 // If no hot item was selected choose the appropriate toolbar
926 if (change == VK_UP || change == VK_END)
927 {
928 if (m_staticToolbar)
929 tb = m_staticToolbar;
930 else
931 tb = m_SFToolbar;
932 }
933 else if (change == VK_DOWN || change == VK_HOME)
934 {
935 if (m_SFToolbar)
936 tb = m_SFToolbar;
937 else
938 tb = m_staticToolbar;
939 }
940 }
941
942 // Ask the first toolbar to change
943 hr = tb->KeyboardItemChange(change);
944
945 if (hr != S_FALSE)
946 return hr;
947
948 // Select the second toolbar based on the first
949 if (tb == m_SFToolbar && m_staticToolbar)
950 tb = m_staticToolbar;
951 else if (m_SFToolbar)
952 tb = m_SFToolbar;
953
954 if (!tb)
955 return hr;
956
957 // Ask the second toolbar to change
958 return tb->KeyboardItemChange(change == VK_DOWN ? VK_HOME : VK_END);
959 }
960
_MenuItemSelect(DWORD changeType)961 HRESULT CMenuBand::_MenuItemSelect(DWORD changeType)
962 {
963 // Needed to prevent the this point from vanishing mid-function
964 CComPtr<CMenuBand> safeThis = this;
965 HRESULT hr;
966
967 if (m_dwFlags & SMINIT_VERTICAL)
968 {
969 switch (changeType)
970 {
971 case VK_UP:
972 case VK_DOWN:
973 return _KeyboardItemChange(changeType);
974
975 // TODO: Left/Right across multi-column menus, if they ever work.
976 case VK_LEFT:
977 changeType = MPOS_SELECTLEFT;
978 break;
979 case VK_RIGHT:
980 changeType = MPOS_SELECTRIGHT;
981 break;
982 }
983 }
984 else
985 {
986 // In horizontal menubars, left/right are equivalent to vertical's up/down
987 switch (changeType)
988 {
989 case VK_LEFT:
990 hr = _KeyboardItemChange(VK_UP);
991 if (hr != S_FALSE)
992 return hr;
993 case VK_RIGHT:
994 hr = _KeyboardItemChange(VK_DOWN);
995 if (hr != S_FALSE)
996 return hr;
997 }
998 }
999
1000 // In this context, the parent is the CMenuDeskBar, so when it bubbles upward,
1001 // it is notifying the deskbar, and not the the higher-level menu.
1002 // Same for the child: since it points to a CMenuDeskBar, it's not just recursing.
1003 switch (changeType)
1004 {
1005 case MPOS_EXECUTE:
1006 {
1007 CMenuToolbarBase * tb = m_hotBar;
1008 int item = m_hotItem;
1009 tb->PrepareExecuteItem(item);
1010 if (m_subMenuParent)
1011 {
1012 m_subMenuParent->OnSelect(changeType);
1013 }
1014 TRACE("Menu closed, executing item...\n");
1015 tb->ExecuteItem();
1016 break;
1017 }
1018 case MPOS_SELECTLEFT:
1019 if (m_parentBand && m_parentBand->_IsPopup()==S_FALSE)
1020 return m_parentBand->_MenuItemSelect(VK_LEFT);
1021 if (m_subMenuChild)
1022 return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
1023 if (!m_subMenuParent)
1024 return S_OK;
1025 return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
1026
1027 case MPOS_SELECTRIGHT:
1028 if (m_hotBar && m_hotItem >= 0 && m_hotBar->PopupItem(m_hotItem, TRUE) == S_OK)
1029 return S_FALSE;
1030 if (m_parentBand)
1031 return m_parentBand->_MenuItemSelect(VK_RIGHT);
1032 if (!m_subMenuParent)
1033 return S_OK;
1034 return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT);
1035
1036 default:
1037 if (!m_subMenuParent)
1038 return S_OK;
1039 return m_subMenuParent->OnSelect(changeType);
1040 }
1041
1042 return S_OK;
1043 }
1044
_CancelCurrentPopup()1045 HRESULT CMenuBand::_CancelCurrentPopup()
1046 {
1047 if (m_subMenuChild)
1048 {
1049 HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
1050 return hr;
1051 }
1052
1053 if (m_trackedPopup)
1054 {
1055 ::SendMessage(m_trackedHwnd, WM_CANCELMODE, 0, 0);
1056 return S_OK;
1057 }
1058
1059 return S_FALSE;
1060 }
1061
_OnPopupSubMenu(IShellMenu * childShellMenu,POINTL * pAt,RECTL * pExclude,BOOL keyInitiated)1062 HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude, BOOL keyInitiated)
1063 {
1064 HRESULT hr = 0;
1065 CComPtr<IBandSite> pBandSite;
1066 CComPtr<IDeskBar> pDeskBar;
1067
1068 // Create the necessary objects
1069 hr = CMenuSite_CreateInstance(IID_PPV_ARG(IBandSite, &pBandSite));
1070 if (FAILED_UNEXPECTEDLY(hr))
1071 return hr;
1072
1073 hr = CMenuDeskBar_CreateInstance(IID_PPV_ARG(IDeskBar, &pDeskBar));
1074 if (FAILED_UNEXPECTEDLY(hr))
1075 return hr;
1076
1077 hr = pDeskBar->SetClient(pBandSite);
1078 if (FAILED_UNEXPECTEDLY(hr))
1079 return hr;
1080
1081 hr = pBandSite->AddBand(childShellMenu);
1082 if (FAILED_UNEXPECTEDLY(hr))
1083 return hr;
1084
1085 //
1086 CComPtr<IMenuPopup> popup;
1087 hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
1088 if (FAILED_UNEXPECTEDLY(hr))
1089 return hr;
1090
1091 m_subMenuChild = popup;
1092
1093 if (m_subMenuParent)
1094 IUnknown_SetSite(popup, m_subMenuParent);
1095 else
1096 IUnknown_SetSite(popup, m_site);
1097
1098 DWORD flags = MPPF_RIGHT;
1099
1100 if (keyInitiated && m_dwFlags & SMINIT_VERTICAL)
1101 flags |= MPPF_INITIALSELECT;
1102
1103 popup->Popup(pAt, pExclude, flags);
1104
1105 return S_OK;
1106 }
1107
_BeforeCancelPopup()1108 HRESULT CMenuBand::_BeforeCancelPopup()
1109 {
1110 if (m_staticToolbar)
1111 m_staticToolbar->BeforeCancelPopup();
1112 if (m_SFToolbar)
1113 m_SFToolbar->BeforeCancelPopup();
1114 return S_OK;
1115 }
1116
_DisableMouseTrack(BOOL bDisable)1117 HRESULT CMenuBand::_DisableMouseTrack(BOOL bDisable)
1118 {
1119 if (m_staticToolbar)
1120 m_staticToolbar->DisableMouseTrack(bDisable);
1121 if (m_SFToolbar)
1122 m_SFToolbar->DisableMouseTrack(bDisable);
1123 return S_OK;
1124 }
1125
_KillPopupTimers()1126 HRESULT CMenuBand::_KillPopupTimers()
1127 {
1128 HRESULT hr = S_OK;
1129 if (m_staticToolbar)
1130 hr = m_staticToolbar->KillPopupTimer();
1131 if (FAILED(hr))
1132 return hr;
1133
1134 if (m_SFToolbar)
1135 hr = m_SFToolbar->KillPopupTimer();
1136
1137 return hr;
1138 }
1139
_MenuBarMouseDown(HWND hwnd,INT item,BOOL isLButton)1140 HRESULT CMenuBand::_MenuBarMouseDown(HWND hwnd, INT item, BOOL isLButton)
1141 {
1142 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hwnd) == S_OK)
1143 m_staticToolbar->MenuBarMouseDown(item, isLButton);
1144 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hwnd) == S_OK)
1145 m_SFToolbar->MenuBarMouseDown(item, isLButton);
1146 return S_OK;
1147 }
1148
_MenuBarMouseUp(HWND hwnd,INT item,BOOL isLButton)1149 HRESULT CMenuBand::_MenuBarMouseUp(HWND hwnd, INT item, BOOL isLButton)
1150 {
1151 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hwnd) == S_OK)
1152 m_staticToolbar->MenuBarMouseUp(item, isLButton);
1153 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hwnd) == S_OK)
1154 m_SFToolbar->MenuBarMouseUp(item, isLButton);
1155 return S_OK;
1156 }
1157
_HasSubMenu()1158 HRESULT CMenuBand::_HasSubMenu()
1159 {
1160 return m_popupBar ? S_OK : S_FALSE;
1161 }
1162
AdjustForTheme(BOOL bFlatStyle)1163 HRESULT CMenuBand::AdjustForTheme(BOOL bFlatStyle)
1164 {
1165 return IUnknown_QueryServiceExec(m_site, SID_SMenuPopup, &CGID_MenuDeskBar, 4, bFlatStyle, NULL, NULL);
1166 }
1167
InvalidateItem(LPSMDATA psmd,DWORD dwFlags)1168 HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
1169 {
1170 UNIMPLEMENTED;
1171 return S_OK;
1172 }
1173
GetState(LPSMDATA psmd)1174 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
1175 {
1176 UNIMPLEMENTED;
1177 return S_OK;
1178 }
1179
SetMenuToolbar(IUnknown * punk,DWORD dwFlags)1180 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
1181 {
1182 UNIMPLEMENTED;
1183 return S_OK;
1184 }
1185
ResizeBorderDW(LPCRECT prcBorder,IUnknown * punkToolbarSite,BOOL fReserved)1186 HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
1187 {
1188 UNIMPLEMENTED;
1189 return S_OK;
1190 }
1191
ContextSensitiveHelp(BOOL fEnterMode)1192 HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
1193 {
1194 UNIMPLEMENTED;
1195 return S_OK;
1196 }
1197
GetSubMenu(THIS)1198 HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
1199 {
1200 UNIMPLEMENTED;
1201 return S_OK;
1202 }
1203
SetToolbar(THIS)1204 HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
1205 {
1206 UNIMPLEMENTED;
1207 return S_OK;
1208 }
1209
SetMinWidth(THIS)1210 HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
1211 {
1212 UNIMPLEMENTED;
1213 return S_OK;
1214 }
1215
SetNoBorder(THIS)1216 HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
1217 {
1218 UNIMPLEMENTED;
1219 return S_OK;
1220 }
1221
SetTheme(THIS)1222 HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
1223 {
1224 UNIMPLEMENTED;
1225 return S_OK;
1226 }
1227
GetTop(THIS)1228 HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
1229 {
1230 UNIMPLEMENTED;
1231 return S_OK;
1232 }
1233
GetBottom(THIS)1234 HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
1235 {
1236 UNIMPLEMENTED;
1237 return S_OK;
1238 }
1239
GetTracked(THIS)1240 HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
1241 {
1242 UNIMPLEMENTED;
1243 return S_OK;
1244 }
1245
GetParentSite(THIS)1246 HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
1247 {
1248 UNIMPLEMENTED;
1249 return S_OK;
1250 }
1251
GetState(THIS)1252 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
1253 {
1254 UNIMPLEMENTED;
1255 return S_OK;
1256 }
1257
DoDefaultAction(THIS)1258 HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
1259 {
1260 UNIMPLEMENTED;
1261 return S_OK;
1262 }
1263
IsEmpty(THIS)1264 HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
1265 {
1266 UNIMPLEMENTED;
1267 return S_OK;
1268 }
1269
HasFocusIO()1270 HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
1271 {
1272 if (m_popupBar)
1273 return S_OK;
1274 return S_FALSE;
1275 }
1276
TranslateAcceleratorIO(LPMSG lpMsg)1277 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
1278 {
1279 // TODO: Alt down -> toggle menu focus
1280 return S_FALSE;
1281 }
1282
IsDirty()1283 HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
1284 {
1285 UNIMPLEMENTED;
1286 return S_OK;
1287 }
1288
Load(IStream * pStm)1289 HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
1290 {
1291 UNIMPLEMENTED;
1292 return S_OK;
1293 }
1294
Save(IStream * pStm,BOOL fClearDirty)1295 HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
1296 {
1297 UNIMPLEMENTED;
1298 return S_OK;
1299 }
1300
GetSizeMax(ULARGE_INTEGER * pcbSize)1301 HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
1302 {
1303 UNIMPLEMENTED;
1304 return S_OK;
1305 }
1306
GetClassID(CLSID * pClassID)1307 HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
1308 {
1309 UNIMPLEMENTED;
1310 return S_OK;
1311 }
1312
QueryStatus(const GUID * pguidCmdGroup,ULONG cCmds,OLECMD prgCmds[],OLECMDTEXT * pCmdText)1313 HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
1314 {
1315 UNIMPLEMENTED;
1316 return S_OK;
1317 }
1318
1319 extern "C"
RSHELL_CMenuBand_CreateInstance(REFIID riid,LPVOID * ppv)1320 HRESULT WINAPI RSHELL_CMenuBand_CreateInstance(REFIID riid, LPVOID *ppv)
1321 {
1322 return ShellObjectCreator<CMenuBand>(riid, ppv);
1323 }
1324