home *** CD-ROM | disk | FTP | other *** search
- // Pavel Zolnikov[http://www.codeproject.com/script/profile/whos_who.asp?id=35980], 2002
-
- using System;
- using System.Runtime.InteropServices;
-
- namespace ZCommon
- {
- /// <summary>
- /// Implements base functionality required for setting Windows Hooks (SetWindowsHookEx API)
- /// </summary>
- /// <example>
- ///
- /// //Sample hook that raises Idle event when thread is about to go idle.
- /// //Can be usefull for procesing background lo priority tasks
- /// public class IdleHook : WindowsHook
- /// {
- /// public void Start()
- /// {
- /// UnHookMe();
- /// HookMe(11);//WH_FOREGROUNDIDLE
- /// }
- ///
- /// public void Stop()
- /// {
- /// UnHookMe();
- /// }
- ///
- /// public event EventHandler Idle;
- ///
- /// protected override Int32 HookCallBack(Int32 ncode, Int32 wParam, Int32 lParam)
- /// {
- /// if( Idle != null )
- /// Idle(this, EventArgs.Empty);
- ///
- /// return base.HookCallBack(ncode, wParam, lParam);
- /// }
- /// }
- /// </example>
- abstract public class WindowsHook : MarshalByRefObject, IDisposable
- {
- WindowsHook.WindowsHookCallBack hookDelegate;
- IntPtr hhook;
-
- /// <summary>
- /// Override this function to process hooks
- /// </summary>
- /// <remarks>
- /// Call <code>return base.HookCallBack(ncode, wParam, lParam)</code> at the end.
- /// </remarks>
- protected virtual Int32 HookCallBack(Int32 ncode, Int32 wParam, Int32 lParam)
- {
- GC.KeepAlive(this);//FxCop
- /// making sure that other hooks get chance to process event as well.
- return CallNextHookEx(hhook , ncode, wParam, lParam);
- }
-
- /// <summary>
- /// Hooks <code>HookCallBack</code> method to process event of type specified by <code>idHook</code>;
- /// </summary>
- /// <param name="idHook">See winuser.h for possible values(WH_something)</param>
- protected void HookMe(Int32 idHook)
- {
- GC.KeepAlive(this);
- hookDelegate = new WindowsHookCallBack(hookCallBack);
-
- hhook = SetWindowsHookEx(
- idHook,
- hookDelegate,
- IntPtr.Zero,
- Win32.GetCurrentThreadId() );
- }
-
- /// <summary>
- /// Stops processing events.
- /// </summary>
- protected void UnHookMe()
- {
- GC.KeepAlive(this);
- if( hhook != IntPtr.Zero )
- {
- UnhookWindowsHookEx( hhook );
- hhook = IntPtr.Zero;
- }
-
- if( hookDelegate != null )
- hookDelegate = null;
- }
-
- /// <summary>
- /// Stops processing events, disposes of resources.
- /// </summary>
- public virtual void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- UnHookMe();
- }
-
- ~WindowsHook()
- {
- Dispose(false);
- }
-
- /// <summary>
- /// WindowsHook callback prototype.
- /// </summary>
- delegate Int32 WindowsHookCallBack(Int32 ncode, Int32 wParam, Int32 lParam);
-
- /// <summary>
- /// Generic implementation of WindowsHook.
- /// </summary>
- /// <remarks>
- /// Checks ncode to be greater or equal to HC_ACTION before calling virtual HookCallBack.
- /// </remarks>
- Int32 hookCallBack(Int32 ncode, Int32 wParam, Int32 lParam)
- {
- GC.KeepAlive(this);
- return ncode >= 0 ? //HC_ACTION, etc
- HookCallBack( ncode, wParam, lParam ) :
- CallNextHookEx(hhook , ncode, wParam, lParam);
- }
-
- [DllImport("user32.dll")]
- static extern IntPtr SetWindowsHookEx( Int32 idHook, WindowsHookCallBack lpfn, IntPtr hmodule, Int32 threadID);
-
- [DllImport("user32.dll")]
- static extern Int32 CallNextHookEx(IntPtr hhok, Int32 ncode, Int32 wParam, Int32 lParam);
-
- [DllImport("user32.dll")]
- static extern bool UnhookWindowsHookEx( IntPtr hhook );
- }
- }