Code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Cephalopod.Cephalopod_Management
{
class CephKeyHook
{
public delegate int keyboardHookProc(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;
}
Logger _logger = new Logger();
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int WM_SYSKEYDOWN = 0x104;
const int WM_SYSKEYUP = 0x105;
public static Hashtable Modifiers = new Hashtable();
public static List<CephKeyHook> HookedKeys = new List<CephKeyHook>();
int index;
int ModifierPressed;
int ModifierToSend;
int KeyPressed;
int KeySent;
string SpecialCommands;
string SendTo;
int RoundRobin = 0;
IntPtr hhook = IntPtr.Zero;
static bool KeyHookEnabled = false;
public void AddKey(int index, int mod_p, int key_p, int mod_s, int key_s, string Sendto, string Special)
{
CephKeyHook KeyToHook = new CephKeyHook();
KeyToHook.index = index;
KeyToHook.ModifierPressed = mod_p;
KeyToHook.ModifierToSend = mod_s;
KeyToHook.KeyPressed = key_p;
KeyToHook.KeySent = key_s;
KeyToHook.SpecialCommands = Special;
KeyToHook.SendTo = Sendto;
if (mod_p > 0)
{
if (Modifiers.Contains(mod_p) == true)
{
HookedKeys.Add(KeyToHook);
}
}
HookedKeys.Add(KeyToHook);
}
public void AddModifier(int key)
{
Modifiers.Add(key, "false");
//hook();
}
internal void hook()
{
IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
GC.KeepAlive(hhook);
}
private void unhook()
{
UnhookWindowsHookEx(hhook);
}
private int hookProc(int code, int wParam, ref keyboardHookStruct lParam)
{
if (code >= 0)
{
Keys key = (Keys)lParam.vkCode;
KeyEventArgs kea = new KeyEventArgs(key);
int keycode = lParam.vkCode;
if (Modifiers.Contains(lParam.vkCode) == true)
{
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
Modifiers[lParam.vkCode] = "true";
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
Modifiers[lParam.vkCode] = "false";
}
var MatchingKeys = from k in HookedKeys where k.KeyPressed == keycode select new { k.index, k.ModifierPressed, k.KeyPressed, k.SendTo };
foreach (var _keys in MatchingKeys)
{
if (_keys.SendTo == "KEYHOOKS" && wParam == WM_KEYDOWN)
{
if (KeyHookEnabled)
{
KeyHookEnabled = false;
}
else
{
KeyHookEnabled = true;
}
}
if (KeyHookEnabled)
{
if (wParam == WM_KEYDOWN)
{
if (_keys.ModifierPressed > 1)
{
if (Modifiers[_keys.ModifierPressed].ToString() == "true")
{
ProcessKeyHooked(_keys.index, wParam);
}
}
else
{
ProcessKeyHooked(_keys.index, wParam);
}
}
else if (wParam == WM_KEYUP)
{
ProcessKeyHooked(_keys.index, wParam);
}
}
}
}
return CallNextHookEx(hhook, code, wParam, ref lParam);
}
private void ProcessKeyHooked(int index, int wParam)
{
int WM_CODE = Win32.WM_KEYDOWN;
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
WM_CODE = Win32.WM_KEYDOWN;
_logger.LogMessage(index.ToString() + " : KEYDOWN");
}
else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
{
WM_CODE = Win32.WM_KEYUP;
_logger.LogMessage(index.ToString() + " : KEYUP");
}
if (HookedKeys[index].SpecialCommands == null)
{
switch (HookedKeys[index].SendTo)
{
case "ALL":
for (int i = 0; i < CephWindowManipulation.WoWInstances.Count(); i++)
{
if (CephWindowManipulation.WoWInstances[i].Title == "World of Warcraft")
{
if (HookedKeys[index].ModifierToSend != 0)
{
Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].ModifierToSend, 0);
}
Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].KeySent, 0);
}
}
break;
case "SLAVES":
for (int i = 0; i < CephWindowManipulation.WoWInstances.Count(); i++)
{
if (CephWindowManipulation.WoWInstances[i].Title == "World of Warcraft" && int.Parse(CephWindowManipulation.WoWInstances[i].Handle.ToString()) != CephWindowManipulation.position[0])
{
if (HookedKeys[index].ModifierToSend != 0)
{
Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].ModifierToSend, 0);
}
Win32.PostMessage(CephWindowManipulation.WoWInstances[i].Handle, WM_CODE, HookedKeys[index].KeySent, 0);
}
}
break;
case "KEYHOOKS":
break;
}
}
}
private void RoundRobinProcessing(int index)
{
string WhoTo;
int CountTo;
}
#region DLL imports
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
#endregion
}
}
It's messy, I know, but I am learning keyboard hooks at the same time as doing this and I'm not cleaning the code upm till it actually works.