c#钩子程序键盘事件监听(拦截系统组合键)WebBrowser浏览器控件
1.什么是钩子程序
hook(钩子)是windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出, 在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递(return)。
运行下面的程序案例需注意,程序会全屏展示,并且拦截所有系统组合键(除ctrl+alt+del),在程序菜单栏可退出。
2.钩子程序的主要代码
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static WindowsFormsApplication1.Win32Api;
namespace WindowsFormsApplication1
{
/**
* c#钩子程序 键盘监控(拦截系统组合键)
* */
public class Win32Api
{
#region 常数和结构
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_SYSKEYDOWN = 0x104;
public const int WM_SYSKEYUP = 0x105;
public const int WH_KEYBOARD_LL = 13;
[StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型
public class KeyboardHookStruct
{
public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;
}
#endregion
#region Api
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
//安装钩子的函数
[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("user32")]
public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion
}
public class KeyboardHook
{
int hHook;
Win32Api.HookProc KeyboardHookDelegate;
public event KeyEventHandler OnKeyDownEvent;
public event KeyEventHandler OnKeyUpEvent;
public event KeyPressEventHandler OnKeyPressEvent;
public KeyboardHook() { }
/**
* 设置钩子
* */
public void SetHook()
{
KeyboardHookDelegate = new Win32Api.HookProc(KeyboardHookProc);
Process cProcess = Process.GetCurrentProcess();
ProcessModule cModule = cProcess.MainModule;
var mh = Win32Api.GetModuleHandle(cModule.ModuleName);
hHook = Win32Api.SetWindowsHookEx(Win32Api.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
}
/**
* 卸载钩子
* */
public void UnHook()
{
Win32Api.UnhookWindowsHookEx(hHook);
}
/**
* 拦截按键
* nCode参数是钩子代码,钩子子程使用这个参数来确定任务,这个参数的值依赖于Hook类型。
* wParam和lParam参数包含了消息信息,我们可以从中提取需要的信息。
* */
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if (nCode >= 0)
{
KeyboardHookStruct kbh = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// 截获左win(开始菜单键)
if (kbh.vkCode == 91)
{
return 1;
}
// 截获右win
if (kbh.vkCode == 92)
{
return 1;
}
//截获Ctrl+Esc
if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
{
return 1;
}
//截获alt+f4
if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
{
return 1;
}
//截获alt+tab
if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
{
return 1;
}
//截获Ctrl+Shift+Esc
if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift)
{
return 1;
}
//截获alt+空格
if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Alt)
{
return 1;
}
//截获F1
if (kbh.vkCode == 241)
{
return 1;
}
//截获Ctrl+Alt+Delete
if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)
{
return 1;
}
}
return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
3.窗体类主要代码:
using System;
using System.Windows.Forms;
/**
* 命名空间,类似于java中的import
* */
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
4.窗体样式主要代码:
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.菜单ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.退出程序ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.考试须知ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.webBrowser1 = new System.Windows.Forms.WebBrowser(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); // // menuStrip1 // this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.菜单ToolStripMenuItem, this.考试须知ToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(893, 25); this.menuStrip1.TabIndex = 0; this.menuStrip1.Text = "menuStrip1"; // // 菜单ToolStripMenuItem // this.菜单ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.退出程序ToolStripMenuItem}); this.菜单ToolStripMenuItem.Name = "菜单ToolStripMenuItem"; this.菜单ToolStripMenuItem.Size = new System.Drawing.Size(44, 21); this.菜单ToolStripMenuItem.Text = "菜单"; // // 退出程序ToolStripMenuItem // this.退出程序ToolStripMenuItem.Name = "退出程序ToolStripMenuItem"; this.退出程序ToolStripMenuItem.Size = new System.Drawing.Size(124, 22); this.退出程序ToolStripMenuItem.Text = "退出程序"; this.退出程序ToolStripMenuItem.Click += new System.EventHandler(this.退出程序ToolStripMenuItem_Click); // // 考试须知ToolStripMenuItem // this.考试须知ToolStripMenuItem.Name = "考试须知ToolStripMenuItem"; this.考试须知ToolStripMenuItem.Size = new System.Drawing.Size(68, 21); this.考试须知ToolStripMenuItem.Text = "考试须知"; this.考试须知ToolStripMenuItem.Click += new System.EventHandler(this.考试须知ToolStripMenuItem_Click); // // webBrowser1 属性设置 // this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; this.webBrowser1.Location = new System.Drawing.Point(0, 25); this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); this.webBrowser1.Name = "webBrowser1"; this.webBrowser1.Size = new System.Drawing.Size(893, 286); this.webBrowser1.TabIndex = 1; /** * 设置 WebBrowser 容器默认请求的ip地址 * */ this.webBrowser1.Navigate("http://www.baidu.com"); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(893, 311); this.Controls.Add(this.webBrowser1); this.Controls.Add(this.menuStrip1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MainMenuStrip = this.menuStrip1; this.Name = "Form1"; this.ShowInTaskbar = false; this.Text = "Form1"; this.TopMost = true; this.WindowState = System.Windows.Forms.FormWindowState.Maximized;//窗体最大化 this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); this.Load += new System.EventHandler(this.Form1_Load); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion /** * 定义菜单 * */ private MenuStrip menuStrip1; /** * 定义菜单按钮 * */ private ToolStripMenuItem 菜单ToolStripMenuItem; private ToolStripMenuItem 退出程序ToolStripMenuItem; private ToolStripMenuItem 考试须知ToolStripMenuItem; /** * 定义WebBrowser容器 * */ private WebBrowser webBrowser1; } }
5.窗体事件的主要代码:
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
/**
* 窗体类
* */
public partial class Form1 : Form
{
public Form1()
{
/**
* 容器初始化
* */
InitializeComponent();
}
/**
* 定义钩子对象
* */
KeyboardHook kh;
/**
* 窗体加载时启动 winfrom 钩子
**/
private void Form1_Load(object sender, EventArgs e)
{
kh = new KeyboardHook();
kh.SetHook();
}
/**
* 键盘事件监听
* */
void kh_OnKeyDownEvent(object sender, KeyEventArgs e)
{
}
/**
* 窗体关闭
* */
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
kh.UnHook();
}
/**
* 退出程序
* */
private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.GetCurrentProcess().Kill();
}
private void 考试须知ToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("考生请注意:作弊者,格杀勿论,不留余地~");
}
}
}
fixed
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。