C#钩子本线程内消息拦截

钩子其实就是调用一下API而已:

1、安装钩子:
  SetWindowsHookEx
函数原形:HHOOK SetWindowsHookEx(
int idHook, // 钩子类型,
HOOKPROC lpfn, // 钩子函数地址
INSTANCE hMod, // 钩子所在的实例的句柄,
DWORD dwThreadId // 钩子所监视的线程的线程号
)
hMod: 对于线程序钩子,参数传NULL;
对于系统钩子:参数为钩子DLL的句柄
  dwThreadId:对于全局钩子,该参数为NULL。
钩子类型用WH_CALLWNDPROC=4(发送到窗口的消息。由SendMessage触发)
返回:成功:返回SetWindowsHookEx返回所安装的钩子句柄;
失败:NULL;

2、回调,你要截获消息就在这里进行:
LRESULT WINAPI MyHookProc(
int nCode , // 指定是否需要处理该消息
WPARAM wParam, // 包含该消息的附加消息
LPARAM lParam // 包含该消息的附加消息
)

3、调用下一个钩子
LRESULT CallNextHookEx(
HHOOK hhk, // 是您自己的钩子函数的句柄。用该句柄可以遍历钩子链
int nCode, // 把传入的参数简单传给CallNextHookEx即可
WPARAM wParam, // 把传入的参数简单传给CallNextHookEx即可
LPARAM lParam // 把传入的参数简单传给CallNextHookEx即可
);

4、用完后记得卸载钩子哦,要不然你的系统会变得奇慢无比!
BOOL UnhookWindowsHookEx(
HHOOK hhk // 要卸载的钩子句柄。
)

把上面这些API用C#封装一下,就可以直接用了!
给个线程钩子的例子吧(两个Form都在同一个线程中运行):

using System.Runtime.InteropServices;

public class Form1 : System.Windows.Forms.Form
{
...
//定义委托(钩子函数,用于回调)
public delegate int HookProc(int code, IntPtr wparam, ref CWPSTRUCT cwp);

//安装钩子的函数
[DllImport("User32.dll",CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(int type, HookProc hook, IntPtr instance, int threadID);
//调用下一个钩子的函数
[DllImport("User32.dll",CharSet = CharSet.Auto)]
public static extern int CallNextHookEx(IntPtr hookHandle, int code, IntPtr wparam, ref CWPSTRUCT cwp);
//卸载钩子
[DllImport("User32.dll",CharSet = CharSet.Auto)]
public static extern bool UnhookWindowsHookEx(IntPtr hookHandle);
//获取窗体线程ID
DllImport("User32.dll",CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, int ID);

private HookProc hookProc;
private IntPtr hookHandle = IntPtr.Zero;

public Form1()
{
....
//挂接钩子处理方法
this.hookProc = new HookProc(myhookproc);
}

//开始拦截
private bool StartHook()
{
Form2 f=new Form2();
f.Show();//加上这个
//安装钩子,拦截系统向Form2发出的消息
this.hookHandle = SetWindowsHookEx(4, hookProc, IntPtr.Zero ,GetWindowThreadProcessId(f.Handle,0));
return (this.hookHandle != 0);
}

//停止拦截
private bool StopHook()
{
return UnhookWindowsHookEx(this.hookHandle);
}

//钩子处理函数,在这里拦截消息并做处理
private int myhookproc(int code, IntPtr wparam, ref CWPSTRUCT cwp)
{
switch(code)
{
case 0:
switch(cwp.message)
{
case 0x0000F://WM_PAINT,拦截WM_PAINT消息
//do something
break;
}
break;
}
return CallNextHookEx(hookHandle,code,wparam, ref cwp);
}

[StructLayout(LayoutKind.Sequential)]
public struct CWPSTRUCT
{
public IntPtr lparam;
public IntPtr wparam;
public int message;
public IntPtr hwnd;
}
}

public class Form2 : System.Windows.Forms.Form
{
....
}

时间: 2025-01-30 16:28:50

C#钩子本线程内消息拦截的相关文章

深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)

1.创建和终止线程 在MFC程序中创建一个线程,宜调用AfxBeginThread函数.该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程. 工作者线程 CWinThread *AfxBeginThread( AFX_THREADPROC pfnThreadProc, //控制函数 LPVOID pParam, //传递给控制函数的参数 int nPriority = THREAD_PRIORITY_NORMAL, //线程的优先级 UINT nStackSize =

sleep-MFC里的线程内Sleep()不执行???

问题描述 MFC里的线程内Sleep()不执行??? void CAaaDlg::OnButton1() { // TODO: Add your control notification handler code here m_a=0; SetTimer(1,500,NULL); } void CAaaDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default Upda

使用xmlhttp和Java session监听改善站内消息系统

session|xml 使用xmlhttp和Java session监听改善站内消息系统 bromon 原创  引自:http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=25340 这个题目含有许多需要解释的概念,最容易说明的是"站内消息",这是很多论坛都有的功能,可以通过web向其他的在线用户发送消息,很多用户都使用过.站内消息的第一个好处是大家都不需要安装客户端,你不用知道对方的MSN或

用xmlhttp和Java session监听改善站内消息系统

session|xml 原文出处:http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=25340 这个题目含有许多需要解释的概念,最容易说明的是"站内消息",这是很多论坛都有的功能,可以通过web向其他的在线用户发送消息,很多用户都使用过.站内消息的第一个好处是大家都不需要安装客户端,你不用知道对方的MSN或者QQ,就能与他联系,称赞他的观点或者是给他一顿臭骂.第二个好处是客户管理方便,利用

用xmlhttp和Java session改善站内消息

session|xml 这个题目含有许多需要解释的概念,最容易说明的是"站内消息",这是很多论坛都有的功能,可以通过web向其他的在线用户发送消息,很多用户都使用过.站内消息的第一个好处是大家都不需要安装客户端,你不用知道对方的MSN或者QQ,就能与他联系,称赞他的观点或者是给他一顿臭骂.第二个好处是客户管理方便,利用session来维护在线名单,各种脚本都已经把session操作封装得很易用了,不用像其他无状态的即时通信工具(比如使用UDP通信的工具)一样,要费一些脑细胞来解决在线名

用vs2013开发平板的winform软件怎么能用钩子获取到WM_TOUCH消息

问题描述 用vs2013开发平板的winform软件怎么能用钩子获取到WM_TOUCH消息. 解决方案

多线程-java相同线程,不同方法线程内传值问题

问题描述 java相同线程,不同方法线程内传值问题 大家好,我想请问一个问题,比如 class A{ new Thread(() -> { int a = 1; B b = new B(); b.invokeB(a); }); } class B{ public void invokeB(int a){ C c = new C(); c.invokeC(); } } class C{ public void invokeC(){ //这里我想用a的值,由于某些原因,不能直接把a传过来,听说用Th

qt-QT线程内调用外部函数发送信号是否有正确?多线程调用外部函数需要注意哪些问题?

问题描述 QT线程内调用外部函数发送信号是否有正确?多线程调用外部函数需要注意哪些问题? 大家好,我在QT多线程编程时,在线程内部调用了一个外部函数,外部函数中使用了emit来发送信号,请问这样是否会存在问题?另外,在线程中调用外部函数时需要注意哪些问题? 解决方案 我编写的代码大概如下: class myThread:public QThread; class DeviceScaner:public QObject { Q_OBJECT public: DeviceScaner(); ~Dev

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装  (5):前台Jquery easyUI实现   (6):EF上下文实例管理   (7):DBSession的封装 前言:通过上篇博客我们完成了对DbSession的代码编写,DbSession就相