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 #pragma once 21 22 class CMenuBand; 23 24 class CMenuFocusManager : 25 public CComCoClass<CMenuFocusManager>, 26 public CComObjectRootEx<CComMultiThreadModelNoCS> 27 { 28 private: 29 static DWORD TlsIndex; 30 31 static CMenuFocusManager * GetManager(); 32 33 enum StackEntryType 34 { 35 NoEntry, 36 MenuBarEntry, 37 MenuPopupEntry, 38 TrackedMenuEntry 39 }; 40 41 struct StackEntry 42 { 43 StackEntryType type; 44 CMenuBand * mb; 45 HMENU hmenu; 46 HWND hwnd; 47 }; 48 49 public: 50 static CMenuFocusManager * AcquireManager(); 51 52 static void ReleaseManager(CMenuFocusManager * obj); 53 54 private: 55 static LRESULT CALLBACK s_MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); 56 static LRESULT CALLBACK s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam); 57 58 private: 59 StackEntry * m_current; 60 StackEntry * m_parent; 61 StackEntry * m_menuBar; 62 63 HHOOK m_hMsgFilterHook; 64 HHOOK m_hGetMsgHook; 65 DWORD m_threadId; 66 67 BOOL m_mouseTrackDisabled; 68 69 POINT m_ptPrev; 70 71 HWND m_captureHwnd; 72 73 HWND m_hwndUnderMouse; 74 StackEntry * m_entryUnderMouse; 75 76 HMENU m_selectedMenu; 77 INT m_selectedItem; 78 DWORD m_selectedItemFlags; 79 80 BOOL m_isLButtonDown; 81 BOOL m_movedSinceDown; 82 HWND m_windowAtDown; 83 84 HWND m_PreviousForeground; 85 86 // TODO: make dynamic 87 #define MAX_RECURSE 20 88 StackEntry m_bandStack[MAX_RECURSE]; 89 int m_bandCount; 90 int m_menuDepth; 91 92 HRESULT PushToArray(StackEntryType type, CMenuBand * mb, HMENU hmenu); 93 HRESULT PopFromArray(StackEntryType * pType, CMenuBand ** pMb, HMENU * pHmenu); 94 95 protected: 96 CMenuFocusManager(); 97 ~CMenuFocusManager(); 98 99 public: 100 101 DECLARE_NOT_AGGREGATABLE(CMenuFocusManager) 102 DECLARE_PROTECT_FINAL_CONSTRUCT() 103 BEGIN_COM_MAP(CMenuFocusManager) 104 END_COM_MAP() 105 106 private: 107 LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam); 108 LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); 109 HRESULT PlaceHooks(); 110 HRESULT RemoveHooks(); 111 HRESULT UpdateFocus(); 112 HRESULT IsTrackedWindow(HWND hWnd, StackEntry ** pentry = NULL); 113 HRESULT IsTrackedWindowOrParent(HWND hWnd); 114 115 void DisableMouseTrack(HWND parent, BOOL disableThis); 116 void SetMenuCapture(HWND child); 117 118 LRESULT ProcessMouseMove(MSG* msg); 119 LRESULT ProcessMouseDown(MSG* msg, BOOL isLButton); 120 LRESULT ProcessMouseUp(MSG* msg, BOOL isLButton); 121 public: 122 HRESULT PushMenuBar(CMenuBand * mb); 123 HRESULT PushMenuPopup(CMenuBand * mb); 124 HRESULT PushTrackedPopup(HMENU popup); 125 HRESULT PopMenuBar(CMenuBand * mb); 126 HRESULT PopMenuPopup(CMenuBand * mb); 127 HRESULT PopTrackedPopup(HMENU popup); 128 }; 129