4 * Copyright 2014 David Quintana
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.
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.
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
22 #include <CommonControls.h>
23 #include <shlwapi_undoc.h>
25 #include "CMenuFocusManager.h"
26 #include "CMenuBand.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(CMenuFocus
);
30 DWORD
CMenuFocusManager::TlsIndex
= 0;
32 CMenuFocusManager
* CMenuFocusManager::GetManager()
34 return reinterpret_cast<CMenuFocusManager
*>(TlsGetValue(TlsIndex
));
37 CMenuFocusManager
* CMenuFocusManager::AcquireManager()
39 CMenuFocusManager
* obj
= NULL
;
43 if ((TlsIndex
= TlsAlloc()) == TLS_OUT_OF_INDEXES
)
51 obj
= new CComObject
<CMenuFocusManager
>();
52 TlsSetValue(TlsIndex
, obj
);
60 void CMenuFocusManager::ReleaseManager(CMenuFocusManager
* obj
)
64 TlsSetValue(TlsIndex
, NULL
);
68 LRESULT CALLBACK
CMenuFocusManager::s_GetMsgHook(INT nCode
, WPARAM wParam
, LPARAM lParam
)
70 return GetManager()->GetMsgHook(nCode
, wParam
, lParam
);
73 HRESULT
CMenuFocusManager::PushToArray(CMenuBand
* item
)
75 if (m_bandCount
>= MAX_RECURSE
)
78 m_bandStack
[m_bandCount
++] = item
;
82 HRESULT
CMenuFocusManager::PopFromArray(CMenuBand
** pItem
)
93 *pItem
= m_bandStack
[m_bandCount
];
95 m_bandStack
[m_bandCount
] = NULL
;
100 HRESULT
CMenuFocusManager::PeekArray(CMenuBand
** pItem
)
107 if (m_bandCount
<= 0)
110 *pItem
= m_bandStack
[m_bandCount
- 1];
115 CMenuFocusManager::CMenuFocusManager() :
117 m_currentFocus(NULL
),
120 m_threadId
= GetCurrentThreadId();
123 CMenuFocusManager::~CMenuFocusManager()
127 LRESULT
CMenuFocusManager::GetMsgHook(INT nCode
, WPARAM wParam
, LPARAM lParam
)
130 return CallNextHookEx(m_hHook
, nCode
, wParam
, lParam
);
132 if (nCode
== HC_ACTION
)
134 BOOL callNext
= TRUE
;
135 MSG
* msg
= reinterpret_cast<MSG
*>(lParam
);
137 // Do whatever is necessary here
139 switch (msg
->message
)
150 m_currentBand
->_MenuItemHotTrack(MPOS_FULLCANCEL
);
153 m_currentBand
->_MenuItemHotTrack(MPOS_SELECTLEFT
);
156 m_currentBand
->_MenuItemHotTrack(MPOS_SELECTRIGHT
);
159 m_currentBand
->_MenuItemHotTrack(VK_UP
);
162 m_currentBand
->_MenuItemHotTrack(VK_DOWN
);
167 //if (msg->wParam >= 'a' && msg->wParam <= 'z')
170 // PostMessage(m_currentFocus, WM_SYSCHAR, wParam, lParam);
179 return CallNextHookEx(m_hHook
, nCode
, wParam
, lParam
);
182 HRESULT
CMenuFocusManager::PlaceHooks(HWND window
)
184 //SetCapture(window);
185 m_hHook
= SetWindowsHookEx(WH_GETMESSAGE
, s_GetMsgHook
, NULL
, m_threadId
);
189 HRESULT
CMenuFocusManager::RemoveHooks(HWND window
)
191 UnhookWindowsHookEx(m_hHook
);
196 HRESULT
CMenuFocusManager::UpdateFocus(CMenuBand
* newBand
)
203 hr
= RemoveHooks(m_currentFocus
);
204 m_currentFocus
= NULL
;
205 m_currentBand
= NULL
;
209 hr
= newBand
->_GetTopLevelWindow(&newFocus
);
215 hr
= PlaceHooks(newFocus
);
220 m_currentFocus
= newFocus
;
221 m_currentBand
= newBand
;
226 HRESULT
CMenuFocusManager::PushMenu(CMenuBand
* mb
)
230 hr
= PushToArray(mb
);
234 return UpdateFocus(mb
);
237 HRESULT
CMenuFocusManager::PopMenu(CMenuBand
* mb
)
242 hr
= PopFromArray(&mbc
);
249 hr
= PeekArray(&mbc
);
251 return UpdateFocus(mbc
);