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

界面编程

开发平台:

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_HOOK_H)
  23. #include "ExtHook.h"
  24. #endif
  25. #if (!defined __EXT_PAINT_MANAGER_H)
  26. #include <ExtPaintManager.h>
  27. #endif
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. typedef
  34. CMap < HWND, HWND,
  35. CExtHookSink::HookChains_t *, CExtHookSink::HookChains_t * >
  36. HookChainsMap_t;
  37. static HookChainsMap_t g_HookChainsMap;
  38. struct __PROF_UIS_API CExtHookSink::HookSinkArray_t :
  39. public CArray< CExtHookSink *, CExtHookSink * >
  40. {
  41. INT Find( const CExtHookSink * pHookSink ) const
  42. {
  43. ASSERT( pHookSink != NULL );
  44. for( INT nSinkIdx = 0; nSinkIdx < GetSize(); nSinkIdx++ )
  45. {
  46. const CExtHookSink * pHookSinkExamine =
  47. GetAt( nSinkIdx );
  48. ASSERT( pHookSink != NULL );
  49. if( pHookSinkExamine == pHookSink )
  50. return nSinkIdx;
  51. }
  52. return -1;
  53. }
  54. void AddHead( CExtHookSink * pHookSink )
  55. {
  56. ASSERT( pHookSink != NULL );
  57. InsertAt( 0, pHookSink );
  58. }
  59. void AddTail( CExtHookSink * pHookSink )
  60. {
  61. ASSERT( pHookSink != NULL );
  62. InsertAt( GetSize(), pHookSink );
  63. }
  64. }; // struct HookSinkArray_t
  65. struct __PROF_UIS_API CExtHookSink::HookChains_t
  66. {
  67. bool m_bEatNcDestroy:1;
  68. HookSinkArray_t m_HookSinkArray;
  69. HWND m_hWndHooked;
  70. WNDPROC m_pWNDPROC;
  71. static LRESULT CALLBACK g_HookWndProc(
  72. HWND hWnd,
  73. UINT nMessage,
  74. WPARAM wParam,
  75. LPARAM lParam
  76. );
  77. HookChains_t(
  78. HWND hWndHooked
  79. )
  80. : m_hWndHooked( hWndHooked )
  81. , m_bEatNcDestroy( false )
  82. {
  83. ASSERT( m_hWndHooked != NULL );
  84. ASSERT( ::IsWindow(m_hWndHooked) );
  85. m_pWNDPROC = (WNDPROC)(__EXT_MFC_LONG_PTR)
  86. ::__EXT_MFC_SetWindowLong(
  87. m_hWndHooked,
  88. __EXT_MFC_GWL_WNDPROC,
  89. #if defined(_WIN64)
  90. (__EXT_MFC_LONG_PTR)
  91. #else
  92. (LONG)(__EXT_MFC_LONG_PTR)
  93. #endif
  94. g_HookWndProc
  95. );
  96. // ASSERT( m_pWNDPROC != NULL );
  97. };
  98. ~HookChains_t()
  99. {
  100. DestroyChains( false );
  101. };
  102. void DestroyChains( bool bDelete )
  103. {
  104. for( int nSinkIdx=0; nSinkIdx < m_HookSinkArray.GetSize(); nSinkIdx++ )
  105. {
  106. CExtHookSink * pHookSink =
  107. m_HookSinkArray[ nSinkIdx ];
  108. ASSERT( pHookSink != NULL );
  109. if( pHookSink->IsAutoDeleteHookWndSink() )
  110. delete pHookSink;
  111. } // for( int nSinkIdx=0; nSinkIdx < m_HookSinkArray.GetSize(); nSinkIdx++ )
  112. m_HookSinkArray.RemoveAll();
  113. ASSERT( m_hWndHooked != NULL );
  114. ASSERT( ::IsWindow(m_hWndHooked) );
  115. ASSERT( m_pWNDPROC != NULL );
  116. ::__EXT_MFC_SetWindowLong(
  117. m_hWndHooked,
  118. __EXT_MFC_GWL_WNDPROC,
  119. #if defined(_WIN64)
  120. (__EXT_MFC_LONG_PTR)
  121. #else
  122. (LONG)(__EXT_MFC_LONG_PTR)
  123. #endif
  124. m_pWNDPROC
  125. );
  126. POSITION posChains = g_HookChainsMap.GetStartPosition();
  127. for( ; posChains != NULL; )
  128. {
  129. CExtHookSink::HookChains_t * pHookChains = NULL;
  130. HWND hWndHooked = NULL;
  131. g_HookChainsMap.GetNextAssoc(
  132. posChains, hWndHooked, pHookChains );
  133. ASSERT( hWndHooked != NULL );
  134. ASSERT( pHookChains != NULL );
  135. if( pHookChains == this )
  136. {
  137. g_HookChainsMap.RemoveKey( hWndHooked );
  138. break;
  139. }
  140. }
  141. if( bDelete )
  142. delete this;
  143. };
  144. LRESULT HookChainsWindowProc(
  145. UINT nMessage,
  146. WPARAM & wParam,
  147. LPARAM & lParam
  148. )
  149. {
  150. __PROF_UIS_MANAGE_STATE;
  151. ASSERT( m_hWndHooked != NULL );
  152. ASSERT( ::IsWindow(m_hWndHooked) );
  153. ASSERT( m_pWNDPROC != NULL );
  154. // CWnd * pWndPermanent = NULL;
  155. // { // BLOCK: state managing
  156. // __PROF_UIS_MANAGE_STATE;
  157. // pWndPermanent = 
  158. // CWnd::FromHandlePermanent( m_hWndHooked );
  159. // } // BLOCK: state managing
  160. bool bEatNcDestroy = m_bEatNcDestroy;
  161. int nSinkIdx, nSinkCount = (int)m_HookSinkArray.GetSize();
  162. for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
  163. {
  164. CExtHookSink * pHookSink =
  165. m_HookSinkArray[ nSinkIdx ];
  166. ASSERT( pHookSink != NULL );
  167. if( nMessage == WM_NCDESTROY ) 
  168. {
  169. if( (! bEatNcDestroy )
  170. && pHookSink->m_bEatNcDestroy
  171. )
  172. bEatNcDestroy = true;
  173. if(! bEatNcDestroy )
  174. pHookSink->OnHookWndNcDestroy();
  175. continue;
  176. } // if( nMessage == WM_NCDESTROY ) 
  177. LRESULT lResult = 0;
  178. if( pHookSink->OnHookWndMsg(
  179. lResult,
  180. m_hWndHooked,
  181. nMessage,
  182. wParam,
  183. lParam
  184. )
  185. )
  186. return lResult;
  187. } // for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
  188. WNDPROC pWNDPROC = m_pWNDPROC;
  189. HWND hWndHooked = m_hWndHooked;
  190. if( nMessage == WM_NCDESTROY ) 
  191. {
  192. DestroyChains( true );
  193. // if( pWndPermanent != NULL )
  194. // {
  195. // __PROF_UIS_MANAGE_STATE;
  196. // CWnd * pWndExamine =
  197. // CWnd::FromHandlePermanent( hWndHooked );
  198. // if( pWndExamine != pWndPermanent )
  199. // return 0L;
  200. // } // if( pWndPermanent != NULL )
  201. if( bEatNcDestroy )
  202. return 0L;
  203. } // if( nMessage == WM_NCDESTROY ) 
  204. LRESULT lResult =
  205. ::CallWindowProc(
  206. pWNDPROC,
  207. hWndHooked,
  208. nMessage,
  209. wParam,
  210. lParam
  211. );
  212. if( ::IsWindow( hWndHooked ) )
  213. {
  214. CExtHookSink::HookChains_t * pHC = NULL;
  215. if( g_HookChainsMap.Lookup( hWndHooked, pHC )
  216. && pHC == this
  217. )
  218. {
  219. nSinkCount = (int)m_HookSinkArray.GetSize();
  220. for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
  221. {
  222. CExtHookSink * pHookSink =
  223. m_HookSinkArray[ nSinkIdx ];
  224. if( pHookSink == NULL )
  225. continue;
  226. pHookSink->OnPostHookWndMsg(
  227. lResult,
  228. m_hWndHooked,
  229. nMessage,
  230. wParam,
  231. lParam
  232. );
  233. if( ! ::IsWindow( hWndHooked ) )
  234. break;
  235. pHC = NULL;
  236. if( ! g_HookChainsMap.Lookup( hWndHooked, pHC ) )
  237. break;
  238. if( pHC != this )
  239. break;
  240. } // for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
  241. }
  242. } // if( ::IsWindow( hWndHooked ) )
  243. return lResult;
  244. };
  245. }; // struct CExtHookSink::HookChains_t
  246. LRESULT CALLBACK CExtHookSink::HookChains_t::g_HookWndProc(
  247. HWND hWnd,
  248. UINT nMessage,
  249. WPARAM wParam,
  250. LPARAM lParam
  251. )
  252. {
  253. LRESULT lResult = 0;
  254. MSG & refMsgMfcCurr = AfxGetThreadState()->m_lastSentMsg;
  255. MSG msgMfcSaved( refMsgMfcCurr );
  256. refMsgMfcCurr.hwnd    = hWnd;
  257. refMsgMfcCurr.message = nMessage;
  258. refMsgMfcCurr.wParam  = wParam;
  259. refMsgMfcCurr.lParam  = lParam;
  260. CExtHookSink::HookChains_t * pHookChains = NULL;
  261. if( g_HookChainsMap.Lookup( hWnd, pHookChains ) )
  262. {
  263. ASSERT( pHookChains != NULL );
  264. ASSERT( pHookChains->m_hWndHooked == hWnd );
  265. lResult =
  266. pHookChains->HookChainsWindowProc(
  267. nMessage,
  268. wParam,
  269. lParam
  270. );  
  271. if( nMessage == WM_NCDESTROY || ( ! ::IsWindow( hWnd ) ) ) 
  272. g_HookChainsMap.RemoveKey( hWnd );
  273. } // if( g_HookChainsMap.Lookup( hWnd, pHookChains ) )
  274. refMsgMfcCurr = msgMfcSaved;
  275. return lResult;
  276. }
  277. CExtHookSink::CExtHookSink(
  278. bool bEnableDetailedWndHooks // = true
  279. )
  280. : m_bEnableDetailedWndHooks( bEnableDetailedWndHooks )
  281. , m_bEatNcDestroy( false )
  282. {
  283. }
  284. CExtHookSink::~CExtHookSink()
  285. {
  286. POSITION posChains = g_HookChainsMap.GetStartPosition();
  287. for( ; posChains != NULL; )
  288. {
  289. CExtHookSink::HookChains_t * pHookChains = NULL;
  290. HWND hWndHooked = NULL;
  291. g_HookChainsMap.GetNextAssoc(
  292. posChains, hWndHooked, pHookChains );
  293. ASSERT( hWndHooked != NULL );
  294. ASSERT( pHookChains != NULL );
  295. // __try
  296. // {
  297. INT nOwnIdx = pHookChains->m_HookSinkArray.Find( this );
  298. if( nOwnIdx < 0 )
  299. continue;
  300. pHookChains->m_HookSinkArray.RemoveAt( nOwnIdx );
  301. // }
  302. // __except( EXCEPTION_EXECUTE_HANDLER )
  303. // {
  304. // }
  305. } // for( ; pos != NULL; )
  306. }
  307. LRESULT CExtHookSink::OnHookWndMsgNextProcInvoke(
  308. UINT nMessage,
  309. WPARAM wParam,
  310. LPARAM lParam
  311. )
  312. {
  313. MSG & msgCurrMfc = AfxGetThreadState()->m_lastSentMsg;
  314. ASSERT( msgCurrMfc.hwnd != NULL );
  315. ASSERT( ::IsWindow( msgCurrMfc.hwnd ) );
  316. CExtHookSink::HookChains_t * pHookChains = NULL;
  317. VERIFY(
  318. g_HookChainsMap.Lookup(
  319. msgCurrMfc.hwnd,
  320. pHookChains
  321. )
  322. );
  323. ASSERT( pHookChains != NULL );
  324. ASSERT( pHookChains->m_hWndHooked == msgCurrMfc.hwnd );
  325. ASSERT( pHookChains->m_pWNDPROC != NULL );
  326. return
  327. ::CallWindowProc(
  328. pHookChains->m_pWNDPROC,
  329. msgCurrMfc.hwnd,
  330. nMessage,
  331. wParam,
  332. lParam
  333. );
  334. }
  335. LRESULT CExtHookSink::OnHookWndMsgNextProcCurrent(
  336. WPARAM wParam,
  337. LPARAM lParam
  338. )
  339. {
  340. MSG & msgCurrMfc = AfxGetThreadState()->m_lastSentMsg;
  341. ASSERT( msgCurrMfc.hwnd != NULL );
  342. ASSERT( ::IsWindow( msgCurrMfc.hwnd ) );
  343. CExtHookSink::HookChains_t * pHookChains = NULL;
  344. VERIFY(
  345. g_HookChainsMap.Lookup(
  346. msgCurrMfc.hwnd,
  347. pHookChains
  348. )
  349. );
  350. ASSERT( pHookChains != NULL );
  351. ASSERT( pHookChains->m_hWndHooked == msgCurrMfc.hwnd );
  352. ASSERT( pHookChains->m_pWNDPROC != NULL );
  353. return
  354. ::CallWindowProc(
  355. pHookChains->m_pWNDPROC,
  356. msgCurrMfc.hwnd,
  357. msgCurrMfc.message,
  358. wParam,
  359. lParam
  360. );
  361. }
  362. LRESULT CExtHookSink::OnHookWndMsgDefault()
  363. {
  364. MSG & msgCurrMfc = AfxGetThreadState()->m_lastSentMsg;
  365. ASSERT( msgCurrMfc.hwnd != NULL );
  366. ASSERT( ::IsWindow( msgCurrMfc.hwnd ) );
  367. CExtHookSink::HookChains_t * pHookChains = NULL;
  368. VERIFY(
  369. g_HookChainsMap.Lookup(
  370. msgCurrMfc.hwnd,
  371. pHookChains
  372. )
  373. );
  374. ASSERT( pHookChains != NULL );
  375. ASSERT( pHookChains->m_hWndHooked == msgCurrMfc.hwnd );
  376. ASSERT( pHookChains->m_pWNDPROC != NULL );
  377. return
  378. ::CallWindowProc(
  379. pHookChains->m_pWNDPROC,
  380. msgCurrMfc.hwnd,
  381. msgCurrMfc.message,
  382. msgCurrMfc.wParam,
  383. msgCurrMfc.lParam
  384. );
  385. }
  386. bool CExtHookSink::OnHookWndMsg(
  387. LRESULT & lResult,
  388. HWND hWndHooked,
  389. UINT nMessage,
  390. WPARAM & wParam,
  391. LPARAM & lParam
  392. )
  393. {
  394. lResult;
  395. hWndHooked;
  396. nMessage;
  397. wParam;
  398. lParam;
  399. if( ! m_bEnableDetailedWndHooks )
  400. return false;
  401. switch( nMessage )
  402. {
  403. case WM_COMMAND:
  404. return
  405. OnHookCmdMsg(
  406. lResult,
  407. hWndHooked,
  408. HIWORD(wParam),
  409. LOWORD(wParam),
  410. (HWND)lParam
  411. );
  412. case WM_NOTIFY:
  413. return
  414. OnHookNotifyMsg(
  415. lResult,
  416. hWndHooked,
  417. (INT)wParam,
  418. (LPNMHDR)lParam
  419. );
  420. case WM_PAINT:
  421. return
  422. OnHookPaintMsg(
  423. lResult,
  424. hWndHooked,
  425. (HDC)wParam
  426. );
  427. case WM_ERASEBKGND:
  428. return
  429. OnHookEraseBackgroundMsg(
  430. lResult,
  431. hWndHooked,
  432. (HDC)wParam
  433. );
  434. case WM_PRINT:
  435. case WM_PRINTCLIENT:
  436. return
  437. OnHookPrintMsg(
  438. lResult,
  439. hWndHooked,
  440. (HDC)wParam
  441. );
  442. case WM_NCPAINT:
  443. return
  444. OnHookNcPaintMsg(
  445. lResult,
  446. hWndHooked,
  447. (HRGN)wParam
  448. );
  449. } // switch( nMessage )
  450. return false;
  451. }
  452. void CExtHookSink::OnPostHookWndMsg(
  453. LRESULT lResult,
  454. HWND hWndHooked,
  455. UINT nMessage,
  456. WPARAM wParam,
  457. LPARAM lParam
  458. )
  459. {
  460. lResult;
  461. hWndHooked;
  462. nMessage;
  463. wParam;
  464. lParam;
  465. }
  466. bool CExtHookSink::OnHookCmdMsg(
  467. LRESULT & lResult,
  468. HWND hWndHooked,
  469. WORD wNotifyCode,
  470. WORD wID,
  471. HWND hWndCtrl
  472. )
  473. {
  474. lResult;
  475. hWndHooked;
  476. wNotifyCode;
  477. wID;
  478. hWndCtrl;
  479. return false;
  480. }
  481. bool CExtHookSink::OnHookNotifyMsg(
  482. LRESULT & lResult,
  483. HWND hWndHooked,
  484. INT nIdCtrl,
  485. LPNMHDR lpnmhdr
  486. )
  487. {
  488. lResult;
  489. hWndHooked;
  490. nIdCtrl;
  491. lpnmhdr;
  492. return false;
  493. }
  494. bool CExtHookSink::OnHookPaintMsg(
  495. LRESULT & lResult,
  496. HWND hWndHooked,
  497. HDC hDC
  498. )
  499. {
  500. lResult;
  501. hWndHooked;
  502. hDC;
  503. return false;
  504. }
  505. bool CExtHookSink::OnHookEraseBackgroundMsg(
  506. LRESULT & lResult,
  507. HWND hWndHooked,
  508. HDC hDC
  509. )
  510. {
  511. lResult;
  512. hWndHooked;
  513. hDC;
  514. return false;
  515. }
  516. bool CExtHookSink::OnHookPrintMsg(
  517. LRESULT & lResult,
  518. HWND hWndHooked,
  519. HDC hDC
  520. )
  521. {
  522. lResult;
  523. hWndHooked;
  524. hDC;
  525. return false;
  526. }
  527. bool CExtHookSink::OnHookNcPaintMsg(
  528. LRESULT & lResult,
  529. HWND hWndHooked,
  530. HRGN hRgnUpdate
  531. )
  532. {
  533. lResult;
  534. hWndHooked;
  535. hRgnUpdate;
  536. return false;
  537. }
  538. void CExtHookSink::OnHookWndNcDestroy()
  539. {
  540. }
  541. void CExtHookSink::OnHookWndAttach( HWND hWnd )
  542. {
  543. ASSERT( hWnd != NULL );
  544. hWnd;
  545. }
  546. void CExtHookSink::OnHookWndDetach( HWND hWnd )
  547. {
  548. ASSERT( hWnd != NULL );
  549. hWnd;
  550. }
  551. bool CExtHookSink::IsAutoDeleteHookWndSink()
  552. {
  553. return false;
  554. }
  555. bool CExtHookSink::SetupHookWndSink(
  556. HWND hWnd,
  557. bool bRemove, // = false
  558. bool bAddToHead // = false
  559. )
  560. {
  561. ASSERT( hWnd != NULL );
  562. if( hWnd == NULL )
  563. return false;
  564. ASSERT( bRemove || (!bRemove && ::IsWindow(hWnd)) );
  565. if( (!bRemove) && (!::IsWindow(hWnd) ) )
  566. return false;
  567. CExtHookSink::HookChains_t * pHookChains = NULL;
  568. if( !g_HookChainsMap.Lookup( hWnd, pHookChains ) )
  569. {
  570. ASSERT( pHookChains == NULL );
  571. }
  572. else
  573. {
  574. ASSERT( pHookChains != NULL );
  575. }
  576. if( bRemove )
  577. {
  578. if( pHookChains == NULL )
  579. return true;
  580. INT pos =
  581. pHookChains->m_HookSinkArray.Find( this );
  582. if( pos < 0 )
  583. return true;
  584. OnHookWndDetach( hWnd );
  585. pHookChains->m_HookSinkArray.RemoveAt( pos );
  586. if( IsAutoDeleteHookWndSink() )
  587. delete this;
  588. if( pHookChains->m_HookSinkArray.GetSize() == 0 )
  589. pHookChains->DestroyChains( true );
  590. return true;
  591. } // if( bRemove )
  592. if( pHookChains == NULL )
  593. {
  594. pHookChains =
  595. new CExtHookSink::HookChains_t( hWnd );
  596. g_HookChainsMap.SetAt( hWnd, pHookChains );
  597. } // if( pHookChains == NULL )
  598. else
  599. {
  600. INT pos =
  601. pHookChains->m_HookSinkArray.Find( this );
  602. if( pos >= 0 )
  603. return true;
  604. } // else from if( pHookChains == NULL )
  605. if( bAddToHead )
  606. pHookChains->m_HookSinkArray.AddHead( this );
  607. else
  608. pHookChains->m_HookSinkArray.AddTail( this );
  609. OnHookWndAttach( hWnd );
  610. return true;
  611. }
  612. ULONG CExtHookSink::SetupHookWndSinkToChilds(
  613. HWND hWnd,
  614. UINT * pDlgCtrlIDs, // = NULL
  615. ULONG nCountOfDlgCtrlIDs, // = 0
  616. bool bDeep // = false
  617. )
  618. {
  619. ASSERT( hWnd != NULL );
  620. if( hWnd == NULL )
  621. return 0;
  622. ASSERT( ::IsWindow(hWnd) );
  623. if( !::IsWindow(hWnd) )
  624. return 0;
  625. ULONG nCountOfHooks = 0;
  626. hWnd = ::GetWindow( hWnd, GW_CHILD );
  627. for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
  628. {
  629. ASSERT(
  630. (nCountOfDlgCtrlIDs == 0 && pDlgCtrlIDs == NULL)
  631. || (nCountOfDlgCtrlIDs > 0 && pDlgCtrlIDs != NULL)
  632. );
  633. bool bSetupHook = true;
  634. if( nCountOfDlgCtrlIDs > 0 && pDlgCtrlIDs != NULL )
  635. {
  636. bSetupHook = false;
  637. UINT nDlgCtrlID = ::GetDlgCtrlID( hWnd );
  638. for( ULONG i=0; i<nCountOfDlgCtrlIDs; i++ )
  639. {
  640. if( pDlgCtrlIDs[i] == nDlgCtrlID )
  641. {
  642. bSetupHook = true;
  643. break;
  644. }
  645. } // for( ULONG i=0; i<nCountOfDlgCtrlIDs; i++ )
  646. } // if( nCountOfDlgCtrlIDs > 0 && pDlgCtrlIDs != NULL )
  647. if( bSetupHook )
  648. {
  649. if( SetupHookWndSink( hWnd ) )
  650. nCountOfHooks++;
  651. else
  652. {
  653. ASSERT( FALSE );
  654. }
  655. } // if( bSetupHook )
  656. if( bDeep )
  657. nCountOfHooks +=
  658. SetupHookWndSinkToChilds(
  659. hWnd,
  660. pDlgCtrlIDs,
  661. nCountOfDlgCtrlIDs,
  662. bDeep
  663. );
  664. } // for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
  665. return nCountOfHooks;
  666. }
  667. void CExtHookSink::RemoveAllWndHooks()
  668. {
  669. HookedWndList_t _list;
  670. GetHookedWindows( _list );
  671. POSITION pos = _list.GetHeadPosition();
  672. for( int nHwndIdx = 0; nHwndIdx < _list.GetCount(); nHwndIdx++ )
  673. {
  674. HWND hWndHooked = _list.GetNext( pos );
  675. VERIFY( SetupHookWndSink( hWndHooked, true ) );
  676. } // for( int nHwndIdx = 0; nHwndIdx < _list.GetCount(); nHwndIdx++ )
  677. }
  678. void CExtHookSink::GetHookedWindows( HookedWndList_t & _list )
  679. {
  680. _list.RemoveAll();
  681. POSITION posChains = g_HookChainsMap.GetStartPosition();
  682. for( ; posChains != NULL; )
  683. {
  684. CExtHookSink::HookChains_t * pHookChains = NULL;
  685. HWND hWndHooked = NULL;
  686. g_HookChainsMap.GetNextAssoc(
  687. posChains, hWndHooked, pHookChains );
  688. ASSERT( hWndHooked != NULL );
  689. ASSERT( pHookChains != NULL );
  690. ASSERT( pHookChains->m_hWndHooked == hWndHooked );
  691. if( pHookChains->m_HookSinkArray.Find(this) < 0 )
  692. continue;
  693. ASSERT( _list.Find(pHookChains->m_hWndHooked) == NULL );
  694. _list.AddTail( pHookChains->m_hWndHooked );
  695. } // for( ; pos != NULL; )
  696. }
  697. bool CExtHookSink::IsHookedWindow( HWND hWnd )
  698. {
  699. CExtHookSink::HookChains_t * pHookChains = NULL;
  700. if( !g_HookChainsMap.Lookup( hWnd, pHookChains ) )
  701. return false;
  702. ASSERT( pHookChains != NULL );
  703. ASSERT( pHookChains->m_hWndHooked == hWnd );
  704. if( pHookChains->m_HookSinkArray.Find(this) >= 0 )
  705. return true;
  706. return false;
  707. }
  708. CExtHookSpy::HookSpyItem_t CExtHookSpy::g_arr[ __EHS_IDX_COUNT ] =
  709. {
  710. __EHSEF_MOUSE_ALL,
  711. __EHSEF_KEYBOARD,
  712. __EHSEF_GET_MSG,
  713. __EHSEF_SYS_MSG,
  714. __EHSEF_WND_PROC_IN,
  715. __EHSEF_WND_PROC_OUT,
  716. };
  717. CExtHookSpy::HookSpyItem_t::HookSpyItem_t( DWORD dwEHSEF )
  718. : m_hHook( NULL )
  719. , m_bListChanged( false )
  720. , m_dwEHSEF( dwEHSEF )
  721. {
  722. }
  723. bool CExtHookSpy::HookSpyItem_t::IsRegistered( CExtHookSpy * pHS, DWORD dwEHSEF )
  724. {
  725. dwEHSEF;
  726. bool bVal = false;
  727. bool bRetVal = m_map.Lookup( pHS, bVal ) ? true : false;
  728. /*
  729. #if (defined _DEBUG)
  730. DWORD dwEffectiveEHSEF = dwEHSEF & m_dwEHSEF;
  731. DWORD dwCurrentEHSEF = pHS->HookSpyGetEHSEF();
  732. DWORD dwCheckEHSEF = dwCurrentEHSEF & __EHSEF_BASIC_HOOK_FILTERING;
  733. if( bRetVal )
  734. {
  735. ASSERT( ( dwCheckEHSEF & dwEffectiveEHSEF ) != 0 );
  736. ASSERT( m_list.Find( pHS ) != NULL );
  737. }
  738. else
  739. {
  740. ASSERT( ( dwCheckEHSEF & dwEffectiveEHSEF ) == 0 );
  741. ASSERT( m_list.Find( pHS ) == NULL );
  742. }
  743. #endif // (defined _DEBUG)
  744. */
  745. return bRetVal;
  746. }
  747. void CExtHookSpy::HookSpyItem_t::Register( CExtHookSpy * pHS, DWORD dwEHSEF, bool bAddToHead )
  748. {
  749. if( pHS == NULL )
  750. return;
  751. DWORD dwEffectiveEHSEF = dwEHSEF & m_dwEHSEF;
  752. if( dwEffectiveEHSEF == 0 )
  753. return;
  754. bool bRegistered = IsRegistered( pHS, m_dwEHSEF );
  755. pHS->HookSpyModifyEHSEF( 0, dwEffectiveEHSEF );
  756. if( bRegistered )
  757. return;
  758. INT nPrevRegisteredCount = INT( m_list.GetCount() );
  759. ASSERT( nPrevRegisteredCount >= 0 );
  760. if( bAddToHead )
  761. m_list.AddHead( pHS );
  762. else
  763. m_list.AddTail( pHS );
  764. m_map.SetAt( pHS, false );
  765. m_bListChanged = true;
  766. ASSERT( (nPrevRegisteredCount+1) == INT( m_list.GetCount() ) );
  767. ASSERT( (nPrevRegisteredCount+1) == INT( m_map.GetCount() ) );
  768. if( nPrevRegisteredCount == 0 )
  769. Hook( true );
  770. }
  771. void CExtHookSpy::HookSpyItem_t::Unregister( CExtHookSpy * pHS, DWORD dwEHSEF )
  772. {
  773. if( pHS == NULL || ( m_dwEHSEF & dwEHSEF ) == 0 )
  774. return;
  775. #if (defined _DEBUG)
  776. bool bRegistered = IsRegistered( pHS, m_dwEHSEF );
  777. #endif // (defined _DEBUG)
  778. if( ( pHS->HookSpyGetEHSEF() & m_dwEHSEF ) == 0 )
  779. {
  780. ASSERT( ! bRegistered );
  781. return;
  782. }
  783. ASSERT( bRegistered );
  784. DWORD dwEffectiveEHSEF = dwEHSEF & m_dwEHSEF;
  785. pHS->HookSpyModifyEHSEF( dwEffectiveEHSEF, 0 );
  786. if( ( pHS->HookSpyGetEHSEF() & m_dwEHSEF ) != 0 )
  787. return;
  788. POSITION pos = m_list.Find( pHS );
  789. ASSERT( pos != NULL );
  790. m_list.RemoveAt( pos );
  791. m_map.RemoveKey( pHS );
  792. m_bListChanged = true;
  793. INT nRegisteredCount = INT( m_list.GetCount() );
  794. ASSERT( nRegisteredCount >= 0 );
  795. ASSERT( nRegisteredCount == INT( m_map.GetCount() ) );
  796. if( nRegisteredCount == 0 )
  797. Hook( false );
  798. }
  799. void CExtHookSpy::HookSpyItem_t::Hook( bool bHook )
  800. {
  801. if( bHook )
  802. {
  803. if( m_hHook != NULL )
  804. return;
  805. if( ( m_dwEHSEF & __EHSEF_MOUSE_ALL ) != 0 )
  806. {
  807. m_hHook =
  808. ::SetWindowsHookEx(
  809. WH_MOUSE,
  810. SHS_HookMouseProc, 
  811. 0,
  812. ::GetCurrentThreadId()
  813. );
  814. // ASSERT( m_hHook != NULL );
  815. }
  816. else
  817. if( ( m_dwEHSEF & __EHSEF_KEYBOARD ) != 0 )
  818. {
  819. m_hHook =
  820. ::SetWindowsHookEx(
  821. WH_KEYBOARD,
  822. SHS_HookKeyboardProc, 
  823. 0,
  824. ::GetCurrentThreadId()
  825. );
  826. // ASSERT( m_hHook != NULL );
  827. }
  828. else
  829. if( ( m_dwEHSEF & __EHSEF_GET_MSG ) != 0 )
  830. {
  831. m_hHook =
  832. ::SetWindowsHookEx(
  833. WH_GETMESSAGE,
  834. SHS_HookGetMsgProc, 
  835. 0,
  836. ::GetCurrentThreadId()
  837. );
  838. // ASSERT( m_hHook != NULL );
  839. }
  840. else
  841. if( ( m_dwEHSEF & __EHSEF_SYS_MSG ) != 0 )
  842. {
  843. m_hHook =
  844. ::SetWindowsHookEx(
  845. WH_SYSMSGFILTER,
  846. SHS_HookSysMsgProc, 
  847. 0,
  848. ::GetCurrentThreadId()
  849. );
  850. // ASSERT( m_hHook != NULL );
  851. }
  852. else
  853. if( ( m_dwEHSEF & __EHSEF_WND_PROC_IN ) != 0 )
  854. {
  855. m_hHook =
  856. ::SetWindowsHookEx(
  857. WH_CALLWNDPROC,
  858. SHS_HookCallWindowProcIn, 
  859. 0,
  860. ::GetCurrentThreadId()
  861. );
  862. // ASSERT( m_hHook != NULL );
  863. }
  864. else
  865. if( ( m_dwEHSEF & __EHSEF_WND_PROC_OUT ) != 0 )
  866. {
  867. m_hHook =
  868. ::SetWindowsHookEx(
  869. WH_CALLWNDPROCRET,
  870. SHS_HookCallWindowProcOut, 
  871. 0,
  872. ::GetCurrentThreadId()
  873. );
  874. // ASSERT( m_hHook != NULL );
  875. }
  876. #if (defined _DEBUG)
  877. else
  878. {
  879. ASSERT( FALSE );
  880. }
  881. #endif // (defined _DEBUG)
  882. } // if( bHook )
  883. else
  884. {
  885. if( m_hHook == NULL )
  886. return;
  887. ::UnhookWindowsHookEx( m_hHook );
  888. m_hHook = NULL;
  889. } // else from if( bHook )
  890. }
  891. CExtHookSpy::CExtHookSpy(
  892. DWORD dwEHSEF // = 0 // auto-register flags, zero - unregister
  893. )
  894. : m_bHookConvertLocationsToClient( false )
  895. , m_dwEHSEF( 0 )
  896. {
  897. if( dwEHSEF != 0 )
  898. HookSpyRegister( dwEHSEF );
  899. }
  900. CExtHookSpy::~CExtHookSpy()
  901. {
  902. HookSpyUnregister();
  903. }
  904. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookMouseProc(
  905. int nCode,      // hook code
  906. WPARAM wParam,  // message identifier
  907. LPARAM lParam   // mouse coordinates
  908. )
  909. {
  910. __PROF_UIS_MANAGE_STATE;
  911. MOUSEHOOKSTRUCT * lpMS = (MOUSEHOOKSTRUCT*)lParam;
  912. ASSERT( lpMS != NULL );
  913. if( nCode == HC_ACTION )
  914. {
  915. POSITION pos = g_arr[__EHS_IDX_MOUSE].m_list.GetHeadPosition();
  916. for( g_arr[__EHS_IDX_MOUSE].m_bListChanged = false; pos != NULL; )
  917. {
  918. CExtHookSpy * pHS = g_arr[__EHS_IDX_MOUSE].m_list.GetNext( pos );
  919. ASSERT( pHS != NULL );
  920. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  921. if( (  dwEHSEF & __EHSEF_MOUSE_ALL ) == 0 )
  922. continue;
  923. bool bNC = false;
  924. switch( wParam )
  925. {
  926. case WM_NCMOUSEMOVE:
  927. bNC = true;
  928. case WM_MOUSEMOVE:
  929. if( (  dwEHSEF & ( bNC ? __EHSEF_MOUSE_MOVE_NC : __EHSEF_MOUSE_MOVE ) ) == 0 )
  930. continue;
  931. else
  932. {
  933. CPoint point = lpMS->pt; // screen coordinates
  934. if( pHS->m_bHookConvertLocationsToClient && (! bNC ) )
  935. ::ScreenToClient( lpMS->hwnd, &point );
  936. if( pHS->
  937. HSLL_OnMouseMove(
  938. lpMS->hwnd,
  939. 0, // wParam,
  940. point
  941. )
  942. )
  943. return 1; // eat!
  944. }
  945. break;
  946. case WM_MOUSEWHEEL:
  947. if( (  dwEHSEF & __EHSEF_MOUSE_WHEEL ) == 0 )
  948. continue;
  949. else
  950. if( pHS->
  951. HSLL_OnMouseWheel(
  952. wParam,
  953. lParam
  954. )
  955. )
  956. return 1; // eat!
  957. break;
  958. case WM_NCLBUTTONDBLCLK:
  959. case WM_NCRBUTTONDBLCLK:
  960. case WM_NCMBUTTONDBLCLK:
  961. case WM_NCLBUTTONDOWN:
  962. case WM_NCRBUTTONDOWN:
  963. case WM_NCMBUTTONDOWN:
  964. case WM_NCLBUTTONUP:
  965. case WM_NCRBUTTONUP:
  966. case WM_NCMBUTTONUP:
  967. bNC = true;
  968. case WM_LBUTTONDBLCLK:
  969. case WM_RBUTTONDBLCLK:
  970. case WM_MBUTTONDBLCLK:
  971. case WM_LBUTTONDOWN:
  972. case WM_RBUTTONDOWN:
  973. case WM_MBUTTONDOWN:
  974. case WM_LBUTTONUP:
  975. case WM_RBUTTONUP:
  976. case WM_MBUTTONUP:
  977. if( (  dwEHSEF & ( bNC ? __EHSEF_MOUSE_CLICK_NC : __EHSEF_MOUSE_CLICK ) ) == 0 )
  978. continue;
  979. else
  980. {
  981. CPoint point = lpMS->pt; // screen coordinates
  982. if( pHS->m_bHookConvertLocationsToClient && (! bNC ) )
  983. ::ScreenToClient( lpMS->hwnd, &point );
  984. if( pHS->
  985. HSLL_OnMouseClick(
  986. lpMS->hwnd,
  987. UINT(wParam),
  988. 0,
  989. point
  990. )
  991. )
  992. return 1; // eat!
  993. }
  994. break;
  995. } // switch( wParam )
  996. if( g_arr[__EHS_IDX_MOUSE].m_bListChanged )
  997. {
  998. g_arr[__EHS_IDX_MOUSE].m_bListChanged = false;
  999. pos = g_arr[__EHS_IDX_MOUSE].m_list.GetHeadPosition();
  1000. } // if( g_arr[__EHS_IDX_MOUSE].m_bListChanged )
  1001. } // for( g_arr[__EHS_IDX_MOUSE].m_bListChanged = false; pos != NULL; )
  1002. g_arr[__EHS_IDX_MOUSE].m_bListChanged = false;
  1003. } // if( nCode == HC_ACTION )
  1004. return ::CallNextHookEx( g_arr[__EHS_IDX_MOUSE].m_hHook, nCode, wParam, lParam );
  1005. }
  1006. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookKeyboardProc(
  1007. int nCode,      // hook code
  1008. WPARAM wParam,  // virtual-key code
  1009. LPARAM lParam   // keystroke-message information
  1010. )
  1011. {
  1012. __PROF_UIS_MANAGE_STATE;
  1013. if( nCode == HC_ACTION )
  1014. {
  1015. POSITION pos = g_arr[__EHS_IDX_KEYBOARD].m_list.GetHeadPosition();
  1016. for( g_arr[__EHS_IDX_KEYBOARD].m_bListChanged = false; pos != NULL; )
  1017. {
  1018. CExtHookSpy * pHS = g_arr[__EHS_IDX_KEYBOARD].m_list.GetNext( pos );
  1019. ASSERT( pHS != NULL );
  1020. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  1021. if( (  dwEHSEF & __EHSEF_KEYBOARD ) == 0 )
  1022. continue;
  1023. if( pHS->
  1024. HSLL_OnKey(
  1025. UINT(wParam),
  1026. LOWORD(lParam),
  1027. HIWORD(lParam)
  1028. )
  1029. )
  1030. return 1; // eat!
  1031. if( g_arr[__EHS_IDX_KEYBOARD].m_bListChanged )
  1032. {
  1033. g_arr[__EHS_IDX_KEYBOARD].m_bListChanged = false;
  1034. pos = g_arr[__EHS_IDX_KEYBOARD].m_list.GetHeadPosition();
  1035. } // if( g_arr[__EHS_IDX_KEYBOARD].m_bListChanged )
  1036. } // for( g_arr[__EHS_IDX_KEYBOARD].m_bListChanged = false; pos != NULL; )
  1037. g_arr[__EHS_IDX_KEYBOARD].m_bListChanged = false;
  1038. } // if( nCode == HC_ACTION )
  1039. return ::CallNextHookEx( g_arr[__EHS_IDX_KEYBOARD].m_hHook, nCode, wParam, lParam );
  1040. }
  1041. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookGetMsgProc(
  1042. int nCode,
  1043. WPARAM wParam,
  1044. LPARAM lParam
  1045. )
  1046. {
  1047. __PROF_UIS_MANAGE_STATE;
  1048. POSITION pos = g_arr[__EHS_IDX_GET_MSG].m_list.GetHeadPosition();
  1049. for( g_arr[__EHS_IDX_GET_MSG].m_bListChanged = false; pos != NULL; )
  1050. {
  1051. CExtHookSpy * pHS = g_arr[__EHS_IDX_GET_MSG].m_list.GetNext( pos );
  1052. ASSERT( pHS != NULL );
  1053. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  1054. if( (  dwEHSEF & __EHSEF_GET_MSG ) == 0 )
  1055. continue;
  1056. LRESULT lResult = 0;
  1057. bool bCallNextHook = true;
  1058. if( pHS->
  1059. HSLL_OnGetMsgProc(
  1060. bCallNextHook,
  1061. lResult,
  1062. nCode,
  1063. wParam,
  1064. (MSG*)lParam
  1065. )
  1066. )
  1067. {
  1068. if( bCallNextHook )
  1069. return ::CallNextHookEx( g_arr[__EHS_IDX_GET_MSG].m_hHook, nCode, wParam, lParam );
  1070. else
  1071. return lResult; // eat!
  1072. }
  1073. if( g_arr[__EHS_IDX_GET_MSG].m_bListChanged )
  1074. {
  1075. g_arr[__EHS_IDX_GET_MSG].m_bListChanged = false;
  1076. pos = g_arr[__EHS_IDX_GET_MSG].m_list.GetHeadPosition();
  1077. } // if( g_arr[__EHS_IDX_GET_MSG].m_bListChanged )
  1078. } // for( g_arr[__EHS_IDX_GET_MSG].m_bListChanged = false; pos != NULL; )
  1079. g_arr[__EHS_IDX_GET_MSG].m_bListChanged = false;
  1080. return ::CallNextHookEx( g_arr[__EHS_IDX_GET_MSG].m_hHook, nCode, wParam, lParam );
  1081. }
  1082. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookSysMsgProc(
  1083. int nCode,
  1084. WPARAM wParam,
  1085. LPARAM lParam
  1086. )
  1087. {
  1088. __PROF_UIS_MANAGE_STATE;
  1089. POSITION pos = g_arr[__EHS_IDX_SYS_MSG].m_list.GetHeadPosition();
  1090. for( g_arr[__EHS_IDX_SYS_MSG].m_bListChanged = false; pos != NULL; )
  1091. {
  1092. CExtHookSpy * pHS = g_arr[__EHS_IDX_SYS_MSG].m_list.GetNext( pos );
  1093. ASSERT( pHS != NULL );
  1094. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  1095. if( (  dwEHSEF & __EHSEF_SYS_MSG ) == 0 )
  1096. continue;
  1097. LRESULT lResult = 0;
  1098. bool bCallNextHook = true;
  1099. if( pHS->
  1100. HSLL_OnSysMsgProc(
  1101. bCallNextHook,
  1102. lResult,
  1103. nCode,
  1104. wParam,
  1105. lParam
  1106. )
  1107. )
  1108. {
  1109. if( bCallNextHook )
  1110. return ::CallNextHookEx( g_arr[__EHS_IDX_SYS_MSG].m_hHook, nCode, wParam, lParam );
  1111. else
  1112. return lResult; // eat!
  1113. }
  1114. if( g_arr[__EHS_IDX_SYS_MSG].m_bListChanged )
  1115. {
  1116. g_arr[__EHS_IDX_SYS_MSG].m_bListChanged = false;
  1117. pos = g_arr[__EHS_IDX_SYS_MSG].m_list.GetHeadPosition();
  1118. } // if( g_arr[__EHS_IDX_SYS_MSG].m_bListChanged )
  1119. } // for( g_arr[__EHS_IDX_SYS_MSG].m_bListChanged = false; pos != NULL; )
  1120. g_arr[__EHS_IDX_SYS_MSG].m_bListChanged = false;
  1121. return ::CallNextHookEx( g_arr[__EHS_IDX_SYS_MSG].m_hHook, nCode, wParam, lParam );
  1122. }
  1123. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookCallWindowProcIn(
  1124. int nCode,
  1125. WPARAM wParam,
  1126. LPARAM lParam
  1127. )
  1128. {
  1129. __PROF_UIS_MANAGE_STATE;
  1130. POSITION pos = g_arr[__EHS_IDX_WND_PROC_IN].m_list.GetHeadPosition();
  1131. for( g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged = false; pos != NULL; )
  1132. {
  1133. CExtHookSpy * pHS = g_arr[__EHS_IDX_WND_PROC_IN].m_list.GetNext( pos );
  1134. ASSERT( pHS != NULL );
  1135. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  1136. if( (  dwEHSEF & __EHSEF_WND_PROC_IN ) == 0 )
  1137. continue;
  1138. LRESULT lResult = 0;
  1139. bool bCallNextHook = true;
  1140. if( pHS->
  1141. HSLL_OnCallWindowProcIn(
  1142. bCallNextHook,
  1143. lResult,
  1144. nCode,
  1145. ( wParam != 0 ) ? true : false,
  1146. (PCWPSTRUCT)lParam
  1147. )
  1148. )
  1149. {
  1150. if( bCallNextHook )
  1151. return ::CallNextHookEx( g_arr[__EHS_IDX_WND_PROC_IN].m_hHook, nCode, wParam, lParam );
  1152. else
  1153. return lResult; // eat!
  1154. }
  1155. if( g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged )
  1156. {
  1157. g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged = false;
  1158. pos = g_arr[__EHS_IDX_WND_PROC_IN].m_list.GetHeadPosition();
  1159. } // if( g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged )
  1160. } // for( g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged = false; pos != NULL; )
  1161. g_arr[__EHS_IDX_WND_PROC_IN].m_bListChanged = false;
  1162. return ::CallNextHookEx( g_arr[__EHS_IDX_WND_PROC_IN].m_hHook, nCode, wParam, lParam );
  1163. }
  1164. LRESULT CALLBACK CExtHookSpy::HookSpyItem_t::SHS_HookCallWindowProcOut(
  1165. int nCode,
  1166. WPARAM wParam,
  1167. LPARAM lParam
  1168. )
  1169. {
  1170. __PROF_UIS_MANAGE_STATE;
  1171. POSITION pos = g_arr[__EHS_IDX_WND_PROC_OUT].m_list.GetHeadPosition();
  1172. for( g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged = false; pos != NULL; )
  1173. {
  1174. CExtHookSpy * pHS = g_arr[__EHS_IDX_WND_PROC_OUT].m_list.GetNext( pos );
  1175. ASSERT( pHS != NULL );
  1176. DWORD dwEHSEF = pHS->HookSpyGetEHSEF();
  1177. if( (  dwEHSEF & __EHSEF_WND_PROC_OUT ) == 0 )
  1178. continue;
  1179. LRESULT lResult = 0;
  1180. bool bCallNextHook = true;
  1181. if( pHS->
  1182. HSLL_OnCallWindowProcOut(
  1183. bCallNextHook,
  1184. lResult,
  1185. nCode,
  1186. ( wParam != 0 ) ? true : false,
  1187. (PCWPRETSTRUCT)lParam
  1188. )
  1189. )
  1190. {
  1191. if( bCallNextHook )
  1192. return ::CallNextHookEx( g_arr[__EHS_IDX_WND_PROC_OUT].m_hHook, nCode, wParam, lParam );
  1193. else
  1194. return lResult; // eat!
  1195. }
  1196. if( g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged )
  1197. {
  1198. g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged = false;
  1199. pos = g_arr[__EHS_IDX_WND_PROC_OUT].m_list.GetHeadPosition();
  1200. } // if( g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged )
  1201. } // for( g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged = false; pos != NULL; )
  1202. g_arr[__EHS_IDX_WND_PROC_OUT].m_bListChanged = false;
  1203. return ::CallNextHookEx( g_arr[__EHS_IDX_WND_PROC_OUT].m_hHook, nCode, wParam, lParam );
  1204. }
  1205. bool CExtHookSpy::HSLL_OnMouseWheel(
  1206. WPARAM wParam,
  1207. LPARAM lParam
  1208. )
  1209. {
  1210. wParam;
  1211. if( ! g_PaintManager.m_bIsWin2000orLater )
  1212. return false;
  1213. struct __SAME_AS_MOUSEHOOKSTRUCTEX
  1214. {
  1215. MOUSEHOOKSTRUCT mhs;
  1216. DWORD mouseData;
  1217. };
  1218. __SAME_AS_MOUSEHOOKSTRUCTEX * pMHEX =
  1219. reinterpret_cast
  1220. < __SAME_AS_MOUSEHOOKSTRUCTEX * >
  1221. ( lParam );
  1222. ASSERT( pMHEX != NULL );
  1223. DWORD dwWheelDeltaAndZeroFlags =
  1224. DWORD( pMHEX->mouseData ) & 0xFFFF0000;
  1225. MSG _msg;
  1226. ::memset( &_msg, 0, sizeof(MSG) );
  1227. _msg.hwnd = pMHEX->mhs.hwnd;
  1228. _msg.wParam = WPARAM(dwWheelDeltaAndZeroFlags);
  1229. _msg.lParam = MAKELPARAM(pMHEX->mhs.pt.x,pMHEX->mhs.pt.y);
  1230. _msg.message = WM_MOUSEWHEEL;
  1231. // TRACE1( "wheel_msg = %xn", _msg.message );
  1232. DWORD dwEHSEF = HookSpyGetEHSEF();
  1233. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1234. {
  1235. if( HSLL_PreTranslateMessage( &_msg ) )
  1236. return true;
  1237. if( ! HookSpyIsRegistered() )
  1238. return false;
  1239. }
  1240. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1241. {
  1242. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1243. return true;
  1244. if( ! HookSpyIsRegistered() )
  1245. return false;
  1246. }
  1247. if( OnHookSpyMouseWheelMsg( &_msg ) )
  1248. return true;
  1249. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1250. {
  1251. if( OnHookSpyPostProcessMessage( &_msg ) )
  1252. return true;
  1253. }
  1254. return false;
  1255. }
  1256. bool CExtHookSpy::HSLL_OnMouseMove(
  1257. HWND hWnd,
  1258. UINT nFlags,
  1259. CPoint point
  1260. )
  1261. {
  1262. if( hWnd == NULL
  1263. || (! ::IsWindow(hWnd) )
  1264. || (! ::GetCursorPos(&point) ) 
  1265. )
  1266. return false;
  1267. ::ScreenToClient( hWnd, &point );
  1268. MSG _msg;
  1269. ::memset( &_msg, 0, sizeof(MSG) );
  1270. _msg.hwnd = hWnd;
  1271. _msg.wParam = WPARAM(nFlags);
  1272. _msg.lParam = MAKELPARAM( point.x, point.y );
  1273. _msg.message = WM_MOUSEMOVE;
  1274. _msg.pt = point;
  1275. DWORD dwEHSEF = HookSpyGetEHSEF();
  1276. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1277. {
  1278. if( HSLL_PreTranslateMessage( &_msg ) )
  1279. return true;
  1280. if( ! HookSpyIsRegistered() )
  1281. return false;
  1282. }
  1283. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1284. {
  1285. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1286. return true;
  1287. if( ! HookSpyIsRegistered() )
  1288. return false;
  1289. }
  1290. if( OnHookSpyMouseMoveMsg( &_msg ) )
  1291. return true;
  1292. if( ! HookSpyIsRegistered() )
  1293. return false;
  1294. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1295. {
  1296. if( OnHookSpyPostProcessMessage( &_msg ) )
  1297. return true;
  1298. }
  1299. return false;
  1300. }
  1301. bool CExtHookSpy::HSLL_OnMouseClick(
  1302. HWND hWnd,
  1303. UINT nMessage,
  1304. UINT nFlags,
  1305. CPoint point
  1306. )
  1307. {
  1308. MSG _msg;
  1309. ::memset( &_msg, 0, sizeof(MSG) );
  1310. _msg.hwnd = hWnd;
  1311. _msg.wParam = WPARAM(nFlags);
  1312. _msg.lParam = MAKELPARAM(point.x,point.y);
  1313. _msg.message = nMessage;
  1314. ::ScreenToClient( hWnd, &point );
  1315. _msg.pt = point;
  1316. DWORD dwEHSEF = HookSpyGetEHSEF();
  1317. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1318. {
  1319. if( HSLL_PreTranslateMessage( &_msg ) )
  1320. return true;
  1321. if( ! HookSpyIsRegistered() )
  1322. return false;
  1323. }
  1324. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1325. {
  1326. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1327. return true;
  1328. if( ! HookSpyIsRegistered() )
  1329. return false;
  1330. }
  1331. if( OnHookSpyMouseClickMsg( &_msg ) )
  1332. return true;
  1333. if( ! HookSpyIsRegistered() )
  1334. return false;
  1335. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1336. {
  1337. if( OnHookSpyPostProcessMessage( &_msg ) )
  1338. return true;
  1339. }
  1340. return false;
  1341. }
  1342. bool CExtHookSpy::HSLL_OnKey(
  1343. UINT nChar,
  1344. UINT nRepCnt,
  1345. UINT nFlags
  1346. )
  1347. {
  1348. MSG _msg;
  1349. ::memset( &_msg, 0, sizeof(MSG) );
  1350. _msg.hwnd = ::GetFocus();
  1351. _msg.wParam = WPARAM(nChar);
  1352. _msg.lParam = MAKELPARAM(nRepCnt,nFlags);
  1353. _msg.message =
  1354. ( ( nFlags & (KF_UP) ) != 0 )
  1355. ? WM_KEYUP
  1356. : WM_KEYDOWN
  1357. ;
  1358. // TRACE3(
  1359. // "key_msg = %x (%s), flags = 0x%04Xn",
  1360. // _msg.message,
  1361. // (_msg.message == WM_KEYUP) ? "WM_KEYUP" : "WM_KEYDOWN",
  1362. // nFlags
  1363. // );
  1364. DWORD dwEHSEF = HookSpyGetEHSEF();
  1365. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1366. {
  1367. if( HSLL_PreTranslateMessage( &_msg ) )
  1368. return true;
  1369. if( ! HookSpyIsRegistered() )
  1370. return false;
  1371. }
  1372. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1373. {
  1374. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1375. return true;
  1376. if( ! HookSpyIsRegistered() )
  1377. return false;
  1378. }
  1379. if( OnHookSpyKeyMsg( &_msg ) )
  1380. return true;
  1381. if( ! HookSpyIsRegistered() )
  1382. return false;
  1383. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1384. {
  1385. if( OnHookSpyPostProcessMessage( &_msg ) )
  1386. return true;
  1387. }
  1388. return false;
  1389. }
  1390. bool CExtHookSpy::HSLL_OnGetMsgProc(
  1391. bool & bCallNextHook,
  1392. LRESULT & lResult,
  1393. int nCode,
  1394. WPARAM wParam,
  1395. MSG * pMSG
  1396. )
  1397. {
  1398. lResult;
  1399. if( nCode != HC_ACTION )
  1400. return false;
  1401. if( wParam != PM_REMOVE )
  1402. return false;
  1403. DWORD dwEHSEF = HookSpyGetEHSEF();
  1404. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1405. {
  1406. if( HSLL_PreTranslateMessage( pMSG ) )
  1407. {
  1408. bCallNextHook = false;
  1409. return true;
  1410. }
  1411. if( ! HookSpyIsRegistered() )
  1412. return false;
  1413. }
  1414. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1415. {
  1416. if( OnHookSpyPreTranslateMessage( pMSG ) )
  1417. {
  1418. bCallNextHook = false;
  1419. return true;
  1420. }
  1421. if( ! HookSpyIsRegistered() )
  1422. return false;
  1423. }
  1424. if( OnHookSpyGetMsgProc( pMSG ) )
  1425. {
  1426. bCallNextHook = false;
  1427. return true;
  1428. }
  1429. if( ! HookSpyIsRegistered() )
  1430. return false;
  1431. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1432. {
  1433. if( OnHookSpyPostProcessMessage( pMSG ) )
  1434. {
  1435. bCallNextHook = false;
  1436. return true;
  1437. }
  1438. }
  1439. return false;
  1440. }
  1441. bool CExtHookSpy::HSLL_OnSysMsgProc(
  1442. bool & bCallNextHook,
  1443. LRESULT & lResult,
  1444. int nCode,
  1445. WPARAM wParam,
  1446. LPARAM lParam
  1447. )
  1448. {
  1449. // lResult;
  1450. // if( nCode != HC_ACTION )
  1451. // return false;
  1452. bCallNextHook;
  1453. lResult;
  1454. nCode;
  1455. wParam;
  1456. lParam;
  1457. return false;
  1458. }
  1459. bool CExtHookSpy::HSLL_OnCallWindowProcIn(
  1460. bool & bCallNextHook,
  1461. LRESULT & lResult,
  1462. int nCode,
  1463. bool bMessageSentByCurrentThread,
  1464. PCWPSTRUCT pMessageData
  1465. )
  1466. {
  1467. bCallNextHook;
  1468. lResult;
  1469. bMessageSentByCurrentThread;
  1470. if( nCode != HC_ACTION )
  1471. return false;
  1472. MSG _msg;
  1473. ::memset( &_msg, 0, sizeof(MSG) );
  1474. _msg.hwnd = pMessageData->hwnd;
  1475. _msg.wParam = pMessageData->wParam;
  1476. _msg.lParam = pMessageData->lParam;
  1477. _msg.message = pMessageData->message;
  1478. DWORD dwEHSEF = HookSpyGetEHSEF();
  1479. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1480. {
  1481. if( HSLL_PreTranslateMessage( &_msg ) )
  1482. return true;
  1483. if( ! HookSpyIsRegistered() )
  1484. return false;
  1485. }
  1486. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1487. {
  1488. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1489. return true;
  1490. if( ! HookSpyIsRegistered() )
  1491. return false;
  1492. }
  1493. if( OnHookSpyCallWindowProcIn( &_msg ) )
  1494. return true;
  1495. if( ! HookSpyIsRegistered() )
  1496. return false;
  1497. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1498. {
  1499. if( OnHookSpyPostProcessMessage( &_msg ) )
  1500. return true;
  1501. }
  1502. return false;
  1503. }
  1504. bool CExtHookSpy::HSLL_OnCallWindowProcOut(
  1505. bool & bCallNextHook,
  1506. LRESULT & lResult,
  1507. int nCode,
  1508. bool bMessageSentByCurrentThread,
  1509. PCWPRETSTRUCT pMessageData
  1510. )
  1511. {
  1512. bCallNextHook;
  1513. lResult;
  1514. bMessageSentByCurrentThread;
  1515. if( nCode != HC_ACTION )
  1516. return false;
  1517. MSG _msg;
  1518. ::memset( &_msg, 0, sizeof(MSG) );
  1519. _msg.hwnd = pMessageData->hwnd;
  1520. _msg.wParam = pMessageData->wParam;
  1521. _msg.lParam = pMessageData->lParam;
  1522. _msg.message = pMessageData->message;
  1523. DWORD dwEHSEF = HookSpyGetEHSEF();
  1524. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION_LL ) != 0 )
  1525. {
  1526. if( HSLL_PreTranslateMessage( &_msg ) )
  1527. return true;
  1528. if( ! HookSpyIsRegistered() )
  1529. return false;
  1530. }
  1531. if( ( dwEHSEF & __EHSEF_PRE_TRANSLATION ) != 0 )
  1532. {
  1533. if( OnHookSpyPreTranslateMessage( &_msg ) )
  1534. return true;
  1535. if( ! HookSpyIsRegistered() )
  1536. return false;
  1537. }
  1538. if( OnHookSpyCallWindowProcOut( &_msg ) )
  1539. return true;
  1540. if( ! HookSpyIsRegistered() )
  1541. return false;
  1542. if( ( dwEHSEF & __EHSEF_POST_PROCESSING ) != 0 )
  1543. {
  1544. if( OnHookSpyPostProcessMessage( &_msg ) )
  1545. return true;
  1546. }
  1547. return false;
  1548. }
  1549. bool CExtHookSpy::HSLL_PreTranslateMessage(
  1550. MSG * pMSG
  1551. )
  1552. {
  1553. ASSERT( pMSG != NULL );
  1554. pMSG;
  1555. return false;
  1556. }
  1557. bool CExtHookSpy::OnHookSpyPreTranslateMessage(
  1558. MSG * pMSG
  1559. )
  1560. {
  1561. ASSERT( pMSG != NULL );
  1562. pMSG;
  1563. return false;
  1564. }
  1565. bool CExtHookSpy::OnHookSpyPostProcessMessage(
  1566. MSG * pMSG
  1567. )
  1568. {
  1569. ASSERT( pMSG != NULL );
  1570. pMSG;
  1571. return false;
  1572. }
  1573. bool CExtHookSpy::OnHookSpyMouseWheelMsg(
  1574. MSG * pMSG
  1575. )
  1576. {
  1577. ASSERT( pMSG != NULL );
  1578. pMSG;
  1579. return false;
  1580. }
  1581. bool CExtHookSpy::OnHookSpyMouseMoveMsg(
  1582. MSG * pMSG
  1583. )
  1584. {
  1585. ASSERT( pMSG != NULL );
  1586. pMSG;
  1587. return false;
  1588. }
  1589. bool CExtHookSpy::OnHookSpyMouseClickMsg(
  1590. MSG * pMSG
  1591. )
  1592. {
  1593. ASSERT( pMSG != NULL );
  1594. pMSG;
  1595. return false;
  1596. }
  1597. bool CExtHookSpy::OnHookSpyKeyMsg(
  1598. MSG * pMSG
  1599. )
  1600. {
  1601. ASSERT( pMSG != NULL );
  1602. pMSG;
  1603. return false;
  1604. }
  1605. bool CExtHookSpy::OnHookSpyGetMsgProc(
  1606. MSG * pMSG
  1607. )
  1608. {
  1609. ASSERT( pMSG != NULL );
  1610. pMSG;
  1611. return false;
  1612. }
  1613. //bool CExtHookSpy::OnHookSpySysMsgProc(
  1614. // MSG * pMSG
  1615. // )
  1616. //{
  1617. // ASSERT( pMSG != NULL );
  1618. // pMSG;
  1619. // return false;
  1620. //}
  1621. bool CExtHookSpy::OnHookSpyCallWindowProcIn(
  1622. MSG * pMSG
  1623. )
  1624. {
  1625. ASSERT( pMSG != NULL );
  1626. pMSG;
  1627. return false;
  1628. }
  1629. bool CExtHookSpy::OnHookSpyCallWindowProcOut(
  1630. MSG * pMSG
  1631. )
  1632. {
  1633. ASSERT( pMSG != NULL );
  1634. pMSG;
  1635. return false;
  1636. }
  1637. void CExtHookSpy::HookSpyRegister(
  1638. DWORD dwEHSEF, // = __EHSEF_ALL
  1639. bool bAddToHead // = true
  1640. )
  1641. {
  1642. HookSpyRegister( this, dwEHSEF, bAddToHead );
  1643. }
  1644. void CExtHookSpy::HookSpyRegister(
  1645. CExtHookSpy * pHS,
  1646. DWORD dwEHSEF, // = __EHSEF_ALL
  1647. bool bAddToHead // = true
  1648. )
  1649. {
  1650. __PROF_UIS_MANAGE_STATE;
  1651. if( pHS == NULL )
  1652. return;
  1653. if( dwEHSEF == 0 )
  1654. {
  1655. HookSpyUnregister( pHS );
  1656. return;
  1657. }
  1658. INT nIndex, nCount = __EHS_IDX_COUNT;
  1659. for( nIndex = 0; nIndex < nCount; nIndex ++ )
  1660. g_arr[ nIndex ].Register( pHS, dwEHSEF, bAddToHead );
  1661. if( ( pHS->HookSpyGetEHSEF() & __EHSEF_BASIC_HOOK_FILTERING ) != 0 )
  1662. pHS->HookSpyModifyEHSEF( 0, dwEHSEF&__EHSEF_ADDITIONAL_PROCESSING );
  1663. }
  1664. void CExtHookSpy::HookSpyUnregister(
  1665. DWORD dwEHSEF // = __EHSEF_ALL
  1666. )
  1667. {
  1668. HookSpyUnregister( this, dwEHSEF );
  1669. }
  1670. void CExtHookSpy::HookSpyUnregister(
  1671. CExtHookSpy * pHS,
  1672. DWORD dwEHSEF // = __EHSEF_ALL
  1673. )
  1674. {
  1675. __PROF_UIS_MANAGE_STATE;
  1676. if( pHS == NULL || dwEHSEF == 0 )
  1677. return;
  1678. INT nIndex, nCount = __EHS_IDX_COUNT;
  1679. for( nIndex = 0; nIndex < nCount; nIndex ++ )
  1680. g_arr[ nIndex ].Unregister( pHS, dwEHSEF );
  1681. if( ( pHS->HookSpyGetEHSEF() & __EHSEF_BASIC_HOOK_FILTERING ) == 0 )
  1682. pHS->HookSpyModifyEHSEF( dwEHSEF&__EHSEF_ADDITIONAL_PROCESSING, 0 );
  1683. }
  1684. bool CExtHookSpy::HookSpyIsRegistered(
  1685. const CExtHookSpy * pHS,
  1686. DWORD dwEHSEF // = __EHSEF_ALL
  1687. )
  1688. {
  1689. __PROF_UIS_MANAGE_STATE;
  1690. if( pHS == NULL || dwEHSEF == 0 )
  1691. return false;
  1692. INT nIndex, nCount = __EHS_IDX_COUNT;
  1693. for( nIndex = 0; nIndex < nCount; nIndex ++ )
  1694. {
  1695. if( g_arr[ nIndex ].IsRegistered( ((CExtHookSpy*)pHS), dwEHSEF ) )
  1696. return true;
  1697. }
  1698. return false;
  1699. }