國內最大的酷站演示中心!
鉤子(hook),是windows消息處理機制的一個平臺,應用程序可以在上面設置子程以監視指定窗口的某種消息,而且所監視的窗口可以是其他進程所創建的。當消息到達后,在目標窗口處理函數之前處理它。鉤子機制允許應用程序截獲處理window消息或特定事件。
關于hook的詳細介紹,在微軟的msdn中有,http://www.microsoft.com/china/community/program/originalarticles/techdoc/hook.mspx
下面是我在c#中來應用hook:
實現效果:
當用戶在textbox中輸入 b 的時候,textbox 始終顯示 a
實現過程:
1、新建一個c#的windowsapplication
2、在form1中,添加下面一些變量:
internal enum hooktype //枚舉,鉤子的類型
{
//msgfilter = -1,
//journalrecord = 0,
//journalplayback = 1,
keyboard = 2,
//getmessage = 3,
//callwndproc = 4,
//cbt = 5,
//sysmsgfilter = 6,
//mouse = 7,
//hardware = 8,
//debug = 9,
//shell = 10,
//foregroundidle = 11,
//callwndprocret = 12,
//keyboardll = 13,
//mousell = 14,
};
intptr _nexthookptr; //記錄hook編號
3、在form1中引入必須的api
[dllimport("kernel32.dll")]
static extern int getcurrentthreadid(); //取得當前線程編號的api
[dllimport("user32.dll")]
internal extern static void unhookwindowshookex(intptr handle); //取消hook的api
[dllimport("user32.dll")]
internal extern static intptr setwindowshookex(int idhook, [marshalas(unmanagedtype.functionptr)] hookproc lpfn, intptr hinstance, int threadid); //設置hook的api
[dllimport("user32.dll")]
internal extern static intptr callnexthookex(intptr handle, int code, intptr wparam, intptr lparam); //取得下一個hook的api
4、聲明一個實現的委托
internal delegate intptr hookproc(int code, intptr wparam, intptr lparam);
5、添加自己的hook處理過程
intptr myhookproc(int code, intptr wparam, intptr lparam)
{
if( code < 0 ) return callnexthookex(_nexthookptr,code, wparam, lparam); //返回,讓后面的程序處理該消息
if( wparam.toint32() == 98 || wparam.toint32() == 66 ) //如果用戶輸入的是 b
{
this.textbox1.text = "a";
return (intptr) 1; //直接返回了,該消息就處理結束了
}
else
{
return intptr.zero; //返回,讓后面的程序處理該消息
}
}
6、添加加入hook鏈和從hook鏈中取消的函數
public void sethook()
{
if( _nexthookptr != intptr.zero ) //已經勾過了
return;
hookproc myhookproc = new hookproc(myhookproc); //聲明一個自己的hook實現函數的委托對象
_nexthookptr = setwindowshookex((int)hooktype.keyboard, myhookproc , intptr.zero , getcurrentthreadid()); //加到hook鏈中
}
public void unhook()
{
if( _nexthookptr != intptr.zero )
{
unhookwindowshookex(_nexthookptr); //從hook鏈中取消
_nexthookptr = intptr.zero;
}
}
7、在form1的load事件中添加 sethook() , 在form1的closing 事件中添加 unhook()
private void form1_load(object sender, system.eventargs e)
{
sethook();
}
private void form1_closing(object sender, system.componentmodel.canceleventargs e)
{
unhook();
}
8、運行
輸入 b , 發現 textbox 里面顯示的是 a 了!
小結:
這是一個非常簡單的hook應用,當我們在做windows程序的時候,可能會用到這些東西。我正在試圖做一個比較通用的類來進行一個封裝,以便以后更好的使用。努力ing...