您的位置:首页 > 其它

全局钩子实现键盘按键替换

2012-04-24 12:30 435 查看
本本的显卡刚修好,A键又坏了,自己就用C# 弄了一个按键替换的小工具,用Win键替换A。

功能主要包括常规按键替换,以及锁定输入功能(家中有小宝宝的话很好用,解除锁定按C+A+D)



用到的结构有:

[StructLayout(LayoutKind.Sequential)]
public struct KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}

public enum HookTypes
{
None = -100,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_SHELL = 10,
WH_KEYBOARD_LL = 13,    //low level
WH_MOUSE_LL = 14        //low level
};


Hook相关Code有:

public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

public abstract class SystemHook
{
private HookTypes hookType;
public HookProc HookProc;
public int hHook;

public SystemHook(HookTypes type)
{
hookType = type;
}

public bool InstallHook()
{
if (hHook == 0)
{
HookProc = new HookProc(HookCallback);
hHook = SetWindowsHookEx((int)HookType, HookProc, Instance, 0);
}
return hHook == 0 ? false : true;
}

public bool UninstallHook()
{
bool flag = true;
if (hHook != 0)
{
flag = UnhookWindowsHookEx(hHook);
hHook = 0;
}
return flag;
}

public abstract int HookCallback(int nCode, IntPtr wParam, IntPtr lParam);

public IntPtr Instance
{
get { return GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); }
}

public HookTypes HookType
{
get { return hookType; }
}

#region Win_32_Utility_Methods

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern int SetWindowsHookEx(
int idHook,
HookProc lpfn,
IntPtr hInstance,
int threadId
);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern bool UnhookWindowsHookEx(int idHook);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern int CallNextHookEx(
int idHook,
int nCode,
IntPtr wParam,
IntPtr lParam
);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern void keybd_event(
byte bVk,
byte bScan,
Int32 dwFlags,
Int32 dwExtraInfo);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern bool BlockInput(bool isBlock);

#endregion Win_32_Utility_Methods
}


public class KeyboardHook : SystemHook
{
private static readonly int WM_KEYDOWN = 0x100;
private static readonly int WM_SYSKEYDOWN = 0x104;

private static readonly int KEYEVENTF_KEYDOWN = 0x00;
private static readonly int KEYEVENTF_KEYUP = 0x2;

public KeyboardHook()
: base(HookTypes.WH_KEYBOARD_LL)
{
CustomerKeyPairsDic = new Dictionary<int, CustomizeKeyPairs>();
}

public override int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

if ((wParam.ToInt32() != WM_KEYDOWN) && (wParam.ToInt32() != WM_SYSKEYDOWN))
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

KeyboardHookStruct input = (KeyboardHookStruct)
Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

if (CustomerKeyPairsDic.ContainsKey(input.vkCode))
{
CustomizeKeyPairs cusKey = CustomerKeyPairsDic[input.vkCode];
if ((input.flags & 16) != 16)//过滤虚拟键盘
{
if (wParam.ToInt32() == WM_SYSKEYDOWN)
{
keybd_event((byte)cusKey.OldKey, 0, KEYEVENTF_KEYUP, 0);
}
int KeyStatue = (input.flags & 128) / 64;
keybd_event((byte)cusKey.NewKey, 0, KeyStatue, 0);
return 1;
}
}

return CallNextHookEx(hHook, nCode, wParam, lParam);
}

public Dictionary<int, CustomizeKeyPairs> CustomerKeyPairsDic;

public bool LockKeyboardAndMouse()
{
return BlockInput(true);
}

public bool UnlockKeyboardAndMouse()
{
return BlockInput(false);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: