鉤子其實就是調用一下api而已:
1、安裝鉤子:
setwindowshookex
函數原形:hhook setwindowshookex(
int idhook, // 鉤子類型,
hookproc lpfn, // 鉤子函數地址
instance hmod, // 鉤子所在的實例的句柄,
dword dwthreadid // 鉤子所監視的線程的線程號
)
hmod: 對于線程序鉤子,參數傳null;
對于系統鉤子:參數為鉤子dll的句柄
dwthreadid:對于全局鉤子,該參數為null。
鉤子類型用wh_callwndproc=4(發送到窗口的消息。由sendmessage觸發)
返回:成功:返回setwindowshookex返回所安裝的鉤子句柄;
失?。簄ull;
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
{
....
}
新聞熱點
疑難解答