1.引入
由于需要使用动态链接库及Process进程类,所以需要在项目中引入命名空间
using System.Diagnostics;
using System.Runtime.InteropServices; //调用操作系统动态链接库
2.键盘屏蔽
实现屏蔽键盘的功能,并且把按的任意的一个键的值显示在标签中。
如 按下了 space windows 等,不会产生键盘该有的功能,因为做了屏蔽处理,而是显示键值在标签上。
代码如下:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices; //调用操作系统动态链接库
using System.Windows.Forms;
namespace WindowsFormsApp14 {
public partial class Form1 : Form {
private KeyboardHookLib _keyboardHook = null;
public Form1() {
InitializeComponent();
}
//开启改键
private void button1_Click(object sender, EventArgs e) {
//把客户端委托函数传给键盘钩子类KeyBoardHookLib
_keyboardHook.InstallHook(this.Form1_KeyPress);
}
//退出改键
private void button2_Click(object sender, EventArgs e) {
if (_keyboardHook != null) {
_keyboardHook.UninstallHook();
}
}
private void Form1_Load(object sender, EventArgs e) {
}
//窗口退出事件
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
if (_keyboardHook != null) {
//卸载钩子
_keyboardHook.UninstallHook();
}
}
//右键菜单-与此例无关
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e) {
if (WindowState == FormWindowState.Minimized) {
//还原窗体显示
WindowState = FormWindowState.Normal;
//激活窗体并给予它焦点
this.Activate();
}
}
//客户端传递的委托函数
private void Form1_KeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle) {
handle = false; //预设不拦截
Keys key = (Keys)hookStruct.vkVode;
String keyname = key.ToString();
this.showresult.Text = keyname;
return;
}
}
/
class KeyboardHookLib {
//钩子类型:键盘
private const int WH_KEYBOARD_LL = 13; //全局钩子键盘为13,线程钩子键盘为2
private const int WM_KEYDOWN = 0x0100; //键按下
private const int WM_KEYUP = 0x0101; //键弹起
//全局系统按键
private const int WM_SYSKEYDOWN = 0x104;
//键盘处理委托事件,捕获键盘输入,调用委托方法
private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);
private static HookHandle _keyBoardHookProcedure;
//客户端键盘处理委托事件
public delegate void ProcessKeyHandle(HookStruct param, out bool handle);
private static ProcessKeyHandle _clientMethod = null;
//接收SetWindowsHookEx返回值 判断是否安装钩子
private static int _hHookValue = 0;
//Hook结构 存储按键信息的结构体
[StructLayout(LayoutKind.Sequential)]
public class HookStruct {
public int vkVode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
//安装钩子
//idHook为13代表键盘钩子为14代表鼠标钩子,lpfn为函数指针,指向需要执行的函数,hIntance为指向进程快的指针,threadId默认为0就可以了
[DllImport("user32.dll")]
private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);
//取消钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//调用下一个钩子
[DllImport("user32.dll")]
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
//获取当前线程id
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
//通过线程Id,获取进程快
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(String name);
private IntPtr _hookWindowPtr = IntPtr.Zero;
public KeyboardHookLib() { }
#region
//加上客户端方法的委托的安装钩子
public void InstallHook(ProcessKeyHandle clientMethod) {
//客户端委托事件
_clientMethod = clientMethod;
//安装键盘钩子
if (_hHookValue == 0) {
_keyBoardHookProcedure = new HookHandle(GetHookProc);
_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
_hHookValue = SetWindowsHookEx(
WH_KEYBOARD_LL,
_keyBoardHookProcedure,
_hookWindowPtr,
0
);
if (_hHookValue == 0) {
//设置钩子失败
UninstallHook();
}
}
}
#endregion
//取消钩子事件
public void UninstallHook() {
if (_hHookValue != 0) {
bool ret = UnhookWindowsHookEx(_hHookValue);
if (ret) {
_hHookValue = 0;
}
}
}
private static int GetHookProc(int nCode, int wParam, IntPtr lParam) {
//当nCode大于0,并且时按下事件时为1
if (nCode >= 0 && (wParam == WM_KEYDOWN) || (wParam == WM_KEYDOWN)) {
//将按键信息转换为结构体
HookStruct hookStruc = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));
//是否拦截按键的标识符,默认不拦截
bool handle = false;
//客户端调用
_clientMethod(hookStruc,out handle); //如果传递了客户端委托,就调用
handle = true; //如果这个handle为false,则代表不拦截此次按键,按了 windows等键会执行客户端键值显示,但是同时也会产生该键本有的功能。
if (handle){ return 1; }
}
return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
}
}
}
3.全局改键
这个案例是把键盘的UP键改成了 回车键加greendisgood 1000多个字符键再加一个回车键,玩过魔兽的都知道这是魔兽秘籍。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices; //调用操作系统动态链接库
using System.Windows.Forms;
namespace WindowsFormsApp14 {
public partial class Form1 : Form {
private KeyboardHookLib _keyboardHook = null;
public Form1() {
InitializeComponent();
}
//开启改键
private void button1_Click(object sender, EventArgs e) {
_keyboardHook = new KeyboardHookLib();
_keyboardHook.InstallHook();
}
//退出改键
private void button2_Click(object sender, EventArgs e) {
if (_keyboardHook != null) {
_keyboardHook.UninstallHook();
}
}
private void Form1_Load(object sender, EventArgs e) {
}
//窗口退出事件
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
if (_keyboardHook != null) {
//卸载钩子
_keyboardHook.UninstallHook();
}
}
//右键菜单
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e) {
if (WindowState == FormWindowState.Minimized) {
//还原窗体显示
WindowState = FormWindowState.Normal;
//激活窗体并给予它焦点
this.Activate();
}
}
}
class KeyboardHookLib {
//钩子类型:键盘
private const int WH_KEYBOARD_LL = 13; //全局钩子键盘为13,线程钩子键盘为2
private const int WM_KEYDOWN = 0x0100; //键按下
private const int WM_KEYUP = 0x0101; //键弹起
//全局系统按键
private const int WM_SYSKEYDOWN = 0x104;
//键盘处理委托事件,捕获键盘输入,调用委托方法
private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);
private static HookHandle _keyBoardHookProcedure;
//接收SetWindowsHookEx返回值
private static int _hHookValue = 0;
//Hook结构 存储按键信息的结构体
[StructLayout(LayoutKind.Sequential)]
public class HookStruct {
public int vkVode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
//安装钩子
//idHook为13代表键盘钩子为14代表鼠标钩子,lpfn为函数指针,指向需要执行的函数,hIntance为指向进程快的指针,threadId默认为0就可以了
[DllImport("user32.dll")]
private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);
//取消钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//调用下一个钩子
[DllImport("user32.dll")]
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
//获取当前线程id
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();
//通过线程Id,获取进程快
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(String name);
private IntPtr _hookWindowPtr = IntPtr.Zero;
public KeyboardHookLib() { }
public void InstallHook() {
//安装键盘勾子
if (_hHookValue == 0) {
_keyBoardHookProcedure = new HookHandle(GetHookProc);
//得到进程块
_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
_hHookValue = SetWindowsHookEx(
WH_KEYBOARD_LL,
_keyBoardHookProcedure,
_hookWindowPtr,
0
);
//如果设置钩子失败
if (_hHookValue == 0) {
UninstallHook();
}
}
}
//取消钩子事件
public void UninstallHook() {
if (_hHookValue != 0) {
bool ret = UnhookWindowsHookEx(_hHookValue);
if (ret) {
_hHookValue = 0;
}
}
}
private static int GetHookProc(int nCode, int wParam, IntPtr lParam) {
//当nCode大于0,并且时按下事件时为1
if (nCode >= 0 && (wParam == WM_KEYDOWN) || (wParam == WM_KEYDOWN)) {
//将按键信息转换为结构体
HookStruct hookStruc = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));
//是否拦截按键的标识符,默认不拦截
bool handle = false;
switch ((Keys)hookStruc.vkVode) {
//将拦截标识符置为拦截,如果按了上键相当于向当前窗口发送一个回车
//再发送greendisgood 10000,再发送一个回车
case Keys.Up:
handle = true;
SendKeys.Send("{ENTER}");
SendKeys.Send("greendisgood 1000");
SendKeys.Send("{ENTER}");
break;
}
//1表示拦截键盘
if (handle){ return 1; }
}
return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
}
}
}
先运行程序,然后点击开启改键,然后缩小程序,然后随便打开一个可以输入文字的东西如文档等,我这里直接拿一个记事本做测试,文档一开始为空,然后按一下UP上键,内容如下:
有输入法的话,先把输入法关了,不然会乱码!