Server/WindowsHook.cs
author sl
Fri, 15 Aug 2014 10:20:01 +0200
changeset 30 c375286d1a1c
parent 0 f6eca6facd07
permissions -rw-r--r--
Still trying to setup WCF for us to work nicely.
Now using multi threading and reliable session.
Implementing thread safe functions where needed.
Enforcing session mode.
Fixing bug in marquee label as we forgot to reset current position when text is changed.
     1 //=============================================================================
     2 // COPYRIGHT: Prosoft-Lanz
     3 //=============================================================================
     4 //
     5 // $Workfile: WindowsHook.cs $
     6 //
     7 // PROJECT : CodeProject Components
     8 // VERSION : 1.00
     9 // CREATION : 19.02.2003
    10 // AUTHOR : JCL
    11 //
    12 // DETAILS : This class implement the Windows hook mechanism.
    13 //           From MSDN, Dino Esposito.
    14 //
    15 //-----------------------------------------------------------------------------
    16 using System;
    17 using System.Runtime.InteropServices;
    18 
    19 namespace CodeProject.Win32API.Hook
    20 {
    21 	///////////////////////////////////////////////////////////////////////
    22 	#region Class HookEventArgs
    23 
    24 	/// Class used for hook event arguments.
    25 	public class HookEventArgs : EventArgs
    26 	{
    27 		/// Event code parameter.
    28 		public int code;
    29 		/// wParam parameter.
    30 		public IntPtr wParam;
    31 		/// lParam parameter.
    32 		public IntPtr lParam;
    33 
    34 		internal HookEventArgs(int code, IntPtr wParam, IntPtr lParam)
    35 		{
    36 			this.code = code;
    37 			this.wParam = wParam;
    38 			this.lParam = lParam;
    39 		}
    40 	}
    41 	
    42 	#endregion
    43 
    44 	///////////////////////////////////////////////////////////////////////
    45 	#region Enum HookType
    46 
    47 	/// Hook Types.
    48 	public enum HookType : int
    49 	{
    50 		/// <value>0</value>
    51 		WH_JOURNALRECORD = 0,
    52 		/// <value>1</value>
    53 		WH_JOURNALPLAYBACK = 1,
    54 		/// <value>2</value>
    55 		WH_KEYBOARD = 2,
    56 		/// <value>3</value>
    57 		WH_GETMESSAGE = 3,
    58 		/// <value>4</value>
    59 		WH_CALLWNDPROC = 4,
    60 		/// <value>5</value>
    61 		WH_CBT = 5,
    62 		/// <value>6</value>
    63 		WH_SYSMSGFILTER = 6,
    64 		/// <value>7</value>
    65 		WH_MOUSE = 7,
    66 		/// <value>8</value>
    67 		WH_HARDWARE = 8,
    68 		/// <value>9</value>
    69 		WH_DEBUG = 9,
    70 		/// <value>10</value>
    71 		WH_SHELL = 10,
    72 		/// <value>11</value>
    73 		WH_FOREGROUNDIDLE = 11,
    74 		/// <value>12</value>
    75 		WH_CALLWNDPROCRET = 12,		
    76 		/// <value>13</value>
    77 		WH_KEYBOARD_LL = 13,
    78 		/// <value>14</value>
    79 		WH_MOUSE_LL = 14
    80 	}
    81 	#endregion
    82 
    83 	///////////////////////////////////////////////////////////////////////
    84 	#region Class WindowsHook
    85 
    86 	/// <summary>
    87 	/// Class to expose the windows hook mechanism.
    88 	/// </summary>
    89 	public class WindowsHook
    90 	{
    91 		/// <summary>
    92 		/// Hook delegate method.
    93 		/// </summary>
    94 		public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    95 
    96 		// internal properties
    97 		internal IntPtr hHook = IntPtr.Zero;
    98 		internal HookProc filterFunc = null;
    99 		internal HookType hookType;
   100 
   101 		/// <summary>
   102 		/// Hook delegate method.
   103 		/// </summary>
   104 		public delegate void HookEventHandler(object sender, HookEventArgs e);
   105 
   106 		/// <summary>
   107 		/// Hook invoke event.
   108 		/// </summary>
   109 		public event HookEventHandler HookInvoke;
   110 
   111 		internal void OnHookInvoke(HookEventArgs e)
   112 		{
   113 			if (HookInvoke != null)
   114 				HookInvoke(this, e);
   115 		}
   116 
   117 		/// <summary>
   118 		/// Construct a HookType hook.
   119 		/// </summary>
   120 		/// <param name="hook">Hook type.</param>
   121 		public WindowsHook(HookType hook)
   122 		{
   123 			hookType = hook;
   124 			filterFunc = new HookProc(this.CoreHookProc);
   125 		}
   126 		/// <summary>
   127 		/// Construct a HookType hook giving a hook filter delegate method.
   128 		/// </summary>
   129 		/// <param name="hook">Hook type</param>
   130 		/// <param name="func">Hook filter event.</param>
   131 		public WindowsHook(HookType hook, HookProc func)
   132 		{
   133 			hookType = hook;
   134 			filterFunc = func; 
   135 		}
   136 
   137 		// default hook filter function
   138 		internal int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
   139 		{
   140 			if (code < 0)
   141 				return CallNextHookEx(hHook, code, wParam, lParam);
   142 
   143 			// let clients determine what to do
   144 			HookEventArgs e = new HookEventArgs(code, wParam, lParam);
   145 			OnHookInvoke(e);
   146 
   147 			// yield to the next hook in the chain
   148 			return CallNextHookEx(hHook, code, wParam, lParam);
   149 		}
   150 
   151 		/// <summary>
   152 		/// Install the hook. 
   153 		/// </summary>
   154 		public void Install()
   155 		{
   156 			hHook = SetWindowsHookEx(hookType, filterFunc, IntPtr.Zero, (int)AppDomain.GetCurrentThreadId());
   157 		}
   158 
   159 		
   160 		/// <summary>
   161 		/// Uninstall the hook.
   162 		/// </summary>
   163  		public void Uninstall()
   164 		{
   165 			if (hHook != IntPtr.Zero)
   166 			{
   167 				UnhookWindowsHookEx(hHook);
   168 				hHook = IntPtr.Zero;
   169 			}
   170 		}
   171 
   172 		#region Win32 Imports
   173 
   174 		[DllImport("user32.dll")]
   175 		internal static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID);
   176 
   177 		[DllImport("user32.dll")]
   178 		internal static extern int UnhookWindowsHookEx(IntPtr hhook); 
   179 
   180 		[DllImport("user32.dll")]
   181 		internal static extern int CallNextHookEx(IntPtr hhook, int code, IntPtr wParam, IntPtr lParam);
   182 
   183 		#endregion
   184 	}
   185 	#endregion
   186 }