1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * Shell Menu Band 3*c2c66affSColin Finck * 4*c2c66affSColin Finck * Copyright 2014 David Quintana 5*c2c66affSColin Finck * 6*c2c66affSColin Finck * This library is free software; you can redistribute it and/or 7*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8*c2c66affSColin Finck * License as published by the Free Software Foundation; either 9*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10*c2c66affSColin Finck * 11*c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 12*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*c2c66affSColin Finck * Lesser General Public License for more details. 15*c2c66affSColin Finck * 16*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17*c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18*c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19*c2c66affSColin Finck */ 20*c2c66affSColin Finck #pragma once 21*c2c66affSColin Finck 22*c2c66affSColin Finck class CMenuBand; 23*c2c66affSColin Finck 24*c2c66affSColin Finck class CMenuFocusManager : 25*c2c66affSColin Finck public CComCoClass<CMenuFocusManager>, 26*c2c66affSColin Finck public CComObjectRootEx<CComMultiThreadModelNoCS> 27*c2c66affSColin Finck { 28*c2c66affSColin Finck private: 29*c2c66affSColin Finck static DWORD TlsIndex; 30*c2c66affSColin Finck 31*c2c66affSColin Finck static CMenuFocusManager * GetManager(); 32*c2c66affSColin Finck 33*c2c66affSColin Finck enum StackEntryType 34*c2c66affSColin Finck { 35*c2c66affSColin Finck NoEntry, 36*c2c66affSColin Finck MenuBarEntry, 37*c2c66affSColin Finck MenuPopupEntry, 38*c2c66affSColin Finck TrackedMenuEntry 39*c2c66affSColin Finck }; 40*c2c66affSColin Finck 41*c2c66affSColin Finck struct StackEntry 42*c2c66affSColin Finck { 43*c2c66affSColin Finck StackEntryType type; 44*c2c66affSColin Finck CMenuBand * mb; 45*c2c66affSColin Finck HMENU hmenu; 46*c2c66affSColin Finck HWND hwnd; 47*c2c66affSColin Finck }; 48*c2c66affSColin Finck 49*c2c66affSColin Finck public: 50*c2c66affSColin Finck static CMenuFocusManager * AcquireManager(); 51*c2c66affSColin Finck 52*c2c66affSColin Finck static void ReleaseManager(CMenuFocusManager * obj); 53*c2c66affSColin Finck 54*c2c66affSColin Finck private: 55*c2c66affSColin Finck static LRESULT CALLBACK s_MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); 56*c2c66affSColin Finck static LRESULT CALLBACK s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam); 57*c2c66affSColin Finck 58*c2c66affSColin Finck private: 59*c2c66affSColin Finck StackEntry * m_current; 60*c2c66affSColin Finck StackEntry * m_parent; 61*c2c66affSColin Finck StackEntry * m_menuBar; 62*c2c66affSColin Finck 63*c2c66affSColin Finck HHOOK m_hMsgFilterHook; 64*c2c66affSColin Finck HHOOK m_hGetMsgHook; 65*c2c66affSColin Finck DWORD m_threadId; 66*c2c66affSColin Finck 67*c2c66affSColin Finck BOOL m_mouseTrackDisabled; 68*c2c66affSColin Finck 69*c2c66affSColin Finck POINT m_ptPrev; 70*c2c66affSColin Finck 71*c2c66affSColin Finck HWND m_captureHwnd; 72*c2c66affSColin Finck 73*c2c66affSColin Finck HWND m_hwndUnderMouse; 74*c2c66affSColin Finck StackEntry * m_entryUnderMouse; 75*c2c66affSColin Finck 76*c2c66affSColin Finck HMENU m_selectedMenu; 77*c2c66affSColin Finck INT m_selectedItem; 78*c2c66affSColin Finck DWORD m_selectedItemFlags; 79*c2c66affSColin Finck 80*c2c66affSColin Finck BOOL m_movedSinceDown; 81*c2c66affSColin Finck HWND m_windowAtDown; 82*c2c66affSColin Finck 83*c2c66affSColin Finck HWND m_PreviousForeground; 84*c2c66affSColin Finck 85*c2c66affSColin Finck // TODO: make dynamic 86*c2c66affSColin Finck #define MAX_RECURSE 20 87*c2c66affSColin Finck StackEntry m_bandStack[MAX_RECURSE]; 88*c2c66affSColin Finck int m_bandCount; 89*c2c66affSColin Finck int m_menuDepth; 90*c2c66affSColin Finck 91*c2c66affSColin Finck HRESULT PushToArray(StackEntryType type, CMenuBand * mb, HMENU hmenu); 92*c2c66affSColin Finck HRESULT PopFromArray(StackEntryType * pType, CMenuBand ** pMb, HMENU * pHmenu); 93*c2c66affSColin Finck 94*c2c66affSColin Finck protected: 95*c2c66affSColin Finck CMenuFocusManager(); 96*c2c66affSColin Finck ~CMenuFocusManager(); 97*c2c66affSColin Finck 98*c2c66affSColin Finck public: 99*c2c66affSColin Finck 100*c2c66affSColin Finck DECLARE_NOT_AGGREGATABLE(CMenuFocusManager) 101*c2c66affSColin Finck DECLARE_PROTECT_FINAL_CONSTRUCT() 102*c2c66affSColin Finck BEGIN_COM_MAP(CMenuFocusManager) 103*c2c66affSColin Finck END_COM_MAP() 104*c2c66affSColin Finck 105*c2c66affSColin Finck private: 106*c2c66affSColin Finck LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam); 107*c2c66affSColin Finck LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); 108*c2c66affSColin Finck HRESULT PlaceHooks(); 109*c2c66affSColin Finck HRESULT RemoveHooks(); 110*c2c66affSColin Finck HRESULT UpdateFocus(); 111*c2c66affSColin Finck HRESULT IsTrackedWindow(HWND hWnd, StackEntry ** pentry = NULL); 112*c2c66affSColin Finck HRESULT IsTrackedWindowOrParent(HWND hWnd); 113*c2c66affSColin Finck 114*c2c66affSColin Finck void DisableMouseTrack(HWND parent, BOOL disableThis); 115*c2c66affSColin Finck void SetMenuCapture(HWND child); 116*c2c66affSColin Finck 117*c2c66affSColin Finck LRESULT ProcessMouseMove(MSG* msg); 118*c2c66affSColin Finck LRESULT ProcessMouseDown(MSG* msg, BOOL isLButton); 119*c2c66affSColin Finck LRESULT ProcessMouseUp(MSG* msg, BOOL isLButton); 120*c2c66affSColin Finck public: 121*c2c66affSColin Finck HRESULT PushMenuBar(CMenuBand * mb); 122*c2c66affSColin Finck HRESULT PushMenuPopup(CMenuBand * mb); 123*c2c66affSColin Finck HRESULT PushTrackedPopup(HMENU popup); 124*c2c66affSColin Finck HRESULT PopMenuBar(CMenuBand * mb); 125*c2c66affSColin Finck HRESULT PopMenuPopup(CMenuBand * mb); 126*c2c66affSColin Finck HRESULT PopTrackedPopup(HMENU popup); 127*c2c66affSColin Finck }; 128