[RSHELL]
[reactos.git] / base / shell / rshell / CMenuBand.cpp
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 "precomp.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 DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
34
35 extern "C"
36 HRESULT WINAPI CMenuBand_Constructor(REFIID riid, LPVOID *ppv)
37 {
38 *ppv = NULL;
39
40 CMenuBand * site = new CComObject<CMenuBand>();
41
42 if (!site)
43 return E_OUTOFMEMORY;
44
45 HRESULT hr = site->QueryInterface(riid, ppv);
46
47 if (FAILED_UNEXPECTEDLY(hr))
48 site->Release();
49
50 return hr;
51 }
52
53 CMenuBand::CMenuBand() :
54 m_staticToolbar(NULL),
55 m_SFToolbar(NULL),
56 m_site(NULL),
57 m_psmc(NULL),
58 m_subMenuChild(NULL),
59 m_hmenu(NULL),
60 m_menuOwner(NULL),
61 m_useBigIcons(FALSE),
62 m_topLevelWindow(NULL),
63 m_hotBar(NULL),
64 m_hotItem(-1)
65 {
66 m_focusManager = CMenuFocusManager::AcquireManager();
67 }
68
69 CMenuBand::~CMenuBand()
70 {
71 CMenuFocusManager::ReleaseManager(m_focusManager);
72
73 if (m_staticToolbar)
74 delete m_staticToolbar;
75
76 if (m_SFToolbar)
77 delete m_SFToolbar;
78 }
79
80 HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
81 IShellMenuCallback *psmc,
82 UINT uId,
83 UINT uIdAncestor,
84 DWORD dwFlags)
85 {
86 if (m_psmc != psmc)
87 m_psmc = psmc;
88 m_uId = uId;
89 m_uIdAncestor = uIdAncestor;
90 m_dwFlags = dwFlags;
91
92 if (m_psmc)
93 {
94 _CallCB(SMC_CREATE, 0, reinterpret_cast<LPARAM>(&m_UserData));
95 }
96
97 return S_OK;
98 }
99
100 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
101 IShellMenuCallback **ppsmc,
102 UINT *puId,
103 UINT *puIdAncestor,
104 DWORD *pdwFlags)
105 {
106 if (!pdwFlags) // maybe?
107 return E_INVALIDARG;
108
109 if (ppsmc)
110 *ppsmc = m_psmc;
111
112 if (puId)
113 *puId = m_uId;
114
115 if (puIdAncestor)
116 *puIdAncestor = m_uIdAncestor;
117
118 *pdwFlags = m_dwFlags;
119
120 return S_OK;
121 }
122
123 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(
124 HMENU hmenu,
125 HWND hwnd,
126 DWORD dwFlags)
127 {
128 DbgPrint("CMenuBand::SetMenu called, hmenu=%p; hwnd=%p, flags=%x\n", hmenu, hwnd, dwFlags);
129
130 BOOL created = FALSE;
131
132 if (m_staticToolbar == NULL)
133 {
134 m_staticToolbar = new CMenuStaticToolbar(this);
135 created = true;
136 }
137 m_hmenu = hmenu;
138 m_menuOwner = hwnd;
139
140 HRESULT hr = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
141 if (FAILED_UNEXPECTEDLY(hr))
142 return hr;
143
144 if (m_site)
145 {
146 HWND hwndParent;
147
148 hr = m_site->GetWindow(&hwndParent);
149 if (FAILED_UNEXPECTEDLY(hr))
150 return hr;
151
152 if (created)
153 {
154 hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
155 if (FAILED_UNEXPECTEDLY(hr))
156 return hr;
157
158 hr = m_staticToolbar->FillToolbar();
159 }
160 else
161 {
162 hr = m_staticToolbar->FillToolbar(TRUE);
163 }
164 }
165
166 return hr;
167 }
168
169 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(
170 HMENU *phmenu,
171 HWND *phwnd,
172 DWORD *pdwFlags)
173 {
174 if (m_staticToolbar == NULL)
175 return E_FAIL;
176
177 return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags);
178 }
179
180 HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
181 {
182 HWND hwndParent;
183 HRESULT hr;
184
185 m_site = NULL;
186
187 if (pUnkSite == NULL)
188 return S_OK;
189
190 hwndParent = NULL;
191 hr = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
192 if (FAILED_UNEXPECTEDLY(hr))
193 return hr;
194
195 hr = m_site->GetWindow(&hwndParent);
196 if (FAILED_UNEXPECTEDLY(hr))
197 return hr;
198
199 if (!::IsWindow(hwndParent))
200 return E_FAIL;
201
202 if (m_staticToolbar != NULL)
203 {
204 hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
205 if (FAILED_UNEXPECTEDLY(hr))
206 return hr;
207
208 hr = m_staticToolbar->FillToolbar();
209 if (FAILED_UNEXPECTEDLY(hr))
210 return hr;
211 }
212
213 if (m_SFToolbar != NULL)
214 {
215 hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
216 if (FAILED_UNEXPECTEDLY(hr))
217 return hr;
218
219 hr = m_SFToolbar->FillToolbar();
220 if (FAILED_UNEXPECTEDLY(hr))
221 return hr;
222 }
223
224 hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_subMenuParent));
225 if (hr != E_NOINTERFACE && FAILED_UNEXPECTEDLY(hr))
226 return hr;
227
228 CComPtr<IOleWindow> pTopLevelWindow;
229 hr = IUnknown_QueryService(m_site, SID_STopLevelBrowser, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
230 if (FAILED_UNEXPECTEDLY(hr))
231 return hr;
232
233 return pTopLevelWindow->GetWindow(&m_topLevelWindow);
234 }
235
236 HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
237 {
238 if (m_site == NULL)
239 return E_FAIL;
240
241 return m_site->QueryInterface(riid, ppvSite);
242 }
243
244 HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(
245 HWND *phwnd)
246 {
247 if (m_SFToolbar != NULL)
248 return m_SFToolbar->GetWindow(phwnd);
249
250 if (m_staticToolbar != NULL)
251 return m_staticToolbar->GetWindow(phwnd);
252
253 return E_FAIL;
254 }
255
256 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
257 {
258 SIZE sizeStatic = { 0 };
259 SIZE sizeShlFld = { 0 };
260 HRESULT hr = S_OK;
261
262 if (m_staticToolbar != NULL)
263 hr = m_staticToolbar->GetIdealSize(sizeStatic);
264 if (FAILED_UNEXPECTEDLY(hr))
265 return hr;
266
267 if (m_SFToolbar != NULL)
268 hr = m_SFToolbar->GetIdealSize(sizeShlFld);
269 if (FAILED_UNEXPECTEDLY(hr))
270 return hr;
271
272 if (m_staticToolbar == NULL && m_SFToolbar == NULL)
273 return E_FAIL;
274
275 int sy = min(prc->bottom - prc->top, sizeStatic.cy + sizeShlFld.cy);
276
277 int syStatic = sizeStatic.cy;
278 int syShlFld = sy - syStatic;
279
280 if (m_SFToolbar)
281 {
282 m_SFToolbar->SetPosSize(
283 prc->left,
284 prc->top,
285 prc->right - prc->left,
286 syShlFld);
287 }
288 if (m_staticToolbar)
289 {
290 m_staticToolbar->SetPosSize(
291 prc->left,
292 prc->top + syShlFld,
293 prc->right - prc->left,
294 syStatic);
295 }
296
297 return S_OK;
298 }
299 HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
300 DWORD dwBandID,
301 DWORD dwViewMode,
302 DESKBANDINFO *pdbi)
303 {
304 SIZE sizeStatic = { 0 };
305 SIZE sizeShlFld = { 0 };
306
307 HRESULT hr = S_OK;
308
309 if (m_staticToolbar != NULL)
310 hr = m_staticToolbar->GetIdealSize(sizeStatic);
311 if (FAILED_UNEXPECTEDLY(hr))
312 return hr;
313
314 if (m_SFToolbar != NULL)
315 hr = m_SFToolbar->GetIdealSize(sizeShlFld);
316 if (FAILED_UNEXPECTEDLY(hr))
317 return hr;
318
319 if (m_staticToolbar == NULL && m_SFToolbar == NULL)
320 return E_FAIL;
321
322 pdbi->ptMinSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
323 pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
324 pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
325 pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
326
327 return S_OK;
328 }
329
330 HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
331 {
332 HRESULT hr = S_OK;
333
334 if (m_staticToolbar != NULL)
335 hr = m_staticToolbar->ShowWindow(fShow);
336 if (FAILED_UNEXPECTEDLY(hr))
337 return hr;
338 if (m_SFToolbar != NULL)
339 hr = m_SFToolbar->ShowWindow(fShow);
340 if (FAILED_UNEXPECTEDLY(hr))
341 return hr;
342
343 if (fShow)
344 {
345 hr = _CallCB(SMC_INITMENU, 0, 0);
346 if (FAILED_UNEXPECTEDLY(hr))
347 return hr;
348 }
349
350 if (m_dwFlags & SMINIT_VERTICAL)
351 {
352 if (fShow)
353 hr = m_focusManager->PushMenu(this);
354 else
355 hr = m_focusManager->PopMenu(this);
356 }
357
358 return S_OK;
359 }
360
361 HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
362 {
363 ShowDW(FALSE);
364
365 if (m_staticToolbar != NULL)
366 return m_staticToolbar->Close();
367
368 if (m_SFToolbar != NULL)
369 return m_SFToolbar->Close();
370
371 return S_OK;
372 }
373 HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
374 {
375 UNIMPLEMENTED;
376 return S_OK;
377 }
378
379 HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
380 {
381 UNIMPLEMENTED;
382 return S_OK;
383 }
384
385 HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
386 {
387 HRESULT hr;
388
389 if (m_subMenuParent)
390 {
391 hr = m_subMenuParent->SetSubMenu(this, fActivate);
392 if (FAILED_UNEXPECTEDLY(hr))
393 return hr;
394 }
395
396 if (fActivate)
397 {
398 CComPtr<IOleWindow> pTopLevelWindow;
399 hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
400 if (FAILED_UNEXPECTEDLY(hr))
401 return hr;
402
403 hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
404 if (FAILED_UNEXPECTEDLY(hr))
405 return hr;
406 }
407 else
408 {
409 m_topLevelWindow = NULL;
410 }
411
412 return S_FALSE;
413 }
414
415 HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
416 {
417 if (!pguidCmdGroup)
418 return E_FAIL;
419
420 if (IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
421 {
422 if (nCmdID == 16) // set (big) icon size
423 {
424 this->m_useBigIcons = nCmdexecopt == 2;
425 return S_OK;
426 }
427 else if (nCmdID == 19) // popup-related
428 {
429 return S_FALSE;
430 }
431
432 return S_FALSE;
433 }
434
435 UNIMPLEMENTED;
436 return S_OK;
437 }
438
439 HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
440 {
441 if (IsEqualIID(guidService, SID_SMenuBandChild) ||
442 IsEqualIID(guidService, SID_SMenuBandBottom) ||
443 IsEqualIID(guidService, SID_SMenuBandBottomSelected))
444 return this->QueryInterface(riid, ppvObject);
445 WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService));
446 return E_NOINTERFACE;
447 }
448
449 HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
450 {
451 UNIMPLEMENTED;
452 return S_OK;
453 }
454
455 HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
456 {
457 switch (dwSelectType)
458 {
459 case MPOS_CHILDTRACKING:
460 if (!m_subMenuParent)
461 break;
462 // TODO: Cancel timers?
463 return m_subMenuParent->OnSelect(dwSelectType);
464 case MPOS_SELECTLEFT:
465 if (m_subMenuChild)
466 m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
467 if (!m_subMenuParent)
468 break;
469 return m_subMenuParent->OnSelect(dwSelectType);
470 case MPOS_SELECTRIGHT:
471 if (!m_subMenuParent)
472 break;
473 return m_subMenuParent->OnSelect(dwSelectType);
474 case MPOS_EXECUTE:
475 case MPOS_FULLCANCEL:
476 if (m_subMenuChild)
477 m_subMenuChild->OnSelect(dwSelectType);
478 if (!m_subMenuParent)
479 break;
480 return m_subMenuParent->OnSelect(dwSelectType);
481 case MPOS_CANCELLEVEL:
482 if (m_subMenuChild)
483 m_subMenuChild->OnSelect(dwSelectType);
484 break;
485 }
486 return S_FALSE;
487 }
488
489 HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
490 {
491 UNIMPLEMENTED;
492 return S_OK;
493 }
494
495 HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
496 {
497 UNIMPLEMENTED;
498 return S_OK;
499 }
500
501 HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
502 {
503 // HACK, so I can test for a submenu in the DeskBar
504 //UNIMPLEMENTED;
505 if (ppunkClient)
506 {
507 if (m_subMenuChild)
508 *ppunkClient = m_subMenuChild;
509 else
510 *ppunkClient = NULL;
511 }
512 return S_OK;
513 }
514
515 HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
516 {
517 //UNIMPLEMENTED;
518 //return S_OK;
519 return S_FALSE;
520 //return E_NOTIMPL;
521 }
522
523 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
524 {
525 //UNIMPLEMENTED;
526 return S_FALSE;
527 }
528
529 HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
530 {
531 if (m_SFToolbar == NULL)
532 {
533 m_SFToolbar = new CMenuSFToolbar(this);
534 }
535
536 HRESULT hr = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
537 if (FAILED_UNEXPECTEDLY(hr))
538 return hr;
539
540 if (m_site)
541 {
542 HWND hwndParent;
543
544 hr = m_site->GetWindow(&hwndParent);
545 if (FAILED_UNEXPECTEDLY(hr))
546 return hr;
547
548 hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
549 if (FAILED_UNEXPECTEDLY(hr))
550 return hr;
551
552 hr = m_SFToolbar->FillToolbar();
553 }
554
555 return hr;
556 }
557
558 HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
559 {
560 if (m_SFToolbar)
561 return m_SFToolbar->GetShellFolder(pdwFlags, ppidl, riid, ppv);
562 return E_FAIL;
563 }
564
565 HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
566 {
567 UNIMPLEMENTED;
568 return S_OK;
569 }
570
571 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
572 {
573 UNIMPLEMENTED;
574 return S_OK;
575 }
576
577 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
578 {
579 UNIMPLEMENTED;
580 return S_OK;
581 }
582
583 HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
584 {
585 *theResult = 0;
586
587 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
588 {
589 return m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
590 }
591
592 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
593 {
594 return m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
595 }
596
597 return S_FALSE;
598 }
599
600 HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
601 {
602 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
603 return S_OK;
604
605 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
606 return S_OK;
607
608 return S_FALSE;
609 }
610
611 HRESULT CMenuBand::_CallCBWithItemId(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam)
612 {
613 return _CallCB(uMsg, wParam, lParam, id);
614 }
615
616 HRESULT CMenuBand::_CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam)
617 {
618 return _CallCB(uMsg, wParam, lParam, 0, pidl);
619 }
620
621 HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPITEMIDLIST pidl)
622 {
623 if (!m_psmc)
624 return S_FALSE;
625
626 HWND hwnd;
627 GetWindow(&hwnd);
628
629 SMDATA smData = { 0 };
630 smData.punk = static_cast<IShellMenu2*>(this);
631 smData.uId = id;
632 smData.uIdParent = m_uId;
633 smData.uIdAncestor = m_uIdAncestor;
634 smData.hwnd = hwnd;
635 smData.pidlItem = pidl;
636 if (m_staticToolbar)
637 {
638 smData.hmenu = m_hmenu;
639 }
640 smData.pvUserData = NULL;
641 if (m_SFToolbar)
642 m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
643 HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
644 ILFree(smData.pidlFolder);
645 if (smData.psf)
646 smData.psf->Release();
647 return hr;
648 }
649
650 HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
651 {
652 TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
653
654 UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
655
656 if (m_menuOwner)
657 {
658 ::TrackPopupMenuEx(popup, flags, x, y, m_menuOwner, &params);
659 }
660 else
661 {
662 ::TrackPopupMenuEx(popup, flags, x, y, m_topLevelWindow, &params);
663 }
664
665 return S_OK;
666 }
667
668 HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
669 {
670 *topLevel = m_topLevelWindow;
671 return S_OK;
672 }
673
674 HRESULT CMenuBand::_OnHotItemChanged(CMenuToolbarBase * tb, INT id)
675 {
676 m_hotBar = tb;
677 m_hotItem = id;
678 if (m_staticToolbar) m_staticToolbar->OnHotItemChanged(tb, id);
679 if (m_SFToolbar) m_SFToolbar->OnHotItemChanged(tb, id);
680 return S_OK;
681 }
682
683 HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
684 {
685 HRESULT hr;
686
687 if (changeType == VK_DOWN)
688 {
689 if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
690 {
691 hr = m_SFToolbar->ChangeHotItem(VK_DOWN);
692 if (hr == S_FALSE)
693 {
694 if (m_staticToolbar)
695 return m_staticToolbar->ChangeHotItem(VK_HOME);
696 else
697 return m_SFToolbar->ChangeHotItem(VK_HOME);
698 }
699 return hr;
700 }
701 else if (m_staticToolbar && m_hotBar == m_staticToolbar)
702 {
703 hr = m_staticToolbar->ChangeHotItem(VK_DOWN);
704 if (hr == S_FALSE)
705 {
706 if (m_SFToolbar)
707 return m_SFToolbar->ChangeHotItem(VK_HOME);
708 else
709 return m_staticToolbar->ChangeHotItem(VK_HOME);
710 }
711 return hr;
712 }
713 }
714 else if (changeType == VK_UP)
715 {
716 if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
717 {
718 hr = m_staticToolbar->ChangeHotItem(VK_UP);
719 if (hr == S_FALSE)
720 {
721 if (m_SFToolbar)
722 return m_SFToolbar->ChangeHotItem(VK_END);
723 else
724 return m_staticToolbar->ChangeHotItem(VK_END);
725 }
726 return hr;
727 }
728 else if (m_SFToolbar && m_hotBar == m_SFToolbar)
729 {
730 hr = m_SFToolbar->ChangeHotItem(VK_UP);
731 if (hr == S_FALSE)
732 {
733 if (m_staticToolbar)
734 return m_staticToolbar->ChangeHotItem(VK_END);
735 else
736 return m_SFToolbar->ChangeHotItem(VK_END);
737 }
738 return hr;
739 }
740 }
741 else if (changeType == MPOS_SELECTLEFT)
742 {
743 if (m_subMenuChild)
744 m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
745 if (!m_subMenuParent)
746 return S_OK;
747 return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
748 }
749 else if (changeType == MPOS_SELECTRIGHT)
750 {
751 if (m_hotBar && m_hotItem >= 0)
752 {
753 if (m_hotBar->HasSubMenu(m_hotItem)==S_OK)
754 {
755 m_hotBar->PopupItem(m_hotItem);
756 return S_FALSE;
757 }
758 }
759 if (!m_subMenuParent)
760 return S_OK;
761 return m_subMenuParent->OnSelect(changeType);
762 }
763 else
764 {
765 if (!m_subMenuParent)
766 return S_OK;
767 return m_subMenuParent->OnSelect(changeType);
768 }
769 return S_OK;
770 }
771
772 HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude, CMenuToolbarBase * toolbar, INT item)
773 {
774 if (m_subMenuChild)
775 {
776 HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
777 if (FAILED_UNEXPECTEDLY(hr))
778 return hr;
779 }
780 if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(toolbar, item);
781 if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(toolbar, item);
782 m_subMenuChild = popup;
783 if (popup)
784 {
785 if (m_subMenuParent)
786 IUnknown_SetSite(popup, m_subMenuParent);
787 else
788 IUnknown_SetSite(popup, m_site);
789
790 popup->Popup(pAt, pExclude, MPPF_RIGHT);
791 }
792 return S_OK;
793 }
794
795 HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
796 {
797 UNIMPLEMENTED;
798 return S_OK;
799 }
800
801 HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
802 {
803 UNIMPLEMENTED;
804 return S_OK;
805 }
806
807 HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
808 {
809 UNIMPLEMENTED;
810 return S_OK;
811 }
812
813 HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
814 {
815 UNIMPLEMENTED;
816 return S_OK;
817 }
818
819 HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
820 {
821 UNIMPLEMENTED;
822 return S_OK;
823 }
824
825 HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
826 {
827 UNIMPLEMENTED;
828 return S_OK;
829 }
830
831 HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
832 {
833 UNIMPLEMENTED;
834 return S_OK;
835 }
836
837 HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
838 {
839 UNIMPLEMENTED;
840 return S_OK;
841 }
842
843 HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
844 {
845 UNIMPLEMENTED;
846 return S_OK;
847 }
848
849 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
850 {
851 UNIMPLEMENTED;
852 return S_OK;
853 }
854
855 HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
856 {
857 UNIMPLEMENTED;
858 return S_OK;
859 }
860
861 HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
862 {
863 UNIMPLEMENTED;
864 return S_OK;
865 }
866
867 HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
868 {
869 UNIMPLEMENTED;
870 return S_OK;
871 }
872
873 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
874 {
875 UNIMPLEMENTED;
876 return S_OK;
877 }
878
879 HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
880 {
881 UNIMPLEMENTED;
882 return S_OK;
883 }
884
885 HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
886 {
887 UNIMPLEMENTED;
888 return S_OK;
889 }
890
891 HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
892 {
893 UNIMPLEMENTED;
894 return S_OK;
895 }
896
897 HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
898 {
899 UNIMPLEMENTED;
900 return S_OK;
901 }
902
903 HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
904 {
905 UNIMPLEMENTED;
906 return S_OK;
907 }
908
909 HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
910 {
911 UNIMPLEMENTED;
912 return S_OK;
913 }