I have a KeyboardHook that is in use in production. Works great. Yesterday I wanted to make a Unit test to test out an idea I had where I make a abstract class that has a virtual method that matches the HOOKPROC delegate. something like this..
public abstract class HookRuleBase : IDisposable
{
private readonly IntPtr hookId;
private static KeyboardProc thisDelegate;
public HookRuleBase()
{
thisDelegate = new KeyboardProc(ProcessKey);
IntPtr user = Kernel32.LoadLibrary("User32.dll");
hookId = User32.SetWindowsHookEx(WH_KEYBOARD_LL, thisDelegate, user, 0);
Console.WriteLine(hookId.ToInt32().ToString("X8"));
}
public void Dispose()
{
var disposed = User32.UnhookWindowsHookEx(hookId);
}
/// <summary>
/// If your rule does not need to handle the key or the key's current state then call this base
/// method.
/// </summary>
public virtual int ProcessKey(int code, System.UIntPtr wParam, ref KeyboardHookStruct lParam)
{
return User32.CallNextHookEx(hookId, code, wParam, ref lParam);
}
private const int WH_KEYBOARD_LL = 13;
}
What I plan on doing with that is replacing some of the static methods I have in my class called KeyboardHook. I think it follows the Strategy pattern... I think... Anywho. So I made a NUnit project. Made a very simple class that extends my HookRuleBase
private class HookRuleTest : HookRuleBase
{
public override int ProcessKey(int code, UIntPtr wParam, ref KeyboardHookStruct lParam)
{
Console.WriteLine("ProcessKey:code:{0}, wParam:{1:X8}, {2}", code, wParam.ToUInt32(), lParam.ToString());
return base.ProcessKey(code, wParam, ref lParam);
}
}
I tried a few things in my tests. First I did a Console beep (a audio que for myself.) then did a Thread sleep for 3 seconds... nothing shows up. so than i stole some code of mine to test a virtual keyboard class of mine. its nothing more than a Winforms form that is started in another thread. so i put in the on load event creating said hook rule, and on closing i disposed of it. Ran my test typed hello world and nothing in the console :/ so as a last resort I created a new winforms project. copied my code for the on load and on closing events, changed project to console project, then ran my code. Started typing and sure enough I started getting output to my console window. So this is driving me crazy. I have no clue why it is doing that. The code works, but just not in Nunit. Can someone guide me in the right direction as to why it isn't working. It acts like the hook is receiving any events, yet the SetWindowsHookEx returns a valid pointer everytime. So I dunno. Please help.