ExtMouseCaptureSink.cpp
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:6k
源码类别:

界面编程

开发平台:

Visual C++

  1. // This is part of the Professional User Interface Suite library.
  2. // Copyright (C) 2001-2009 FOSS Software, Inc.
  3. // All rights reserved.
  4. //
  5. // http://www.prof-uis.com
  6. // mailto:support@prof-uis.com
  7. //
  8. // This source code can be used, modified and redistributed
  9. // under the terms of the license agreement that is included
  10. // in the Professional User Interface Suite package.
  11. //
  12. // Warranties and Disclaimers:
  13. // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
  14. // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  16. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
  17. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
  18. // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
  19. // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
  20. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  21. #include "stdafx.h"
  22. #if (!defined __EXT_MOUSECAPTURESINK_H)
  23. #include <../Src/ExtMouseCaptureSink.h>
  24. #endif
  25. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  26. #if (!defined __EXT_POPUP_MENU_WND_H)
  27. #include <ExtPopupMenuWnd.h>
  28. #endif
  29. #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  30. #ifdef _DEBUG
  31. #define new DEBUG_NEW
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CExtMouseCaptureSink
  37. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  38. volatile HHOOK CExtMouseCaptureSink::g_hMouseHook = NULL;
  39. volatile HWND CExtMouseCaptureSink::g_hWndCapture = NULL;
  40. CCriticalSection CExtMouseCaptureSink::g_cs;
  41. #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  42. CExtMouseCaptureSink::CExtMouseCaptureSink()
  43. {
  44. }
  45. CExtMouseCaptureSink::~CExtMouseCaptureSink()
  46. {
  47. }
  48. HWND CExtMouseCaptureSink::SetCapture( HWND hWnd )
  49. {
  50. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  51. if( hWnd == NULL
  52. || ( ! ::IsWindow(hWnd) )
  53. )
  54. {
  55. ReleaseCapture();
  56. return NULL;
  57. }
  58. HWND hWndOldCapture = NULL;
  59. CSingleLock _slo( &g_cs, TRUE );
  60. if( g_hMouseHook == NULL )
  61. {
  62. ASSERT( g_hWndCapture == NULL );
  63. g_hMouseHook =
  64. ::SetWindowsHookEx(
  65. WH_MOUSE,
  66. _HookMouseProc, 
  67. 0,
  68. ::GetCurrentThreadId()
  69. );
  70. ASSERT( g_hMouseHook != NULL );
  71. }
  72. else
  73. {
  74. ASSERT( g_hWndCapture != NULL );
  75. hWndOldCapture = g_hWndCapture;
  76. }
  77. if( g_hMouseHook != NULL )
  78. g_hWndCapture = hWnd;
  79. else
  80. {
  81. hWnd = g_hWndCapture = NULL;
  82. }
  83. _slo.Unlock();
  84. if( hWndOldCapture != NULL
  85. && ::IsWindow( hWndOldCapture )
  86. )
  87. ::SendMessage( hWndOldCapture, WM_CAPTURECHANGED, 0L, LPARAM(hWnd) );
  88. ///// (debug/preview) ::SendMessage( hWnd, WM_CAPTURECHANGED, 0L, LPARAM(hWnd) );
  89. return hWnd;
  90. #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  91. return ::SetCapture( hWnd );
  92. #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  93. }
  94. HWND CExtMouseCaptureSink::GetCapture()
  95. {
  96. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  97. return g_hWndCapture;
  98. #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  99. return ::GetCapture();
  100. #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  101. }
  102. BOOL CExtMouseCaptureSink::ReleaseCapture()
  103. {
  104. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  105. if( g_hWndCapture == NULL )
  106. return TRUE;
  107. HWND hWndOldCapture = NULL;
  108. CSingleLock _slo( &g_cs, TRUE );
  109. if( g_hMouseHook != NULL )
  110. {
  111. ASSERT( g_hWndCapture != NULL );
  112. ::UnhookWindowsHookEx( g_hMouseHook );
  113. g_hMouseHook = NULL;
  114. hWndOldCapture = g_hWndCapture;
  115. g_hWndCapture = NULL;
  116. }
  117. else
  118. {
  119. ASSERT( g_hWndCapture == NULL );
  120. }
  121. _slo.Unlock();
  122. if( hWndOldCapture != NULL
  123. && ::IsWindow( hWndOldCapture )
  124. )
  125. ::SendMessage( hWndOldCapture, WM_CAPTURECHANGED, 0L, 0L );
  126. return TRUE;
  127. #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  128. return ::ReleaseCapture();
  129. #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  130. }
  131. #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS
  132. LRESULT CALLBACK CExtMouseCaptureSink::_HookMouseProc(
  133. int nCode,      // hook code
  134. WPARAM wParam,  // message identifier
  135. LPARAM lParam   // mouse coordinates
  136. )
  137. {
  138. __PROF_UIS_MANAGE_STATE;
  139. MOUSEHOOKSTRUCT * lpMS = (MOUSEHOOKSTRUCT*)lParam;
  140. ASSERT( lpMS != NULL );
  141. HWND hWndHook = (HWND)g_hWndCapture;
  142. if( lpMS->hwnd != hWndHook
  143. && hWndHook != NULL
  144. && ::IsWindow(hWndHook)
  145. )
  146. {
  147. UINT nMsgToSend = WM_NULL;
  148. switch( wParam )
  149. {
  150. case WM_MOUSEMOVE:
  151. case WM_LBUTTONDOWN:
  152. case WM_LBUTTONUP:
  153. case WM_LBUTTONDBLCLK:
  154. case WM_RBUTTONDOWN:
  155. case WM_RBUTTONUP:
  156. case WM_RBUTTONDBLCLK:
  157. case WM_MBUTTONDOWN:
  158. case WM_MBUTTONUP:
  159. case WM_MBUTTONDBLCLK:
  160. nMsgToSend = wParam;
  161. break;
  162. case WM_NCMOUSEMOVE:
  163. nMsgToSend = WM_MOUSEMOVE;
  164. break;
  165. case WM_NCLBUTTONDOWN:
  166. nMsgToSend = WM_LBUTTONDOWN;
  167. break;
  168. case WM_NCLBUTTONUP:
  169. nMsgToSend = WM_NCLBUTTONUP;
  170. break;
  171. case WM_NCLBUTTONDBLCLK:
  172. nMsgToSend = WM_LBUTTONDBLCLK;
  173. break;
  174. case WM_NCRBUTTONDOWN:
  175. nMsgToSend = WM_RBUTTONDOWN;
  176. break;
  177. case WM_NCRBUTTONUP:
  178. nMsgToSend = WM_RBUTTONUP;
  179. break;
  180. case WM_NCRBUTTONDBLCLK:
  181. nMsgToSend = WM_RBUTTONDBLCLK;
  182. break;
  183. case WM_NCMBUTTONDOWN:
  184. nMsgToSend = WM_MBUTTONDOWN;
  185. break;
  186. case WM_NCMBUTTONUP:
  187. nMsgToSend = WM_MBUTTONUP;
  188. break;
  189. case WM_NCMBUTTONDBLCLK:
  190. nMsgToSend = WM_MBUTTONDBLCLK;
  191. break;
  192. } // switch( wParam )
  193. if( nMsgToSend != WM_NULL )
  194. {
  195. WPARAM wParamMsg = 0L;
  196. if( CExtPopupMenuWnd::IsKeyPressed(VK_LBUTTON) )
  197. wParamMsg |= MK_LBUTTON;
  198. if( CExtPopupMenuWnd::IsKeyPressed(VK_RBUTTON) )
  199. wParamMsg |= MK_RBUTTON;
  200. if( CExtPopupMenuWnd::IsKeyPressed(VK_MBUTTON) )
  201. wParamMsg |= MK_MBUTTON;
  202. if( CExtPopupMenuWnd::IsKeyPressed(VK_SHIFT) )
  203. wParamMsg |= MK_SHIFT;
  204. if( CExtPopupMenuWnd::IsKeyPressed(VK_CONTROL) )
  205. wParamMsg |= MK_CONTROL;
  206. CPoint pt( lpMS->pt );
  207. VERIFY( ::ScreenToClient( hWndHook, &pt ) );
  208. LPARAM lParamMsg = MAKELPARAM( pt.x, pt.y );
  209. ::SendMessage(
  210. hWndHook,
  211. nMsgToSend,
  212. wParamMsg,
  213. lParamMsg
  214. );
  215. return -1; // eat!
  216. } // if( nMsgToSend != WM_NULL )
  217. } // if( hWndHook != NULL && ::IsWindow(hWndHook) )
  218. return
  219. ::CallNextHookEx(
  220. g_hMouseHook,
  221. nCode,
  222. wParam,
  223. lParam
  224. );
  225. }
  226. #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS