1

I am attempting to code a simple project that captures keystrokes to match in a list of "Hot Keys" to ultimately "execute" tasks such as open programs and etc....

An exception gets thrown while I attempt to execute gHook.hook();

Exception:

A first chance exception of type 'System.NullReferenceException' occurred in l0g3.exe

Additional information: Object reference not set to an instance of an object. If there is a handler for this exception, the program may be safely continued.

GlobalKeyBoardHook.cs:

#region License_Do_Not_Remove
/* 
*  Made by TheDarkJoker94. 
*  Check http://thedarkjoker94.cer33.com/ for more C# Tutorials 
*  and also SUBSCRIBE to my Youtube Channel http://www.youtube.com/user/TheDarkJoker094  
*  GlobalKeyboardHook is licensed under a Creative Commons Attribution 3.0 Unported License.(http://creativecommons.org/licenses/by/3.0/)
*  This means you can use this Code for whatever you want as long as you credit me! That means...
*  DO NOT REMOVE THE LINES ABOVE !!! 
*/
#endregion
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KeyHook
{
    public class GlobalKHook
    {
        [DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam);
        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID);
        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam);

        public struct keyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        const int WH_KEYBOARD_LL = 13;
        const int WM_KEYDOWN = 0x0100;
        const int WM_KEYUP = 0x0101;
        const int WM_SYSKEYDOWN = 0x0104;
        const int WM_SYSKEYUP = 0x0105;

        LLKeyboardHook llkh;
        public List<Keys> HookedKeys = new List<Keys>();

        IntPtr Hook = IntPtr.Zero;

        public event KeyEventHandler KeyDown;
        public event KeyEventHandler KeyUp;

        // This is the Constructor. This is the code that runs every time you create a new GlobalKeyboardHook object
        public GlobalKHook()
        {
            llkh = new LLKeyboardHook(HookProc);
            // This starts the hook. You can leave this as comment and you have to start it manually (the thing I do in the tutorial, with the button)
            // Or delete the comment mark and your hook will start automatically when your program starts (because a new GlobalKeyboardHook object is created)
            // That's why there are duplicates, because you start it twice! I'm sorry, I haven't noticed this...
            // hook(); <-- Choose!
        }
        ~GlobalKHook()
        { unhook(); }

        public void hook()
        {
            IntPtr hInstance = LoadLibrary("User32");
            Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0);
        }

        public void unhook()
        {
            UnhookWindowsHookEx(Hook);
        }

        public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam)
        {
            if (Code >= 0)
            {
                Keys key = (Keys)lParam.vkCode;
                if (HookedKeys.Contains(key))
                {
                    KeyEventArgs kArg = new KeyEventArgs(key);
                    if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                        KeyDown(this, kArg);
                    else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                        KeyUp(this, kArg);
                    if (kArg.Handled)
                        return 1;
                }
            }
            return CallNextHookEx(Hook, Code, wParam, ref lParam);
        }

    }
}

mainForm.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using KeyHook;

namespace l0g3
{
    public partial class mainForm : Form
    {
        GlobalKHook gHook;

        public mainForm()
        {
            InitializeComponent();
        }

        private void mainForm_Load(object sender, EventArgs e)
        {
            gHook = new GlobalKHook(); // Create a new GlobalKeyboardHook
            // Declare a KeyDown Event
            gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);
            // Add the keys you want to hook to the HookedKeys list
            foreach (Keys key in Enum.GetValues(typeof(Keys)))
                gHook.HookedKeys.Add(key);
        }

        private void mainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            gHook.unhook();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        // Handle the KeyDown Event
        public void gHook_KeyDown(object sender, KeyEventArgs e)
        {
            textBox1.Text += ((char)e.KeyValue).ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            gHook.hook();
            //gHook.hook();
        }

        private void mainForm_Load_1(object sender, EventArgs e)
        {

        }
    }
}
dottedquad
  • 1,371
  • 6
  • 24
  • 55
  • 1
    At the line in question, has `gHook` been initialized? If you set a breakpoint on that line, when your debugger stops, check to make sure `gHook` is not null. – Reticulated Spline Feb 17 '15 at 05:19
  • @ReticulatedSpline I wrote: `GlobalKHook gHook;` before public `mainForm()` and wrote `gHook = new GlobalKHook();` inside `mainForm_Load()` I am not sure where else to instantiate the object? – dottedquad Feb 17 '15 at 05:27
  • 1
    True, but you should still perform a sanity check. I notice you have two form load event handlers, one where you instantiate the object (`mainForm_Load`), and one which is blank (`mainForm_Load_1`). This may be blatantly obvious, but I have to ask-- are you sure the correct function is being called? – Reticulated Spline Feb 17 '15 at 05:30
  • @ReticulatedSpline Ahh, I haven't noticed my double form load. I removed the `mainForm_Load_1`; placed a breaking point and my code breaks on `gHook.hook();` inside of `private void button1_Click(object sender, EventArgs e)` I commented out `GlobalKHook gHook;` located before `public mainForm()` and also commented out: `gHook = new GlobalKHook();` inside `private void mainForm_Load(object sender, EventArgs e)` and wrote: `GlobalKHook gHook = new GlobalKHook();` before `public mainForm()` and the NullReferenceException exception went away. – dottedquad Feb 17 '15 at 05:45
  • However, when I press button1 the keyboard hook should hook the keyboard and output the key presses to textbox1. I am not receiving any key presses to textbox1. – dottedquad Feb 17 '15 at 05:49
  • 1
    Then please start a new thread, as the problem described in this one has been resolved (null reference exception) and each thread should be (ideally) a single problem. – Reticulated Spline Feb 17 '15 at 05:51
  • @ReticulatedSpline. Alright will do. – dottedquad Feb 17 '15 at 05:54
  • AppDomain.CurrentDomain.FirstChanceException += CurrentDomainOnFirstChanceException; private void CurrentDomainOnFirstChanceException(object sender, FirstChanceExceptionEventArgs firstChanceExceptionEventArgs) { if (firstChanceExceptionEventArgs.Exception is NullReferenceException) { // do your job } } – Ognyan Dimitrov May 27 '15 at 08:47

0 Answers0