[Question/Request] Listening For Custom Events menu

Shout-Out

User Tag List

Results 1 to 3 of 3
  1. #1
    nilum's Avatar Member
    Reputation
    9
    Join Date
    Jun 2009
    Posts
    47
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Release] [c#] Event-Driven, Process-Specific, Low-Level Keyboard Hook

    Well got everything working on my own (somehow).

    Thought I would share what I had.

    To do the testing I used "notepad++", but you can change that to whatever .exe you want to hook. Does work with "WoW".
    Note: 64-bit applications (including notepad on 64-bit versions of Windows) will not work.

    Features:
    Low Level Keyboard Hook
    Process Specific (Only hooks keys when designated process window is active)
    Event Driven
    Prevents Auto-Repeat (this can be added easily for rapid fire)

    Code:
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Diagnostics;
    
    
    namespace Hook
    {
        /// <summary>
        /// Hooks keyboard input of a specific application
        /// <remarks>
        /// George Mamaladze: http://www.codeproject.com/KB/cs/globalhook.aspx 
        /// Stephen Toub: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx
        /// Eitan Pogrebizsky: http://www.koders.com/csharp/fid6AF179F76C05AF581905FF86477E98F2D4D86622.aspx
        /// Michael Schierl: http://mwinapi.sourceforge.net/
        /// Richard Carr: http://www.blackwasp.co.uk/GetActiveProcess.aspx
        /// Modified by nilum
        /// </remarks>
        /// </summary>
        /// 
        public class KeyboardHook : IDisposable
        {
            public event KeyEventHandler KeyDown;
            public event KeyPressEventHandler KeyPress;
            public event KeyEventHandler KeyUp;
    
            public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    
            public int hKeyboardHook = 0; //Declare keyboard hook handle as int.
    
            private const int WM_KEYDOWN = 0x100;
            private const int WM_KEYUP = 0x101;
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;
            private const uint MASK_KEYDOWN = 0x40000000; // for bit 30
            private const uint MASK_KEYUP = 0x80000000; // for bit 31
            private const int HC_ACTION = 0;  //#define HC_ACTION           0
            private const int HC_NOREMOVE = 3; //#define HC_NOREMOVE         3
            private const int WH_KEYBOARD_LL = 13;
    
            private readonly HookProc keyboardHook; //Declare KeyboardHookProcedure as HookProc type.
    
            public static Process[] processes = Process.GetProcessesByName("notepad++");
    
            public KeyboardHook()
            {
                keyboardHook = new HookProc(keyboardHookProc);
                Start();
            }
    
            ~KeyboardHook()
            {
                Stop();
            }
    
            /// <summary>
            /// Unhooks the hook if necessary.
            /// </summary>
            public void Dispose()
            {
                Stop();
            }
    
            public void Start()
            {
                // install Keyboard hook
                if (hKeyboardHook == 0)
                {
                    IntPtr keyboardHookPointer = Marshal.GetFunctionPointerForDelegate(keyboardHook);
    
                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
                            keyboardHookPointer,
                            GetModuleHandle((processes[0].MainModule).ModuleName),
                            0);
    
                    //If SetWindowsHookEx fails.
                    if (hKeyboardHook == 0)
                    {
                        Win32Exception ex = new Win32Exception(Marshal.GetLastWin32Error());
                        //Settings.Instance.Logger.Log(LogLevelType.ErrorsOnly, ex, "Installing keyboard hook failed.");
                        Stop();
    
                        throw ex;
    
                    }
                }
            }
    
            public void Stop()
            {
                bool retKeyboard = true;
    
                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
    
                //If UnhookWindowsHookEx fails.
                if (!(retKeyboard))
                {
                    //Settings.Instance.Logger.Log(LogLevelType.ErrorsOnly, "UnhookWindowsHookEx failed.");
                    throw new Exception("UnhookWindowsHookEx failed.");
                }
            }
    
            //Declare wrapper managed KeyboardHookStruct class.
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode; //Specifies a virtual-key code. The code must be a value in the range 1 to 254.
                public int scanCode; // Specifies a hardware scan code for the key.
                public int flags; // Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
                public int time; // Specifies the time stamp for this message.
                public int dwExtraInfo; // Specifies extra information associated with the message.
            }
    
    
    
            private int keyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && 
                    (nCode != HC_NOREMOVE) && 
                    (KeyDown != null || KeyUp != null || KeyPress != null) &&
                    (GetActiveProcess().Id == processes[0].Id)) //Makes sure the Actice Process is the process we want to receive input from
                {  
                        KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(
                            lParam, typeof(KeyboardHookStruct));
    
                        Keys keyData = (Keys)keyboardHookStruct.vkCode;
    
                        /*
                        if (Keys.Control != keyData && Keys.Alt != keyData && Keys.Shift != keyData) {
                            // Add in modifier key.
                            keyData |= Control.ModifierKeys;
                        }
                        */
    
                        KeyEventArgs e = new KeyEventArgs(keyData);
    
                        // Raise KeyDown.
                        if (KeyDown != null && (wParam.ToInt32() == WM_KEYDOWN || wParam.ToInt32() == WM_SYSKEYDOWN))
                        {
                            KeyDown(this, e);
                        }
    
                        // Raise KeyUp.
                        if (KeyUp != null && (wParam.ToInt32() == WM_KEYUP || wParam.ToInt32() == WM_SYSKEYUP))
                        {
                            KeyUp(this, e);
                        }
                }
    
                return CallNextHookEx(hKeyboardHook, nCode, wParam, (IntPtr)lParam);
            }
    
            private static Process GetActiveProcess()
            {
                IntPtr hwnd = GetForegroundWindow();
                return hwnd != null ? GetProcessByHandle(hwnd) : null;
            }
    
            private static Process GetProcessByHandle(IntPtr hwnd)
            {
                try
                {
                    uint processID;
                    GetWindowThreadProcessId(hwnd, out processID);
                    return Process.GetProcessById((int)processID);
                }
                catch { return null; }
            }
    
            //Import for SetWindowsHookEx function.
            //Use this function to install a hook.
            [DllImport("user32.dll", SetLastError = true)]
            public static extern int SetWindowsHookEx(int idHook, IntPtr callback, IntPtr hInstance, uint threadId);
    
            //Import for UnhookWindowsHookEx.
            //Call this function to uninstall the hook.
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
    
            //Import for CallNextHookEx.
            //Use this function to pass the hook information to next hook procedure in chain.
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);
    
            //Needed to get the Active Window (Window ready to receive user input)
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr GetForegroundWindow();
    
            //Needed to get the Process ID of the Active Window
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        }
    }
    Implementation:
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Hook
    {
        public partial class MainForm : Form
        {
            KeyboardHook keyHook = new KeyboardHook();
    
            public MainForm()
            {
                InitializeComponent();
    
                keyHook.KeyDown += new KeyEventHandler(keyHook_KeyDown);
                keyHook.KeyPress += new KeyPressEventHandler(keyHook_KeyPress);
                keyHook.KeyUp += new KeyEventHandler(keyHook_KeyUp);
            }
    
            private void keyHook_KeyDown(object sender, KeyEventArgs e)
            {
                label1.Text = e.KeyData.ToString();
            }
    
            private void keyHook_KeyUp(object sender, KeyEventArgs e)
            {
                label2.Text = e.KeyData.ToString();
            }
    
            private void checkBox1_CheckedChanged(object sender, EventArgs e)
            {
                if (keyHook.hKeyboardHook != 0)
                {
                    keyHook.Stop();
                    checkBox1.Text = "Hook";
                }
                else if (keyHook.hKeyboardHook == 0)
                {
                    keyHook.Start();
                    checkBox1.Text = "Unhook";
                }
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (keyHook.hKeyboardHook != 0)
                {
                    keyHook.Stop();
                }
            }
    
        }
    }
    I plan on adding mouse support eventually.

    Hope this is helpful to someone.
    Last edited by nilum; 10-17-2011 at 01:43 PM.

    [Question/Request] Listening For Custom Events
  2. #2
    nilum's Avatar Member
    Reputation
    9
    Join Date
    Jun 2009
    Posts
    47
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    -removed evidence of my own stupidity-
    Last edited by nilum; 10-17-2011 at 01:33 PM.

  3. #3
    nilum's Avatar Member
    Reputation
    9
    Join Date
    Jun 2009
    Posts
    47
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If a mod would be so kind as to change the thread title to the title of the first post, I would really appreciate it.
    Last edited by nilum; 10-17-2011 at 01:42 PM.

Similar Threads

  1. [Question/request]Sandbox for 4.0.3.13329
    By VX2 in forum WoW EMU Questions & Requests
    Replies: 0
    Last Post: 01-29-2011, 04:03 PM
  2. [Question/Request] MEFix for 2.4 server
    By Typhlosion in forum WoW ME Questions and Requests
    Replies: 1
    Last Post: 04-28-2009, 12:28 PM
  3. [Question/Request] Pistols for hunters and others
    By Starbrezze in forum WoW ME Questions and Requests
    Replies: 4
    Last Post: 02-26-2008, 03:40 AM
All times are GMT -5. The time now is 03:21 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search