ReactOS 0.4.16-dev-1163-gec5b142
CMenuFocusManager.cpp
Go to the documentation of this file.
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
21/*
22This file implements the CMenuFocusManager class.
23
24This class manages the shell menus, by overriding the hot-tracking behaviour.
25
26For the shell menus, it uses a GetMessage hook,
27where it intercepts messages directed to the menu windows.
28
29In order to show submenus using system popups, it also has a MessageFilter hook.
30
31The menu is tracked using a stack structure. When a CMenuBand wants to open a submenu,
32it pushes the submenu band, or HMENU to track in case of system popups,
33and when the menu has closed, it pops the same pointer or handle.
34
35While a shell menu is open, it overrides the menu toolbar's hottracking behaviour,
36using its own logic to track both the active menu item, and the opened submenu's parent item.
37
38While a system popup is open, it tracks the mouse movements so that it can cancel the popup,
39and switch to another submenu when the mouse goes over another item from the parent.
40
41*/
42#include "shellmenu.h"
43#include <windowsx.h>
44#include <commoncontrols.h>
45#include <shlwapi_undoc.h>
46
47#include "CMenuFocusManager.h"
48#include "CMenuToolbars.h"
49#include "CMenuBand.h"
50
51#if DBG
52# undef _ASSERT
53# define _ASSERT(x) DbgAssert(!!(x), __FILE__, __LINE__, #x)
54
55bool DbgAssert(bool x, const char * filename, int line, const char * expr)
56{
57 if (!x)
58 {
59 char szMsg[512];
60 const char *fname;
61
62 fname = strrchr(filename, '\\');
63 if (fname == NULL)
64 {
65 fname = strrchr(filename, '/');
66 }
67
68 if (fname == NULL)
69 fname = filename;
70 else
71 fname++;
72
73 sprintf(szMsg, "%s:%d: Assertion failed: %s\n", fname, line, expr);
74
75 OutputDebugStringA(szMsg);
76
78 }
79 return x;
80}
81#else
82# undef _ASSERT
83# define _ASSERT(x) (!!(x))
84#endif
85
87
89
90// Gets the thread's assigned manager without refcounting
92{
93 return reinterpret_cast<CMenuFocusManager *>(TlsGetValue(TlsIndex));
94}
95
96// Obtains a manager for the thread, with refcounting
98{
100
101 if (!TlsIndex)
102 {
104 return NULL;
105 }
106
107 obj = GetManager();
108
109 if (!obj)
110 {
111 obj = new CComObject<CMenuFocusManager>();
113 }
114
115 obj->AddRef();
116
117 return obj;
118}
119
120// Releases a previously acquired manager, and deletes it if the refcount reaches 0
122{
123 if (!obj->Release())
124 {
126 }
127}
128
130{
131 return GetManager()->MsgFilterHook(nCode, wParam, lParam);
132}
133
135{
136 return GetManager()->GetMsgHook(nCode, wParam, lParam);
137}
138
140{
142 return E_OUTOFMEMORY;
143
147 m_bandCount++;
148
149 return S_OK;
150}
151
153{
154 if (pType) *pType = NoEntry;
155 if (pMb) *pMb = NULL;
156 if (pHmenu) *pHmenu = NULL;
157
158 if (m_bandCount <= 0)
159 return S_FALSE;
160
161 m_bandCount--;
162
163 if (pType) *pType = m_bandStack[m_bandCount].type;
164 if (*pType == TrackedMenuEntry)
165 {
166 if (pHmenu) *pHmenu = m_bandStack[m_bandCount].hmenu;
167 }
168 else
169 {
170 if (pMb) *pMb = m_bandStack[m_bandCount].mb;
171 }
172
173 return S_OK;
174}
175
177 m_current(NULL),
178 m_parent(NULL),
179 m_hMsgFilterHook(NULL),
180 m_hGetMsgHook(NULL),
181 m_mouseTrackDisabled(FALSE),
182 m_captureHwnd(0),
183 m_hwndUnderMouse(NULL),
184 m_entryUnderMouse(NULL),
185 m_selectedMenu(NULL),
186 m_selectedItem(0),
187 m_selectedItemFlags(0),
188 m_movedSinceDown(FALSE),
189 m_windowAtDown(NULL),
190 m_PreviousForeground(NULL),
191 m_bandCount(0),
192 m_menuDepth(0)
193{
194 m_ptPrev.x = 0;
195 m_ptPrev.y = 0;
197}
198
200{
201}
202
203// Used so that the toolbar can properly ignore mouse events, when the menu is being used with the keyboard
205{
206 BOOL bDisable = FALSE;
207 BOOL lastDisable = FALSE;
208
209 int i = m_bandCount;
210 while (--i >= 0)
211 {
213
214 if (entry.type != TrackedMenuEntry)
215 {
216 HWND hwnd;
217 HRESULT hr = entry.mb->_GetTopLevelWindow(&hwnd);
219 break;
220
221 if (hwnd == parent)
222 {
223 lastDisable = disableThis;
224 entry.mb->_DisableMouseTrack(disableThis);
225 bDisable = TRUE;
226 }
227 else
228 {
229 lastDisable = bDisable;
230 entry.mb->_DisableMouseTrack(bDisable);
231 }
232 }
233 }
234 m_mouseTrackDisabled = lastDisable;
235}
236
238{
239 if (m_captureHwnd != child)
240 {
241 if (child)
242 {
245 TRACE("Capturing %p\n", child);
246 }
247 else
248 {
251 TRACE("Capture is now off\n");
252 }
253
254 }
255}
256
258{
259 if (pentry)
260 *pentry = NULL;
261
262 for (int i = m_bandCount; --i >= 0;)
263 {
265
266 if (entry.type != TrackedMenuEntry)
267 {
268 HRESULT hr = entry.mb->IsWindowOwner(hWnd);
270 return hr;
271 if (hr == S_OK)
272 {
273 if (pentry)
274 *pentry = &entry;
275 return S_OK;
276 }
277 }
278 }
279
280 return S_FALSE;
281}
282
284{
285 for (int i = m_bandCount; --i >= 0;)
286 {
288
289 if (entry.type != TrackedMenuEntry)
290 {
291 HRESULT hr = entry.mb->IsWindowOwner(hWnd);
293 return hr;
294 if (hr == S_OK)
295 return S_OK;
296 if (entry.mb->_IsPopup() == S_OK)
297 {
298 CComPtr<IUnknown> site;
299 CComPtr<IOleWindow> pw;
300 hr = entry.mb->GetSite(IID_PPV_ARG(IUnknown, &site));
302 continue;
303 hr = IUnknown_QueryService(site, SID_SMenuBandParent, IID_PPV_ARG(IOleWindow, &pw));
305 continue;
306
307 HWND hParent;
308 if (pw->GetWindow(&hParent) == S_OK && hParent == hWnd)
309 return S_OK;
310 }
311 }
312 }
313
314 return S_FALSE;
315}
316
318{
319 HWND child;
320 int iHitTestResult = -1;
321
322 POINT pt2 = { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) };
323 ClientToScreen(msg->hwnd, &pt2);
324
325 POINT pt = msg->pt;
326
327 // Don't do anything if another window is capturing the mouse.
328 HWND cCapture = ::GetCapture();
329 if (cCapture && cCapture != m_captureHwnd && m_current->type != TrackedMenuEntry)
330 return TRUE;
331
333
334 m_ptPrev = pt;
335
337
340 {
341 TRACE("MouseMove\n");
342 }
343
344 BOOL isTracking = FALSE;
345 if (entry && (entry->type == MenuBarEntry || m_current->type != TrackedMenuEntry))
346 {
348 iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
349 isTracking = entry->mb->_IsTracking();
350
351 if (iHitTestResult < -1)
352 {
353 // TB_HITTEST would return negative numbers for separators
354 iHitTestResult = -iHitTestResult;
355 }
356 else if (iHitTestResult == -1)
357 {
358 // TB_HITTEST would return -1 in two cases:
359 // 1. the mouse is outside the toolbar;
360 // 2. the mouse is over the first item, and that item is a separator.
361 // Confirm the second scenario by checking first item's rect.
362 RECT rc;
364 if (PtInRect(&rc, pt))
365 iHitTestResult = 1;
366 }
367
368 if (SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE)
369 {
370 // The current tracked item has changed, notify the toolbar
371
372 TRACE("Hot item tracking detected a change (capture=%p / cCapture=%p)...\n", m_captureHwnd, cCapture);
374 if (isTracking && iHitTestResult >= 0 && m_current->type == TrackedMenuEntry)
375 SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0);
376 PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, MAKELPARAM(isTracking, TRUE));
378 return FALSE;
379 }
380 }
381
383 {
384 // Mouse moved away from a tracked window
386 {
388 }
389 }
390
391 if (m_hwndUnderMouse != child)
392 {
393 if (entry)
394 {
395 // Mouse moved to a tracked window
397 {
398 ScreenToClient(child, &pt2);
399 SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y));
400 }
401 }
402
405 }
406
408 {
411 }
412
413 return TRUE;
414}
415
417{
418 HWND child;
419 int iHitTestResult = -1;
420
421 TRACE("ProcessMouseDown %d %d %d\n", msg->message, msg->wParam, msg->lParam);
422
423 // Don't do anything if another window is capturing the mouse.
424 HWND cCapture = ::GetCapture();
425 if (cCapture && cCapture != m_captureHwnd && m_current->type != TrackedMenuEntry)
426 {
427 TRACE("Foreign capture active.\n");
428 return TRUE;
429 }
430
431 POINT pt = msg->pt;
432
434
437 {
438 TRACE("Foreign window detected.\n");
439 return TRUE;
440 }
441
442 if (entry->type == MenuBarEntry)
443 {
444 if (entry != m_current)
445 {
446 TRACE("Menubar with popup active.\n");
447 return TRUE;
448 }
449 }
450
451 if (entry)
452 {
454 iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
455
456 if (iHitTestResult >= 0)
457 {
458 TRACE("MouseDown send %d\n", iHitTestResult);
459 entry->mb->_MenuBarMouseDown(child, iHitTestResult, isLButton);
460 }
461 }
462
463 msg->message = WM_NULL;
464
467
468 TRACE("MouseDown end\n");
469
470 return TRUE;
471}
472
474{
475 HWND child;
476 int iHitTestResult = -1;
477
478 TRACE("ProcessMouseUp %d %d %d\n", msg->message, msg->wParam, msg->lParam);
479
480 // Don't do anything if another window is capturing the mouse.
481 HWND cCapture = ::GetCapture();
482 if (cCapture && cCapture != m_captureHwnd && m_current->type != TrackedMenuEntry)
483 return TRUE;
484
485 POINT pt = msg->pt;
486
488
491 return TRUE;
492
493 if (entry)
494 {
496 iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
497
498 if (iHitTestResult >= 0)
499 {
500 TRACE("MouseUp send %d\n", iHitTestResult);
501 entry->mb->_MenuBarMouseUp(child, iHitTestResult, isLButton);
502 }
503 }
504
505 return TRUE;
506}
507
509{
510 if (nCode < 0)
511 return CallNextHookEx(m_hMsgFilterHook, nCode, hookWParam, hookLParam);
512
513 if (nCode == MSGF_MENU)
514 {
515 BOOL callNext = TRUE;
516 MSG* msg = reinterpret_cast<MSG*>(hookLParam);
517
518 switch (msg->message)
519 {
520 case WM_LBUTTONDOWN:
521 case WM_RBUTTONDOWN:
523 {
524 POINT pt = msg->pt;
526 BOOL hoveringMenuBar = m_menuBar->mb->IsWindowOwner(child) == S_OK;
527 if (hoveringMenuBar)
528 {
530 }
531 }
532 break;
533 case WM_MOUSEMOVE:
534 callNext = ProcessMouseMove(msg);
535 break;
536 case WM_INITMENUPOPUP:
537 TRACE("WM_INITMENUPOPUP %p %p\n", msg->wParam, msg->lParam);
538 m_selectedMenu = reinterpret_cast<HMENU>(msg->lParam);
539 m_selectedItem = -1;
541 break;
542 case WM_MENUSELECT:
543 TRACE("WM_MENUSELECT %p %p\n", msg->wParam, msg->lParam);
544 m_selectedMenu = reinterpret_cast<HMENU>(msg->lParam);
546 m_selectedItemFlags = HIWORD(msg->wParam);
547 break;
548 case WM_KEYDOWN:
549 switch (msg->wParam)
550 {
551 case VK_LEFT:
553 {
555 }
556 break;
557 case VK_RIGHT:
559 {
561 }
562 break;
563 }
564 break;
565 }
566
567 if (!callNext)
568 return 1;
569 }
570
571 return CallNextHookEx(m_hMsgFilterHook, nCode, hookWParam, hookLParam);
572}
573
575{
576 BOOL isLButton = FALSE;
577 if (nCode < 0)
578 return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam);
579
580 if (nCode == HC_ACTION)
581 {
582 BOOL callNext = TRUE;
583 MSG* msg = reinterpret_cast<MSG*>(hookLParam);
584 POINT pt = msg->pt;
585
586 switch (msg->message)
587 {
589 if (m_captureHwnd)
590 {
591 TRACE("Capture lost.\n");
593 }
594 break;
595
596 case WM_NCLBUTTONDOWN:
597 case WM_LBUTTONDBLCLK:
598 case WM_LBUTTONDOWN:
599 isLButton = TRUE;
600 TRACE("LB\n");
601
603 {
604 POINT pt = msg->pt;
606 BOOL hoveringMenuBar = m_menuBar->mb->IsWindowOwner(child) == S_OK;
607 if (hoveringMenuBar)
608 {
609 m_current->mb->_MenuItemSelect(MPOS_FULLCANCEL);
610 break;
611 }
612 }
613
615 {
617
619 {
620 m_current->mb->_MenuItemSelect(MPOS_FULLCANCEL);
621 break;
622 }
623 }
624
625 ProcessMouseDown(msg, isLButton);
626
627 break;
628 case WM_NCRBUTTONUP:
629 case WM_RBUTTONUP:
630 ProcessMouseUp(msg, isLButton);
631 break;
632 case WM_NCLBUTTONUP:
633 case WM_LBUTTONUP:
634 isLButton = TRUE;
635 ProcessMouseUp(msg, isLButton);
636 break;
637 case WM_MOUSEMOVE:
638 callNext = ProcessMouseMove(msg);
639 break;
640 case WM_MOUSELEAVE:
641 callNext = ProcessMouseMove(msg);
642 //callNext = ProcessMouseLeave(msg);
643 break;
644 case WM_SYSKEYDOWN:
645 case WM_KEYDOWN:
647 {
649 switch (msg->wParam)
650 {
651 case VK_ESCAPE:
652 case VK_MENU:
653 case VK_LMENU:
654 case VK_RMENU:
655 m_current->mb->_MenuItemSelect(MPOS_FULLCANCEL);
656 break;
657 case VK_RETURN:
658 m_current->mb->_MenuItemSelect(MPOS_EXECUTE);
659 break;
660 case VK_LEFT:
662 break;
663 case VK_RIGHT:
665 break;
666 case VK_UP:
668 break;
669 case VK_DOWN:
671 break;
672 }
673 msg->message = WM_NULL;
674 msg->lParam = 0;
675 msg->wParam = 0;
676 }
677 break;
678 }
679
680 if (!callNext)
681 return 1;
682 }
683
684 return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam);
685}
686
688{
689 if (m_hGetMsgHook)
690 {
691 WARN("GETMESSAGE hook already placed!\n");
692 return S_OK;
693 }
695 {
696 WARN("MSGFILTER hook already placed!\n");
697 return S_OK;
698 }
700 {
701 TRACE("Entering MSGFILTER hook...\n");
703 }
704 else
705 {
706 TRACE("Entering GETMESSAGE hook...\n");
708 }
709 return S_OK;
710}
711
713{
715 {
716 TRACE("Removing MSGFILTER hook...\n");
719 }
720 if (m_hGetMsgHook)
721 {
722 TRACE("Removing GETMESSAGE hook...\n");
725 }
726 return S_OK;
727}
728
729// Used to update the tracking info to account for a change in the top-level menu
731{
732 HRESULT hr;
733 StackEntry * old = m_current;
734
735 TRACE("UpdateFocus\n");
736
737 // Assign the new current item
738 if (m_bandCount > 0)
740 else
741 m_current = NULL;
742
743 // Remove the menu capture if necesary
745 {
747 if (old && old->type == MenuPopupEntry && m_PreviousForeground)
748 {
751 }
752 }
753
754 // Obtain the top-level window for the new active menu
756 {
759 return hr;
760 }
761
762 // Refresh the parent pointer
763 if (m_bandCount >= 2)
764 {
767 }
768 else
769 {
770 m_parent = NULL;
771 }
772
773 // Refresh the menubar pointer, if applicable
774 if (m_bandCount >= 1 && m_bandStack[0].type == MenuBarEntry)
775 {
776 m_menuBar = &(m_bandStack[0]);
777 }
778 else
779 {
780 m_menuBar = NULL;
781 }
782
783 // Remove the old hooks if the menu type changed, or we don't have a menu anymore
784 if (old && (!m_current || old->type != m_current->type))
785 {
787 {
789 }
790
791 hr = RemoveHooks();
793 return hr;
794 }
795
796 // And place new ones if necessary
797 if (m_current && (!old || old->type != m_current->type))
798 {
799 hr = PlaceHooks();
801 return hr;
802 }
803
804 // Give the user a chance to move the mouse to the new menu
805 if (m_parent)
806 {
808 }
809
811 {
812 if (m_captureHwnd == NULL)
813 {
814 // We need to restore the capture after a non-shell submenu or context menu is shown
815 StackEntry * topMenu = m_bandStack;
816 if (topMenu->type == MenuBarEntry)
817 topMenu++;
818
819 // Get the top-level window from the top popup
820 CComPtr<IServiceProvider> bandSite;
821 CComPtr<IOleWindow> deskBar;
822 hr = topMenu->mb->GetSite(IID_PPV_ARG(IServiceProvider, &bandSite));
823 if (FAILED(hr))
824 goto NoCapture;
825 hr = bandSite->QueryService(SID_SMenuPopup, IID_PPV_ARG(IOleWindow, &deskBar));
826 if (FAILED(hr))
827 goto NoCapture;
828
829 CComPtr<IOleWindow> deskBarSite;
830 hr = IUnknown_GetSite(deskBar, IID_PPV_ARG(IOleWindow, &deskBarSite));
831 if (FAILED(hr))
832 goto NoCapture;
833
834 // FIXME: Find the correct place for this
835 HWND hWndOwner;
836 hr = deskBarSite->GetWindow(&hWndOwner);
837 if (FAILED(hr))
838 goto NoCapture;
839
841 if (m_PreviousForeground != hWndOwner)
842 ::SetForegroundWindow(hWndOwner);
843 else
845
846 // Get the HWND of the top-level window
847 HWND hWndSite;
848 hr = deskBar->GetWindow(&hWndSite);
849 if (FAILED(hr))
850 goto NoCapture;
851 SetMenuCapture(hWndSite);
852 }
853NoCapture:
854
856 {
857 if (old && old->type == TrackedMenuEntry)
858 {
859 // FIXME: Debugging code, probably not right
860 POINT pt2;
861 RECT rc2;
862 GetCursorPos(&pt2);
865 if (PtInRect(&rc2, pt2))
867 else
869 }
870 }
871 }
872
874
875 return S_OK;
876}
877
878// Begin tracking top-level menu bar (for file browser windows)
880{
881 TRACE("PushMenuBar %p\n", mb);
882
883 mb->AddRef();
884
885 _ASSERT(m_bandCount == 0);
886
889 return hr;
890
891 return UpdateFocus();
892}
893
894// Begin tracking a shell menu popup (start menu or submenus)
896{
897 TRACE("PushTrackedPopup %p\n", mb);
898
899 mb->AddRef();
900
902
905 return hr;
906
907 hr = UpdateFocus();
908
909 m_menuDepth++;
910
912 {
915 }
916
917 return hr;
918}
919
920// Begin tracking a system popup submenu (submenu of the file browser windows)
922{
923 TRACE("PushTrackedPopup %p\n", popup);
924
925 _ASSERT(m_bandCount > 0);
927
930 return hr;
931
932 TRACE("PushTrackedPopup %p\n", popup);
933 m_selectedMenu = popup;
934 m_selectedItem = -1;
936
937 return UpdateFocus();
938}
939
940// Stop tracking the menubar
942{
944 CMenuBand * mbc;
945 HRESULT hr;
946
947 TRACE("PopMenuBar %p\n", mb);
948
950 {
952 }
953
954 hr = PopFromArray(&type, &mbc, NULL);
956 {
957 UpdateFocus();
958 return hr;
959 }
960
962 if (type != MenuBarEntry)
963 return E_FAIL;
964
965 if (!mbc)
966 return E_FAIL;
967
968 mbc->_SetParentBand(NULL);
969
970 mbc->Release();
971
972 hr = UpdateFocus();
974 return hr;
975
976 if (m_current)
977 {
980 }
981
982 return S_OK;
983}
984
985// Stop tracking a shell menu
987{
989 CMenuBand * mbc;
990 HRESULT hr;
991
992 TRACE("PopMenuPopup %p\n", mb);
993
995 {
997 }
998
999 m_menuDepth--;
1000
1001 hr = PopFromArray(&type, &mbc, NULL);
1003 {
1004 UpdateFocus();
1005 return hr;
1006 }
1007
1009 if (type != MenuPopupEntry)
1010 return E_FAIL;
1011
1012 if (!mbc)
1013 return E_FAIL;
1014
1015 mbc->_SetParentBand(NULL);
1016
1017 mbc->Release();
1018
1019 hr = UpdateFocus();
1021 return hr;
1022
1023 if (m_current)
1024 {
1027 }
1028
1029 return S_OK;
1030}
1031
1032// Stop tracking a system popup submenu
1034{
1036 HMENU hmenu;
1037 HRESULT hr;
1038
1039 TRACE("PopTrackedPopup %p\n", popup);
1040
1041 hr = PopFromArray(&type, NULL, &hmenu);
1043 {
1044 UpdateFocus();
1045 return hr;
1046 }
1047
1049 if (type != TrackedMenuEntry)
1050 return E_FAIL;
1051
1052 if (hmenu != popup)
1053 return E_FAIL;
1054
1055 hr = UpdateFocus();
1057 return hr;
1058
1059 return S_OK;
1060}
#define _ASSERT(x)
#define MAX_RECURSE
#define WM_USER_CHANGETRACKEDITEM
Definition: CMenuToolbars.h:26
#define WM_USER_ISTRACKEDITEM
Definition: CMenuToolbars.h:25
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: precomp.h:61
STDMETHOD() IsWindowOwner(HWND hWnd) override
Definition: CMenuBand.cpp:759
HRESULT _GetTopLevelWindow(HWND *topLevel)
Definition: CMenuBand.cpp:885
STDMETHOD() GetSite(REFIID riid, PVOID *ppvSite) override
Definition: CMenuBand.cpp:251
HRESULT _MenuItemSelect(DWORD changeType)
Definition: CMenuBand.cpp:965
HRESULT _SetParentBand(CMenuBand *parent)
Definition: CMenuBand.cpp:616
HRESULT _ChangeHotItem(CMenuToolbarBase *tb, INT id, DWORD dwFlags)
Definition: CMenuBand.cpp:891
HRESULT _SetChildBand(CMenuBand *child)
Definition: CMenuBand.cpp:605
HRESULT _BeforeCancelPopup()
Definition: CMenuBand.cpp:1112
static CMenuFocusManager * AcquireManager()
HRESULT PopFromArray(StackEntryType *pType, CMenuBand **pMb, HMENU *pHmenu)
LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
HRESULT PopMenuPopup(CMenuBand *mb)
LRESULT ProcessMouseMove(MSG *msg)
StackEntry * m_entryUnderMouse
static LRESULT CALLBACK s_MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam)
static void ReleaseManager(CMenuFocusManager *obj)
HRESULT IsTrackedWindow(HWND hWnd, StackEntry **pentry=NULL)
LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam)
static LRESULT CALLBACK s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
HRESULT IsTrackedWindowOrParent(HWND hWnd)
HRESULT PushTrackedPopup(HMENU popup)
LRESULT ProcessMouseUp(MSG *msg, BOOL isLButton)
HRESULT PushMenuPopup(CMenuBand *mb)
HRESULT PushToArray(StackEntryType type, CMenuBand *mb, HMENU hmenu)
void SetMenuCapture(HWND child)
static CMenuFocusManager * GetManager()
void DisableMouseTrack(HWND parent, BOOL disableThis)
LRESULT ProcessMouseDown(MSG *msg, BOOL isLButton)
StackEntry * m_current
HRESULT PopTrackedPopup(HMENU popup)
StackEntry * m_parent
HRESULT PopMenuBar(CMenuBand *mb)
StackEntry * m_menuBar
static DWORD TlsIndex
HRESULT PushMenuBar(CMenuBand *mb)
StackEntry m_bandStack[MAX_RECURSE]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR rc2[]
Definition: oid.c:1216
#define CALLBACK
Definition: compat.h:35
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:65
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1100
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1276
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1501
HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
Definition: ordinal.c:2642
#define pt(x, y)
Definition: drawing.c:79
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
ULONG AddRef()
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static IActiveScriptSite * site
Definition: script.c:149
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static HWND child
Definition: cursoricon.c:298
static HMENU hmenu
Definition: win.c:66
#define HICF_MOUSE
Definition: commctrl.h:1326
#define WM_MOUSELEAVE
Definition: commctrl.h:4980
#define TB_GETITEMRECT
Definition: commctrl.h:1133
#define TB_HITTEST
Definition: commctrl.h:1268
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: query.h:86
Definition: parser.c:49
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
char mbc
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define TLS_OUT_OF_INDEXES
Definition: winbase.h:576
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:300
#define GET_X_LPARAM(lp)
Definition: windowsx.h:299
#define S_FALSE
Definition: winerror.h:2357
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define GA_ROOT
Definition: winuser.h:2800
#define MAKELPARAM(l, h)
Definition: winuser.h:4019
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define WM_CAPTURECHANGED
Definition: winuser.h:1819
#define WH_MSGFILTER
Definition: winuser.h:29
#define WM_CANCELMODE
Definition: winuser.h:1646
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1789
BOOL WINAPI SetForegroundWindow(_In_ HWND)
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3032
#define HC_ACTION
Definition: winuser.h:48
#define WM_RBUTTONUP
Definition: winuser.h:1791
#define VK_UP
Definition: winuser.h:2236
#define WM_MOUSEMOVE
Definition: winuser.h:1786
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define WM_LBUTTONDOWN
Definition: winuser.h:1787
#define SetWindowsHookEx
Definition: winuser.h:5876
#define MF_POPUP
Definition: winuser.h:136
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define WM_RBUTTONDOWN
Definition: winuser.h:1790
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define VK_RETURN
Definition: winuser.h:2212
#define WM_INITMENUPOPUP
Definition: winuser.h:1757
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
#define VK_RMENU
Definition: winuser.h:2298
#define MSGF_MENU
Definition: winuser.h:1186
#define WM_NULL
Definition: winuser.h:1618
#define SendMessage
Definition: winuser.h:5863
#define WM_LBUTTONUP
Definition: winuser.h:1788
#define PostMessage
Definition: winuser.h:5852
#define WH_GETMESSAGE
Definition: winuser.h:33
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define VK_LEFT
Definition: winuser.h:2235
#define VK_RIGHT
Definition: winuser.h:2237
#define WM_NCLBUTTONUP
Definition: winuser.h:1704
#define VK_DOWN
Definition: winuser.h:2238
HWND WINAPI WindowFromPoint(_In_ POINT)
#define WM_NCRBUTTONUP
Definition: winuser.h:1707
#define WM_KEYDOWN
Definition: winuser.h:1726
#define WM_MENUSELECT
Definition: winuser.h:1758
#define VK_ESCAPE
Definition: winuser.h:2225
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
Definition: window.c:929
#define WM_SYSKEYDOWN
Definition: winuser.h:1730
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1703
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define VK_LMENU
Definition: winuser.h:2297
#define VK_MENU
Definition: winuser.h:2215
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
#define IID_PPV_ARG(Itype, ppType)