HookMgr.h
上传用户:weijiexitu
上传日期:2007-01-18
资源大小:54k
文件大小:9k
源码类别:

菜单

开发平台:

WINDOWS

  1. // HookMgr.h: interface for the CHookMgr class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_HOOKMGR_H__05A75CB2_8E05_4179_8DD8_ACFEF7D7EF7C__INCLUDED_)
  5. #define AFX_HOOKMGR_H__05A75CB2_8E05_4179_8DD8_ACFEF7D7EF7C__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. static inline BOOL ClassMatches(HWND hwnd, LPCTSTR szClassType)
  10. {
  11. if (!szClassType || !lstrlen(szClassType))
  12. return TRUE;
  13. // else
  14. static char szClassName[40];
  15. ::GetClassName(hwnd, szClassName, 40);
  16. return (lstrcmpi(szClassType, szClassName) == 0);
  17. }
  18. #define INITHOOK(hook, flag, type, function) 
  19. if (dwOptions & flag) 
  20. hook = SetWindowsHookEx(type, function, NULL, GetCurrentThreadId()); 
  21. }
  22. #define RELEASEHOOK(hook) 
  23. if (hook) 
  24. UnhookWindowsHookEx(hook); 
  25. hook = NULL; 
  26. }
  27. enum 
  28. {
  29. HM_CALLWNDPROC = 0x0001,
  30. HM_CALLWNDPROCRET = 0x0002,
  31. HM_CBT = 0x0004,
  32. HM_FOREGROUNDIDLE = 0x0008,
  33. HM_GETMESSAGE = 0x0010,
  34. HM_KEYBOARD = 0x0020,
  35. HM_MOUSE = 0x0040,
  36. HM_MSGFILTER = 0x0080,
  37. HM_SHELL = 0x0100,
  38. HM_SYSMSGFILTER = 0x0200,
  39. };
  40. #ifndef HSHELL_APPCOMMAND
  41. #define HSHELL_APPCOMMAND           12
  42. #endif
  43. template<class MGRTYPE>
  44. class CHookMgr  
  45. {
  46. public:
  47. virtual ~CHookMgr() { Release(); }
  48. protected:
  49. BOOL InitHooks(DWORD dwOptions = HM_CALLWNDPROC, LPCTSTR szClassFilter = NULL)
  50. {
  51. Release(); // reset
  52. INITHOOK(m_hCallWndHook, HM_CALLWNDPROC, WH_CALLWNDPROC, CallWndProc);
  53. INITHOOK(m_hCallWndRetHook, HM_CALLWNDPROCRET, WH_CALLWNDPROCRET, CallWndRetProc);
  54. INITHOOK(m_hCbtHook, HM_CBT, WH_CBT, CbtProc);
  55. INITHOOK(m_hForegroundIdleHook, HM_FOREGROUNDIDLE, WH_FOREGROUNDIDLE, ForegroundIdleProc);
  56. INITHOOK(m_hGetMessageHook, HM_GETMESSAGE, WH_GETMESSAGE, GetMessageProc);
  57. INITHOOK(m_hKeyboardHook, HM_KEYBOARD, WH_KEYBOARD, KeyboardProc);
  58. INITHOOK(m_hMouseHook, HM_MOUSE, WH_MOUSE, MouseProc);
  59. INITHOOK(m_hMsgFilterHook, HM_MSGFILTER, WH_MSGFILTER, MsgFilterProc);
  60. INITHOOK(m_hShellHook, HM_SHELL, WH_SHELL, ShellProc);
  61. INITHOOK(m_hSysMsgFilterHook, HM_SYSMSGFILTER, WH_SYSMSGFILTER, SysMsgFilterProc);
  62. m_sClassFilter = szClassFilter;
  63. return TRUE;
  64. }
  65. void Release()
  66. {
  67. RELEASEHOOK(m_hCallWndHook);
  68. RELEASEHOOK(m_hCallWndRetHook);
  69. RELEASEHOOK(m_hCbtHook);
  70. RELEASEHOOK(m_hForegroundIdleHook);
  71. RELEASEHOOK(m_hGetMessageHook);
  72. RELEASEHOOK(m_hKeyboardHook);
  73. RELEASEHOOK(m_hMouseHook);
  74. RELEASEHOOK(m_hMsgFilterHook);
  75. RELEASEHOOK(m_hShellHook);
  76. RELEASEHOOK(m_hSysMsgFilterHook);
  77. }
  78. protected:
  79. HHOOK m_hCallWndHook;
  80. HHOOK m_hCallWndRetHook;
  81. HHOOK m_hCbtHook;
  82. HHOOK m_hForegroundIdleHook;
  83. HHOOK m_hGetMessageHook;
  84. HHOOK m_hKeyboardHook;
  85. HHOOK m_hMouseHook;
  86. HHOOK m_hMsgFilterHook;
  87. HHOOK m_hShellHook;
  88. HHOOK m_hSysMsgFilterHook;
  89. CString m_sClassFilter;
  90. protected:
  91. static MGRTYPE& GetInstance()
  92. static MGRTYPE manager; 
  93. return manager; 
  94. }
  95. CHookMgr() // cannot instanciate one of these directly
  96. {
  97. m_hCallWndHook = NULL;
  98. m_hCallWndRetHook = NULL;
  99. m_hCbtHook = NULL;
  100. m_hForegroundIdleHook = NULL;
  101. m_hGetMessageHook = NULL;
  102. m_hKeyboardHook = NULL;
  103. m_hMouseHook = NULL;
  104. m_hMsgFilterHook = NULL;
  105. m_hShellHook = NULL;
  106. m_hSysMsgFilterHook = NULL;
  107. }
  108. // derived classes override whatever they need
  109. virtual void OnCallWndProc(const MSG& msg) { ASSERT (0); }
  110. virtual void OnCallWndRetProc(const MSG& msg, LRESULT lResult) { ASSERT (0); }
  111. virtual BOOL OnCbt(int nCode, WPARAM wParam, LPARAM lParam) { ASSERT (0); return FALSE; }
  112. virtual void OnForegroundIdle() { ASSERT (0); }
  113. virtual void OnGetMessage(const MSG& msg) { ASSERT (0); }
  114. virtual void OnKeyboard(UINT uVirtKey, UINT uFlags) { ASSERT (0); }
  115. virtual void OnMouse(UINT uMouseMsg, const CPoint& ptMouse) { ASSERT (0); }
  116. virtual void OnMsgFilter(const MSG& msg, int nEvent) { ASSERT (0); }
  117. virtual BOOL OnShell(int nCode, WPARAM wParam, LPARAM lParam) { ASSERT (0); return FALSE; }
  118. virtual void OnSysMsgFilter(const MSG& msg, int nEvent) { ASSERT (0); }
  119. inline BOOL ClassMatches(HWND hwnd)
  120. {
  121. return ::ClassMatches(hwnd, m_sClassFilter);
  122. }
  123. // global app hooks
  124. // WH_CALLWNDPROC
  125. static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
  126. {
  127. #ifdef _USRDLL
  128. // If this is a DLL, need to set up MFC state
  129. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  130. #endif
  131. if (nCode == HC_ACTION)
  132. {
  133. CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
  134. if (GetInstance().ClassMatches(pwp->hwnd))
  135. {
  136. MSG msg = { pwp->hwnd, pwp->message, pwp->wParam, pwp->lParam, 0, { 0, 0 } };
  137. GetInstance().OnCallWndProc(msg);
  138. }
  139. }
  140. return CallNextHookEx(GetInstance().m_hCallWndHook, nCode, wParam, lParam);
  141. }
  142. // WH_CALLWNDRETPROC
  143. static LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
  144. {
  145. #ifdef _USRDLL
  146. // If this is a DLL, need to set up MFC state
  147. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  148. #endif
  149. if (nCode == HC_ACTION)
  150. {
  151. CWPRETSTRUCT* pwp = (CWPRETSTRUCT*)lParam;
  152. if (GetInstance().ClassMatches(pwp->hwnd))
  153. {
  154. MSG msg = { pwp->hwnd, pwp->message, pwp->wParam, pwp->lParam, 0, { 0, 0 } };
  155. GetInstance().OnCallWndRetProc(msg, pwp->lResult);
  156. }
  157. }
  158. return CallNextHookEx(GetInstance().m_hCallWndHook, nCode, wParam, lParam);
  159. }
  160. // WH_CBT
  161. static LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)
  162. {
  163. #ifdef _USRDLL
  164. // If this is a DLL, need to set up MFC state
  165. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  166. #endif
  167. if (nCode == HC_ACTION)
  168. {
  169. if (GetInstance().OnCbt(nCode, wParam, lParam))
  170. return TRUE;
  171. }
  172. // else
  173. return CallNextHookEx(GetInstance().m_hCbtHook, nCode, wParam, lParam);
  174. }
  175. // HM_FOREGROUNDIDLE
  176. static LRESULT CALLBACK ForegroundIdleProc(int nCode, WPARAM wParam, LPARAM lParam)
  177. {
  178. #ifdef _USRDLL
  179. // If this is a DLL, need to set up MFC state
  180. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  181. #endif
  182. if (nCode == HC_ACTION)
  183. {
  184. GetInstance().OnForegroundIdle();
  185. }
  186. return CallNextHookEx(GetInstance().m_hForegroundIdleHook, nCode, wParam, lParam);
  187. }
  188. // WH_GETMESSAGE
  189. static LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
  190. {
  191. #ifdef _USRDLL
  192. // If this is a DLL, need to set up MFC state
  193. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  194. #endif
  195. if (nCode == HC_ACTION)
  196. {
  197. MSG* pMsg = (MSG*)lParam;
  198. if (GetInstance().ClassMatches(pMsg->hwnd))
  199. {
  200. GetInstance().OnGetMessage(*pMsg);
  201. }
  202. }
  203. return CallNextHookEx(GetInstance().m_hGetMessageHook, nCode, wParam, lParam);
  204. }
  205. // WH_KEYBOARD
  206. static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
  207. {
  208. #ifdef _USRDLL
  209. // If this is a DLL, need to set up MFC state
  210. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  211. #endif
  212. if (nCode == HC_ACTION)
  213. {
  214. GetInstance().OnKeyboard(wParam, lParam);
  215. }
  216. return CallNextHookEx(GetInstance().m_hKeyboardHook, nCode, wParam, lParam);
  217. }
  218. // WH_MOUSE
  219. static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  220. {
  221. #ifdef _USRDLL
  222. // If this is a DLL, need to set up MFC state
  223. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  224. #endif
  225. if (nCode == HC_ACTION)
  226. {
  227. CPoint* pCursor = (CPoint*)lParam;
  228. GetInstance().OnMouse(wParam, *pCursor);
  229. }
  230. return CallNextHookEx(GetInstance().m_hMouseHook, nCode, wParam, lParam);
  231. }
  232. // WH_MSGFILTER
  233. static LRESULT CALLBACK MsgFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
  234. {
  235. #ifdef _USRDLL
  236. // If this is a DLL, need to set up MFC state
  237. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  238. #endif
  239. if (nCode == HC_ACTION)
  240. {
  241. MSG* pMsg = (MSG*)lParam;
  242. if (GetInstance().ClassMatches(pMsg->hwnd))
  243. GetInstance().OnMsgFilter(*pMsg, nCode);
  244. }
  245. return CallNextHookEx(GetInstance().m_hMsgFilterHook, nCode, wParam, lParam);
  246. }
  247. // WH_SHELL
  248. static LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
  249. {
  250. #ifdef _USRDLL
  251. // If this is a DLL, need to set up MFC state
  252. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  253. #endif
  254. if (GetInstance().OnShell(nCode, wParam, lParam))
  255. {
  256. if (nCode == HSHELL_APPCOMMAND)
  257. return TRUE;
  258. }
  259. // else
  260. return 0;//CallNextHookEx(GetInstance().m_hShellHook, nCode, wParam, lParam);
  261. }
  262. // WH_SYSMSGFILTER
  263. static LRESULT CALLBACK SysMsgFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
  264. {
  265. #ifdef _USRDLL
  266. // If this is a DLL, need to set up MFC state
  267. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  268. #endif
  269. if (nCode == HC_ACTION)
  270. {
  271. MSG* pMsg = (MSG*)lParam;
  272. if (GetInstance().ClassMatches(pMsg->hwnd))
  273. GetInstance().OnSysMsgFilter(*pMsg, nCode);
  274. }
  275. return CallNextHookEx(GetInstance().m_hSysMsgFilterHook, nCode, wParam, lParam);
  276. }
  277. };
  278. #endif // !defined(AFX_HOOKMGR_H__05A75CB2_8E05_4179_8DD8_ACFEF7D7EF7C__INCLUDED_)