新增类KeybordHookProc

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms; namespace HookDemo
{
/// <summary>
/// 这个类可以让你得到一个在运行中程序的所有键盘事件
/// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息
/// </summary>
public class KeyBordHook
{ private const byte LLKHF_ALTDOWN = 0x20;
private const byte VK_CAPITAL = 0x14;
private const byte VK_ESCAPE = 0x1B;
private const byte VK_F4 = 0x73;
private const byte VK_LCONTROL = 0xA2;
private const byte VK_NUMLOCK = 0x90;
private const byte VK_RCONTROL = 0xA3;
private const byte VK_SHIFT = 0x10;
private const byte VK_TAB = 0x09;
public const int WH_KEYBOARD = ;
private const int WH_MOUSE = ;
private const int WH_MOUSE_LL = ;
private const int WM_KEYDOWN = 0x100;
private const int WM_KEYUP = 0x101;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_LBUTTONUP = 0x202;
private const int WM_MBUTTONDBLCLK = 0x209;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_MBUTTONUP = 0x208;
private const int WM_MOUSEMOVE = 0x200;
private const int WM_MOUSEWHEEL = 0x020A;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_RBUTTONUP = 0x205;
private const int WM_SYSKEYDOWN = 0x104;
private const int WM_SYSKEYUP = 0x105; //全局的事件
public event KeyEventHandler OnKeyDownEvent;
public event KeyEventHandler OnKeyUpEvent;
public event KeyPressEventHandler OnKeyPressEvent; static int hKeyboardHook = ; //键盘钩子句柄 //鼠标常量
public const int WH_KEYBOARD_LL = ; //keyboard hook constant HookProc KeyboardHookProcedure; //声明键盘钩子事件类型. //声明键盘钩子的封送结构类型
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;
} //装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook); //下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); //取得当前线程编号
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId(); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey); public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); /// <summary>
/// 墨认的构造函数构造当前类的实例并自动的运行起来.
/// </summary>
public KeyBordHook()
{
Start();
} //析构函数.
~KeyBordHook()
{
Stop();
} /// <summary>
/// 启动Hook,并用流屏蔽任务管理器
/// </summary>
public void Start()
{
if (hKeyboardHook == )
{
// 创建HookProc实例
KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookProcedure,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[]),
); // 如果设置钩子失败
if (hKeyboardHook == )
{
Stop();
AppLog.Error("SetWindowsHookEx failed.");
} ////用二进制流的方法打开任务管理器。而且不关闭流.这样任务管理器就打开不了
//MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%\\system32\\taskmgr.exe"),
// FileMode.Open);
//byte[] MyByte = new byte[(int)MyFs.Length];
//MyFs.Write(MyByte, 0, (int)MyFs.Length);
}
} /// <summary>
/// 卸载Hook
/// </summary>
public void Stop()
{
bool retKeyboard = true; if (hKeyboardHook != )
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = ;
} //if (null != MyFs)
//{
// MyFs.Close();
//} if (!(retKeyboard))
{
AppLog.Error("UnhookWindowsHookEx failed.");
}
} #region Nested type: KeyMSG public struct KeyMSG
{
public int dwExtraInfo;
public int flags;
public int scanCode; public int time;
public int vkCode;
} #endregion /// <summary>
/// 键盘钩子
/// </summary>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
KeyboardHookStruct m = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); AppLog.Debug($"nCode is :{nCode} -- vkCode is :{m.vkCode}");
if (m.vkCode == (int)Keys.LWin ||
m.vkCode == (int)Keys.RWin ||
m.vkCode == (int)Keys.LWin && m.vkCode == (int)Keys.D ||
m.vkCode == (int)Keys.RWin && m.vkCode == (int)Keys.D ||
m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control ||
m.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt ||
m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt ||
m.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt ||
m.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift ||
(int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete
)
{
AppLog.Info("hooc is OK");
return ;
} return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
} }
}

添加键盘按键触发事件

/// <summary>
/// 键盘按下触发事件
/// </summary>
void kh_OnKeyDownEvent(object sender, KeyEventArgs e)
{ }

键盘钩子的使用


/// <summary>
/// 键盘钩子
/// </summary>
KeyBordHook _keyBordHook;

//键盘钩子实例化
_keyBordHook = new KeyBordHook();
_keyBordHook.OnKeyDownEvent += kh_OnKeyDownEvent;

winform使用钩子限制windows热键的更多相关文章

  1. Winform开发框架之通用Windows摄像头调用拍照--SNF快速开发平台3.3-Spring.Net.Framework

    今天做了一个windows系统下调用摄像头.进行开启.关闭.拍照.设置等等功能演示. 进行源码贡献,欢迎大家下载使用 一.DEMO效果如下: 二.DEMO演示代码如下: using SNF.Utili ...

  2. 推荐一款轻量小众却高效免费开源windows热键脚本语言Autohotkey

    写在前面的话 Autohotkey是一款轻量小众但高效免费开源的windows热键脚本语言,游戏操纵.鼠标操作.键盘快捷重定义,快捷短语等等,只有你想不到,没有它做不到,神器中的神器呀,相见恨晚. 安 ...

  3. WinForm和WPF中注册热键

    由于.Net没有提供专门的类库处理热键,所以需要直接调用windows API来解决. HotKey为.NET调用Windows API的封装代码,主要是RegisterHotKey和Unregist ...

  4. C# 注册 Windows 热键

    闲扯: 前几日,一个朋友问我如何实现按 F1 键实现粘贴(Ctrl+V)功能,百度了一个方法,发给他,他看不懂(已经是 Boss 的曾经的码农),我就做了个Demo给他参考.今日得空,将 Demo 整 ...

  5. [Winform]通过钩子监控键盘操作和鼠标移动

    摘要 有这样一个需求,在程序隐藏之后,需要监控当前电脑是否有操作,如果1分钟内,无操作,则弹出视频,循环播放. 解决办法 从网上找的一个解决办法,可以通过钩子的方式实现,这里记录一下. /// < ...

  6. Windows热键注册的底层原理

    要像系统注册一个全局热键,需要用到RegisterHotKey,函数用法如下(MSDN):BOOL RegisterHotKey(                                    ...

  7. winform窗体之间通过 windows API SendMessage函数传值

    -----------------------------------------------------------‘接收窗体’代码.cs------------------------------ ...

  8. winform播放视频(windows media player)

    1.找到windows media player 工具箱常规下边右键,右键弹窗点击“选择项”,选择工具箱窗口点击“COM组件”,找到 Windows Media Player 勾选,点击确定 2.使用 ...

  9. winform textbox 不能唤醒windows 平板的软键盘解决办法

    这个问题,研究了将近两个小时,baidu,google,好大一会,windows 平板本身的应用程序,必须浏览器,notepad都是可以自动唤起软键盘的,但是我的winfrom 程序就是不可以,起先怀 ...

随机推荐

  1. 018、MySQL取满足日期在两个日期之间的所有数据

    #查询 SELECT GZJK_CREATEDATE FROM abc_table WHERE ( ( GZJK_CREATEDATE >= UNIX_TIMESTAMP( '2019-08-0 ...

  2. hibernate 中 query.list()的优化

    2018年3月15日  今天做项目遇到一个需求,问题是在调用query.list()的时候,因为数据也多大概700条左右,查询一次需要30s+,这简直是不能忍,于是开始考虑怎么优化. 1.因为是单表查 ...

  3. 西门子 S7-200CN CPU 224CN EEPROM芯片

    拆下来了个 224CN 的EEPROM芯片

  4. postman带上token对接口进行测试

    根据验证码进行登陆,登录之后返回token.然后请求其他接口时在header头中带上token访问其他接口进行测试 账户信息输入验证码 登陆成功,看到返回的token 我们这个项目可以刷新一下toke ...

  5. maven项目打包部署到虚拟机测试和生产环境上及查看日志操作

    调试通过后提交代码到gitlab,打包部署到相应环境(测试或生产环境)步骤一样1.打包在要打包的项目上右键run as maven clean 清除原来的包,然后run as maven instal ...

  6. 浅谈arduino的bootloader

    在arduino的板子上,作为核心的avr单片机往往都会烧录一个bootloader,这个叫做bootloader的东东其实是arduino研发团队针对arduino板子开发的一小段代码,借助于这段代 ...

  7. jQuery获取display为none的隐藏元素的宽度和高度的解决方案

    1.利用给元素添加行内样式:visibility:hidden;display:block 2.让隐藏元素变成有物理尺寸存在,但不可见,获取元素宽高 3.再给它还原成display为none,去除vi ...

  8. 干货分享|留学Essay怎么写?

    留学生活其实就是分割成一个个deadline,留学就是赶完一个又一个deadline.朋友同学的革命情感源自赶一个个deadline时候的不离不弃,相知相守,无数个夜里大家群里打卡,你今天Essay写 ...

  9. Python量化交易的简单介绍

    Python只是一门技术. 一.量化交易的发展 1.国外量化金融领域发展日趋成熟. 2.近几年量化交易在国内掀起热潮. 3.Python作为量化交易的编译语言. 二.什么是量化交易 1.利用计算机强大 ...

  10. 洛谷 P1470 最长前缀 Longest Prefix

    题目传送门 解题思路: 其实思路没那么难,就是题面不好理解,解释一下题面吧. 就是在下面的字符串中找一个子串,使其以某种方式被分解后,每部分都是上面所给集合中的元素. AC代码: #include&l ...