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