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_movedSinceDown; 81 HWND m_windowAtDown; 82 83 HWND m_PreviousForeground; 84 85 // TODO: make dynamic 86 #define MAX_RECURSE 20 87 StackEntry m_bandStack[MAX_RECURSE]; 88 int m_bandCount; 89 int m_menuDepth; 90 91 HRESULT PushToArray(StackEntryType type, CMenuBand * mb, HMENU hmenu); 92 HRESULT PopFromArray(StackEntryType * pType, CMenuBand ** pMb, HMENU * pHmenu); 93 94 protected: 95 CMenuFocusManager(); 96 ~CMenuFocusManager(); 97 98 public: 99 100 DECLARE_NOT_AGGREGATABLE(CMenuFocusManager) 101 DECLARE_PROTECT_FINAL_CONSTRUCT() 102 BEGIN_COM_MAP(CMenuFocusManager) 103 END_COM_MAP() 104 105 private: 106 LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam); 107 LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); 108 HRESULT PlaceHooks(); 109 HRESULT RemoveHooks(); 110 HRESULT UpdateFocus(); 111 HRESULT IsTrackedWindow(HWND hWnd, StackEntry ** pentry = NULL); 112 HRESULT IsTrackedWindowOrParent(HWND hWnd); 113 114 void DisableMouseTrack(HWND parent, BOOL disableThis); 115 void SetMenuCapture(HWND child); 116 117 LRESULT ProcessMouseMove(MSG* msg); 118 LRESULT ProcessMouseDown(MSG* msg, BOOL isLButton); 119 LRESULT ProcessMouseUp(MSG* msg, BOOL isLButton); 120 public: 121 HRESULT PushMenuBar(CMenuBand * mb); 122 HRESULT PushMenuPopup(CMenuBand * mb); 123 HRESULT PushTrackedPopup(HMENU popup); 124 HRESULT PopMenuBar(CMenuBand * mb); 125 HRESULT PopMenuPopup(CMenuBand * mb); 126 HRESULT PopTrackedPopup(HMENU popup); 127 }; 128