DumontEXE 0.0.1
WindowsHookManager.h
00001 // HookMgr.h: interface for the CHookMgr class.
00002 //
00003 // This code was acquired on 08/18/2007 from:
00004 //   http://www.codeproject.com/dll/hookmgr.asp
00005 //
00006 //
00007 //////////////////////////////////////////////////////////////////////
00008 
00009 /*!
00010 ** \brief QWinHookMgr class
00011 **
00012 ** This excellent class implementation is designed to quickly and easily
00013 **  simplify hooking in to windows hwnd call procedures.
00014 **
00015 **
00016 */
00017 
00018 #ifndef WINDOWSHOOKMGR_H_2748b4f0_8167_49cb_8b92_94a2224c6ee7
00019 #define WINDOWSHOOKMGR_H_2748b4f0_8167_49cb_8b92_94a2224c6ee7
00020 
00021 #include <windows.h>
00022 #include <QString>
00023 
00024 #ifndef BOOL
00025 #define BOOL bool
00026 #endif
00027 
00028 #ifndef CPoint
00029 #define CPoint tagPOINT
00030 #endif
00031 
00032 static /*inline*/ BOOL ClassMatches( HWND hwnd, QString & qsClassType )
00033 {
00034   if( !qsClassType.length() )
00035     return TRUE;
00036 
00037   // else
00038   static WCHAR szClassName[40];
00039   ::GetClassName( hwnd, szClassName, 40 );
00040 
00041   QString qsClassName = QString::fromWCharArray(szClassName);
00042 
00043   return( qsClassName == qsClassType );
00044 }
00045 
00046 /*
00047 ** This macro sets a hook reference.
00048 **
00049 */
00050 #define INITHOOK(hook, flag, type, function)                                       \
00051         {                                                                          \
00052           if( dwOptions & flag )                                                   \
00053           {                                                                        \
00054             hook = SetWindowsHookEx( type, function, NULL, GetCurrentThreadId() ); \
00055           }                                                                        \
00056         }
00057 
00058 /*
00059 ** This macro releases a hook reference.
00060 **
00061 */
00062 #define RELEASEHOOK(hook)                                                          \
00063         {                                                                          \
00064           if( hook )                                                               \
00065           {                                                                        \
00066             UnhookWindowsHookEx(hook);                                             \
00067             hook = NULL;                                                           \
00068           }                                                                        \
00069         }
00070 
00071 enum 
00072 {
00073   HM_CALLWNDPROC    = 0x0001,
00074   HM_CALLWNDPROCRET = 0x0002,
00075   HM_CBT            = 0x0004,
00076   HM_FOREGROUNDIDLE = 0x0008,
00077   HM_GETMESSAGE     = 0x0010,
00078   HM_KEYBOARD       = 0x0020,
00079   HM_MOUSE          = 0x0040,
00080   HM_MSGFILTER      = 0x0080,
00081   HM_SHELL          = 0x0100,
00082   HM_SYSMSGFILTER   = 0x0200,
00083 };
00084 
00085 #ifndef HSHELL_APPCOMMAND
00086 #define HSHELL_APPCOMMAND 12
00087 #endif
00088 
00089 template<class MGRTYPE>
00090 class WindowsHookMgr
00091 {
00092   public:
00093     virtual ~WindowsHookMgr() { Release(); }
00094 
00095   protected:
00096 
00097     /*!
00098     ** \brief Initialize the window hooks.
00099     **
00100     ** /par dwOptions Specify the windows procedures that should be hooked.  By
00101     **                 default this is set to HM_CALLWNDPROC.
00102     **
00103     ** /par szClassFilter Specify the class filter to be applied to the override hooks.
00104     **
00105     */
00106     BOOL InitHooks( DWORD dwOptions = HM_CALLWNDPROC, LPCTSTR szClassFilter = NULL )
00107     {
00108       Release(); // reset
00109 
00110       INITHOOK( m_hCallWndHook,        HM_CALLWNDPROC,    WH_CALLWNDPROC,    CallWndProc        );
00111       INITHOOK( m_hCallWndRetHook,     HM_CALLWNDPROCRET, WH_CALLWNDPROCRET, CallWndRetProc     );
00112       INITHOOK( m_hCbtHook,            HM_CBT,            WH_CBT,            CbtProc            );
00113       INITHOOK( m_hForegroundIdleHook, HM_FOREGROUNDIDLE, WH_FOREGROUNDIDLE, ForegroundIdleProc );
00114       INITHOOK( m_hGetMessageHook,     HM_GETMESSAGE,     WH_GETMESSAGE,     GetMessageProc     );
00115       INITHOOK( m_hKeyboardHook,       HM_KEYBOARD,       WH_KEYBOARD,       KeyboardProc       );
00116       INITHOOK( m_hMouseHook,          HM_MOUSE,          WH_MOUSE,          MouseProc          );
00117       INITHOOK( m_hMsgFilterHook,      HM_MSGFILTER,      WH_MSGFILTER,      MsgFilterProc      );
00118       INITHOOK( m_hShellHook,          HM_SHELL,          WH_SHELL,          ShellProc          );
00119       INITHOOK( m_hSysMsgFilterHook,   HM_SYSMSGFILTER,   WH_SYSMSGFILTER,   SysMsgFilterProc   );
00120 
00121       m_sClassFilter = szClassFilter;
00122 
00123       return TRUE;
00124     }
00125 
00126     void Release()
00127     {
00128       RELEASEHOOK( m_hCallWndHook        );
00129       RELEASEHOOK( m_hCallWndRetHook     );
00130       RELEASEHOOK( m_hCbtHook            );
00131       RELEASEHOOK( m_hForegroundIdleHook );
00132       RELEASEHOOK( m_hGetMessageHook     );
00133       RELEASEHOOK( m_hKeyboardHook       );
00134       RELEASEHOOK( m_hMouseHook          );
00135       RELEASEHOOK( m_hMsgFilterHook      );
00136       RELEASEHOOK( m_hShellHook          );
00137       RELEASEHOOK( m_hSysMsgFilterHook   );
00138     }
00139 
00140   protected:
00141 
00142     HHOOK   m_hCallWndHook;
00143     HHOOK   m_hCallWndRetHook;
00144     HHOOK   m_hCbtHook;
00145     HHOOK   m_hForegroundIdleHook;
00146     HHOOK   m_hGetMessageHook;
00147     HHOOK   m_hKeyboardHook;
00148     HHOOK   m_hMouseHook;
00149     HHOOK   m_hMsgFilterHook;
00150     HHOOK   m_hShellHook;
00151     HHOOK   m_hSysMsgFilterHook;
00152     QString m_sClassFilter;
00153 
00154   protected:
00155 
00156     /*
00157     ** This returns the static instance of this object.
00158     **
00159     */
00160     static MGRTYPE & GetInstance()
00161     { 
00162       static MGRTYPE manager; 
00163       return manager; 
00164     }
00165 
00166     /*
00167     ** This constructor insures all the hook references are
00168     **  cleared.
00169     **
00170     */
00171     WindowsHookMgr() // cannot instanciate one of these directly
00172     {
00173       m_hCallWndHook        = NULL;
00174       m_hCallWndRetHook     = NULL;
00175       m_hCbtHook            = NULL;
00176       m_hForegroundIdleHook = NULL;
00177       m_hGetMessageHook     = NULL;
00178       m_hKeyboardHook       = NULL;
00179       m_hMouseHook          = NULL;
00180       m_hMsgFilterHook      = NULL;
00181       m_hShellHook          = NULL;
00182       m_hSysMsgFilterHook   = NULL;
00183     }
00184 
00185     /*
00186     ** derived classes override whatever they need
00187     **
00188     */
00189     virtual void OnCallWndProc    ( const MSG& msg                                 ) { Q_ASSERT( 0 );               }
00190     virtual void OnCallWndRetProc ( const MSG& msg,  LRESULT lResult               ) { Q_ASSERT( 0 );               }
00191     virtual BOOL OnCbt            ( int   nCode,     WPARAM  wParam, LPARAM lParam ) { Q_ASSERT( 0 ); return FALSE; }
00192     virtual void OnForegroundIdle (                                                ) { Q_ASSERT( 0 );               }
00193     virtual void OnGetMessage     ( const MSG& msg                                 ) { Q_ASSERT( 0 );               }
00194     virtual void OnKeyboard       ( UINT  uVirtKey,  UINT    uFlags                ) { Q_ASSERT( 0 );               }
00195     virtual void OnMouse          ( UINT  uMouseMsg, const   CPoint& ptMouse       ) { Q_ASSERT( 0 );               }
00196     virtual void OnMsgFilter      ( const MSG& msg,  int     nEvent                ) { Q_ASSERT( 0 );               }
00197     virtual BOOL OnShell          ( int   nCode,     WPARAM  wParam, LPARAM lParam ) { Q_ASSERT( 0 ); return FALSE; }
00198     virtual void OnSysMsgFilter   ( const MSG& msg,  int     nEvent                ) { Q_ASSERT( 0 );               }
00199 
00200     inline BOOL ClassMatches( HWND hwnd )
00201     {
00202       return ::ClassMatches( hwnd, m_sClassFilter );
00203     }
00204 
00205     // global app hooks
00206 
00207     // WH_CALLWNDPROC
00208     static LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
00209     {
00210       if( nCode == HC_ACTION )
00211       {
00212         CWPSTRUCT * pwp = (CWPSTRUCT*) lParam;
00213 
00214         if( GetInstance().ClassMatches( pwp->hwnd ) )
00215         {
00216           MSG msg = { pwp->hwnd, pwp->message, pwp->wParam, pwp->lParam, 0, { 0, 0 } };
00217           GetInstance().OnCallWndProc( msg );
00218         }
00219       }
00220       return CallNextHookEx( GetInstance().m_hCallWndHook, nCode, wParam, lParam );
00221     }
00222 
00223     // WH_CALLWNDRETPROC
00224     static LRESULT CALLBACK CallWndRetProc( int nCode, WPARAM wParam, LPARAM lParam )
00225     {
00226       if( nCode == HC_ACTION )
00227       {
00228         CWPRETSTRUCT * pwp = (CWPRETSTRUCT*) lParam;
00229 
00230         if( GetInstance().ClassMatches( pwp->hwnd ) )
00231         {
00232           MSG msg = { pwp->hwnd, pwp->message, pwp->wParam, pwp->lParam, 0, { 0, 0 } };
00233           GetInstance().OnCallWndRetProc( msg, pwp->lResult );
00234         }
00235       }
00236       return CallNextHookEx( GetInstance().m_hCallWndHook, nCode, wParam, lParam );
00237     }
00238 
00239     // WH_CBT
00240     static LRESULT CALLBACK CbtProc( int nCode, WPARAM wParam, LPARAM lParam )
00241     {
00242       if( nCode == HC_ACTION )
00243       {
00244         if( GetInstance().OnCbt( nCode, wParam, lParam ) )
00245           return TRUE;
00246       }
00247       
00248       // else
00249       return CallNextHookEx( GetInstance().m_hCbtHook, nCode, wParam, lParam );
00250     }
00251 
00252     // HM_FOREGROUNDIDLE
00253     static LRESULT CALLBACK ForegroundIdleProc( int nCode, WPARAM wParam, LPARAM lParam )
00254     {
00255       if( nCode == HC_ACTION )
00256       {
00257         GetInstance().OnForegroundIdle();
00258       }
00259       
00260       return CallNextHookEx( GetInstance().m_hForegroundIdleHook, nCode, wParam, lParam );
00261     }
00262 
00263     // WH_GETMESSAGE
00264     static LRESULT CALLBACK GetMessageProc( int nCode, WPARAM wParam, LPARAM lParam )
00265     {
00266       if( nCode == HC_ACTION )
00267       {
00268         MSG* pMsg = (MSG*)lParam;
00269 
00270         if( GetInstance().ClassMatches( pMsg->hwnd ) )
00271             GetInstance().OnGetMessage( *pMsg );
00272       }
00273       
00274       return CallNextHookEx( GetInstance().m_hGetMessageHook, nCode, wParam, lParam );
00275     }
00276 
00277     // WH_KEYBOARD
00278     static LRESULT CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
00279     {
00280       if( nCode == HC_ACTION )
00281       {
00282         GetInstance().OnKeyboard( wParam, lParam );
00283       }
00284       
00285       return CallNextHookEx( GetInstance().m_hKeyboardHook, nCode, wParam, lParam );
00286     }
00287 
00288     // WH_MOUSE
00289     static LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam )
00290     {
00291       if( nCode == HC_ACTION )
00292       {
00293         CPoint* pCursor = (CPoint*)lParam;
00294         GetInstance().OnMouse( wParam, *pCursor );
00295       }
00296       
00297       return CallNextHookEx( GetInstance().m_hMouseHook, nCode, wParam, lParam );
00298     }
00299 
00300     // WH_MSGFILTER
00301     static LRESULT CALLBACK MsgFilterProc( int nCode, WPARAM wParam, LPARAM lParam )
00302     {
00303       if( nCode == HC_ACTION )
00304       {
00305         MSG* pMsg = (MSG*)lParam;
00306 
00307         if( GetInstance().ClassMatches( pMsg->hwnd) )
00308             GetInstance().OnMsgFilter( *pMsg, nCode );
00309       }
00310 
00311       return CallNextHookEx( GetInstance().m_hMsgFilterHook, nCode, wParam, lParam );
00312     }
00313 
00314     // WH_SHELL
00315     static LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
00316     {
00317       if( GetInstance().OnShell( nCode, wParam, lParam ) )
00318       {
00319         if( nCode == HSHELL_APPCOMMAND )
00320           return TRUE;
00321       }
00322       
00323       // else
00324       return 0;//CallNextHookEx(GetInstance().m_hShellHook, nCode, wParam, lParam);
00325     }
00326 
00327     // WH_SYSMSGFILTER
00328     static LRESULT CALLBACK SysMsgFilterProc( int nCode, WPARAM wParam, LPARAM lParam )
00329     {
00330       if( nCode == HC_ACTION )
00331       {
00332         MSG* pMsg = (MSG*)lParam;
00333 
00334         if( GetInstance().ClassMatches(pMsg->hwnd) )
00335             GetInstance().OnSysMsgFilter( *pMsg, nCode );
00336       }
00337       
00338       return CallNextHookEx( GetInstance().m_hSysMsgFilterHook, nCode, wParam, lParam );
00339     }
00340 
00341 };
00342 
00343 #endif // #ifndef WINDOWSHOOKMGR_H_2748b4f0_8167_49cb_8b92_94a2224c6ee7
00344 
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com