XTPMouseManager.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:9k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPMouseManager.cpp : implementation of the CXTPMouseManager class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPDrawHelpers.h"
  22. #include "XTPMouseManager.h"
  23. #include "XTPCommandBar.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. CThreadLocal<CXTPMouseManager> CXTPMouseManager::_xtpMouseThreadState;
  30. static CPoint ptMouse;
  31. #define TID_MOUSELEAVE 113341
  32. CXTPMouseManager::CXTPMouseManager()
  33. {
  34. m_hHookMouse = 0;
  35. m_nLock = 0;
  36. m_hwndLeave = 0;
  37. m_bForceExpanded = FALSE;
  38. m_pSelected = 0;
  39. m_bIgnoreLButtonUp = FALSE;
  40. #ifdef _AFXDLL
  41. m_pModuleState = 0;
  42. #endif
  43. SetupHook(TRUE);
  44. }
  45. CXTPMouseManager::~CXTPMouseManager()
  46. {
  47. SetupHook(FALSE);
  48. }
  49. void CXTPMouseManager::DeliverMessage(CXTPCommandBar* pCapture, WPARAM wParam, POINT pt)
  50. {
  51. if (!pCapture->GetSafeHwnd())
  52. return;
  53. switch (wParam)
  54. {
  55. case WM_MOUSEMOVE:
  56. case WM_NCMOUSEMOVE:
  57. if (pCapture->m_nLockRecurse <= 0)
  58. {
  59. pCapture->ScreenToClient(&pt);
  60. pCapture->OnMouseMove(0, pt);
  61. }
  62. break;
  63. case WM_LBUTTONDOWN:
  64. case WM_NCLBUTTONDOWN:
  65. case WM_RBUTTONDOWN:
  66. case WM_NCRBUTTONDOWN:
  67. case WM_MBUTTONDOWN:
  68. case WM_NCMBUTTONDOWN:
  69. SendTrackLost();
  70. break;
  71. case WM_LBUTTONUP:
  72. case WM_NCLBUTTONUP:
  73. if (!IsMouseLocked())
  74. SendTrackLost();
  75. break;
  76. }
  77. }
  78. CXTPCommandBar* CXTPMouseManager::HitTest(POINT point) const
  79. {
  80. HWND hWndMouse = ::WindowFromPoint(point);
  81. const CTrackArray& arrTracked = m_arrTracked;
  82. int i;
  83. for (i = (int)arrTracked.GetSize() - 1; i >= 0; i--)
  84. {
  85. CXTPCommandBar* pCommandBar = arrTracked[i];
  86. if (!pCommandBar->GetSafeHwnd())
  87. continue;
  88. int nHtCode = pCommandBar->OnMouseHitTest(point);
  89. if ((nHtCode != HTERROR) && ((nHtCode == HTCLIENT) || ::IsChild(pCommandBar->GetSafeHwnd(), hWndMouse)))
  90. {
  91. return pCommandBar;
  92. }
  93. }
  94. return NULL;
  95. }
  96. BOOL CXTPMouseManager::PreviewTackLost(CXTPCommandBar* pContextMenu, MSG* msg) const
  97. {
  98. if (!(msg->message == WM_LBUTTONDOWN || msg->message == WM_RBUTTONDOWN || msg->message == WM_MBUTTONDOWN ||
  99. msg->message == WM_NCLBUTTONDOWN || msg->message == WM_NCRBUTTONDOWN))
  100. {
  101. return FALSE;
  102. }
  103. CPoint point;
  104. GetCursorPos(&point);
  105. CXTPCommandBar* pCommandBar = HitTest(point);
  106. if (pCommandBar)
  107. {
  108. if (pCommandBar->m_nLockRecurse == 0 || pContextMenu->m_nLockRecurse != 0)
  109. return FALSE;
  110. }
  111. HWND hWndMouse = ::WindowFromPoint(point);
  112. if (m_arrTracked.GetSize() > 0)
  113. {
  114. const CTrustedArray& arrTrusted = m_arrTrusted;
  115. for (int i = 0; i < arrTrusted.GetSize(); i++)
  116. {
  117. HWND hWnd = arrTrusted[i];
  118. if (IsWindow(hWnd) && IsWindowVisible(hWnd) && CXTPWindowRect(hWnd).PtInRect(point))
  119. {
  120. return FALSE;
  121. }
  122. }
  123. if (hWndMouse)
  124. {
  125. if (GetClassLong(hWndMouse, GCL_STYLE) & CS_IME)
  126. return FALSE;
  127. }
  128. }
  129. return TRUE;
  130. }
  131. BOOL CXTPMouseManager::PreTranslateMouseEvents(WPARAM wParam, POINT point)
  132. {
  133. HWND hWndMouse = ::WindowFromPoint(point);
  134. CTrackArray& arrTracked = m_arrTracked;
  135. int i;
  136. for (i = (int)arrTracked.GetSize() - 1; i >= 0; i--)
  137. {
  138. CXTPCommandBar* pCommandBar = arrTracked[i];
  139. if (!pCommandBar->GetSafeHwnd())
  140. continue;
  141. int nHtCode = pCommandBar->OnMouseHitTest(point);
  142. if ((nHtCode != HTERROR) && ((nHtCode == HTCLIENT) || ::IsChild(pCommandBar->GetSafeHwnd(), hWndMouse)))
  143. {
  144. if (pCommandBar->m_nLockRecurse > 0 && wParam != WM_MOUSEMOVE && wParam != WM_NCMOUSEMOVE && !m_bIgnoreLButtonUp)
  145. {
  146. SendTrackLostRecurse();
  147. ptMouse = 0;
  148. }
  149. return FALSE;
  150. }
  151. }
  152. if (arrTracked.GetSize() > 0)
  153. {
  154. CTrustedArray& arrTrusted = m_arrTrusted;
  155. for (i = 0; i < arrTrusted.GetSize(); i++)
  156. {
  157. HWND hWnd = arrTrusted[i];
  158. if (IsWindow(hWnd) && IsWindowVisible(hWnd) && CXTPWindowRect(hWnd).PtInRect(point))
  159. {
  160. return FALSE;
  161. }
  162. }
  163. }
  164. if (hWndMouse && arrTracked.GetSize() > 0)
  165. {
  166. if (GetClassLong(hWndMouse, GCL_STYLE) & CS_IME)
  167. return FALSE;
  168. }
  169. for (i = 0; i < arrTracked.GetSize(); i++)
  170. {
  171. DeliverMessage(arrTracked.GetAt(i), wParam, point);
  172. }
  173. return FALSE;
  174. }
  175. LRESULT CALLBACK CXTPMouseManager::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  176. {
  177. CXTPMouseManager* pMouseManager = XTPMouseManager();
  178. if (nCode != HC_ACTION)
  179. return CallNextHookEx(pMouseManager->m_hHookMouse, nCode, wParam, lParam);
  180. PMOUSEHOOKSTRUCT pHook = (PMOUSEHOOKSTRUCT)lParam;
  181. CPoint point = pHook->pt;
  182. CTrackArray& arrTracked = pMouseManager->m_arrTracked;
  183. if (wParam == WM_LBUTTONDOWN || wParam == WM_RBUTTONDOWN)
  184. pMouseManager->m_bIgnoreLButtonUp = FALSE;
  185. if ((wParam == WM_LBUTTONUP || wParam == WM_NCLBUTTONUP) && pMouseManager->m_bIgnoreLButtonUp)
  186. {
  187. pMouseManager->m_bIgnoreLButtonUp = FALSE;
  188. return TRUE;
  189. }
  190. if (arrTracked.GetSize() != 0 && (wParam == WM_MOUSEMOVE || wParam == WM_NCMOUSEMOVE) && ptMouse == point)
  191. return TRUE;
  192. ptMouse = point;
  193. if (pMouseManager->m_arrTracked.GetSize() == 0)
  194. return CallNextHookEx(pMouseManager->m_hHookMouse, nCode, wParam, lParam);
  195. SAFE_MANAGE_STATE(pMouseManager->m_pModuleState);
  196. if (pMouseManager->PreTranslateMouseEvents(wParam, point))
  197. {
  198. return 1;
  199. }
  200. return CallNextHookEx(pMouseManager->m_hHookMouse, nCode, wParam, lParam);
  201. }
  202. void CXTPMouseManager::SetupHook(BOOL bHook)
  203. {
  204. if (bHook && m_hHookMouse == 0)
  205. {
  206. m_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadId ());
  207. }
  208. if (!bHook && m_hHookMouse)
  209. {
  210. UnhookWindowsHookEx(m_hHookMouse);
  211. m_hHookMouse = 0;
  212. }
  213. }
  214. void CXTPMouseManager::SetTrack(CXTPCommandBar* pTrack, BOOL /*bCaptureMouse*/)
  215. {
  216. #ifdef _AFXDLL
  217. m_pModuleState = AfxGetModuleState();
  218. #endif
  219. if (m_arrTracked.GetSize() == 0 && m_pSelected && m_pSelected != pTrack)
  220. m_pSelected->OnTrackEnter();
  221. if (m_arrTracked.Find(pTrack) == -1)
  222. m_arrTracked.Add(pTrack);
  223. }
  224. void CXTPMouseManager::RemoveTrack(CXTPCommandBar* pTrack)
  225. {
  226. int nIndex = m_arrTracked.Find(pTrack);
  227. if (nIndex != -1)
  228. {
  229. m_arrTracked.RemoveAt(nIndex);
  230. }
  231. if (m_arrTracked.GetSize() == 0)
  232. {
  233. RefreshCursor();
  234. }
  235. m_bIgnoreLButtonUp = FALSE;
  236. }
  237. void AFX_CDECL CXTPMouseManager::RefreshCursor()
  238. {
  239. ptMouse = CPoint(-1, -1);
  240. CPoint pt;
  241. GetCursorPos(&pt);
  242. SetCursorPos(pt.x, pt.y);
  243. }
  244. void CXTPMouseManager::SendTrackLost()
  245. {
  246. while (m_arrTracked.GetSize() > 0)
  247. {
  248. m_arrTracked[0]->OnTrackLost();
  249. }
  250. }
  251. BOOL CXTPMouseManager::IsTopParentActive(HWND hWnd)
  252. {
  253. return CXTPDrawHelpers::IsTopParentActive(hWnd);
  254. }
  255. void CALLBACK CXTPMouseManager::TrackMouseTimerProc (HWND hWnd, UINT /*uMsg*/, UINT idEvent, DWORD /*dwTime*/)
  256. {
  257. RECT    rect;
  258. POINT   pt;
  259. if (!IsWindow(hWnd))
  260. {
  261. KillTimer (hWnd, idEvent);
  262. XTPMouseManager()->m_hwndLeave = 0;
  263. return;
  264. }
  265. GetWindowRect(hWnd, &rect);
  266. ::GetCursorPos (&pt);
  267. BOOL bTopParentActive = GetParent(hWnd) == 0 || (GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP) || IsTopParentActive(hWnd);
  268. if (!::PtInRect (&rect, pt) || !bTopParentActive)
  269. {
  270. KillTimer (hWnd, idEvent);
  271. XTPMouseManager()->m_hwndLeave = 0;
  272. ::PostMessage (hWnd, WM_MOUSELEAVE, 0, 0);
  273. }
  274. }
  275. void CXTPMouseManager::TrackMouseLeave(HWND hwnd)
  276. {
  277. if (m_hwndLeave == hwnd) return;
  278. if (m_hwndLeave && hwnd != m_hwndLeave && IsWindow(m_hwndLeave))
  279. SendMessage(m_hwndLeave, WM_MOUSELEAVE, 0, 0);
  280. m_hwndLeave = hwnd;
  281. ::SetTimer (hwnd, TID_MOUSELEAVE, 50,
  282. (TIMERPROC) TrackMouseTimerProc);
  283. }
  284. void CXTPMouseManager::AddTrustedWindow(HWND hWnd)
  285. {
  286. m_arrTrusted.Add(hWnd);
  287. }
  288. void CXTPMouseManager::RemoveTrustedWindow(HWND hWnd)
  289. {
  290. m_arrTrusted.Remove(hWnd);
  291. }
  292. void CXTPMouseManager::LockTrackRecurse(BOOL bLockTrack)
  293. {
  294. for (int i = 0; i < (int)m_arrTracked.GetSize(); i++)
  295. {
  296. m_arrTracked[i]->m_nLockRecurse += bLockTrack ? +1 : -1;
  297. }
  298. }
  299. CXTPCommandBar* CXTPMouseManager::GetTopTracked() const
  300. {
  301. if (m_arrTracked.GetSize() == NULL)
  302. return NULL;
  303. return m_arrTracked.GetAt(m_arrTracked.GetSize() - 1);
  304. }
  305. BOOL CXTPMouseManager::IsTrackedLock(const CXTPCommandBar* pItem /*= NULL*/)
  306. {
  307. if (m_arrTracked.GetSize() == NULL)
  308. return FALSE;
  309. if (pItem == NULL)
  310. return TRUE;
  311. if (pItem->m_nLockRecurse > 0)
  312. return TRUE;
  313. return m_arrTracked.Find(pItem) == -1;
  314. }
  315. BOOL CXTPMouseManager::IsTrackedLockRecurse() const
  316. {
  317. if (m_arrTracked.GetSize() == 0)
  318. return FALSE;
  319. return m_arrTracked[0]->m_nLockRecurse > 0;
  320. }
  321. void CXTPMouseManager::SendTrackLostRecurse()
  322. {
  323. if (m_arrTracked.GetSize() == 0)
  324. return;
  325. BOOL bLocked = m_arrTracked[0]->m_nLockRecurse > 0;
  326. if (bLocked)
  327. for (int i = 0; i < (int)m_arrTracked.GetSize(); i++)
  328. {
  329. if (m_arrTracked[i]->m_nLockRecurse == 0)
  330. m_arrTracked[i]->OnTrackLost();
  331. }
  332. }