The return value is the value returned by the next hook procedure in the chain. The current hook procedure must also return this value. The meaning of the return value depends on the hook type. For more information, see the descriptions of the individual hook procedures. 建议你看MSDN,那里边有你想知道的
顺便你看看这一个吧,这上面说得很清楚。在网上找的资料噢!说得很不错的,放在这里,大家分享
---- 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。在WINDOWS中,日志钩子是个很特别的钩子,它只有全局钩子一种,是键盘鼠标等输入设备的消息在系统消息队列被取出时发生的,而且系统中只能存在一个这样的日志钩子,更重要是,它不必用在动态链接库中,这样可以省却了为安装一个全局钩子而建立一个动态链接库的麻烦。利用日志钩子,我们可以监视各种输入事件,下面的示例可以用来记录键盘的输入,当有按键发生时,自动记录按键动作的日期和时间以及当前激活的窗口名称。本示例在中文WIN98,Borland C++ Builder4中编译通过。 ---- 1.新建一个工程,在窗体Form1中放置两个按钮Button1和Button2, CAPTION分别为“安装日志钩子”和“卸载日志钩子”。 ---- 2. 定义如下全局变量: 
HHOOK g_hLogHook=NULL; //钩子变量
HWND g_hLastFocus=NULL; 
//记录上一次得到焦点的窗口句柄
const int KeyPressMask=0x80000000; //键盘掩码常量
char g_PrvChar; //保存上一次按键值3.在Button1的OnClick事件中输入:void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (g_hLogHook==NULL)
g_hLogHook = SetWindowsHookEx
(WH_JOURNALRECORD,
(HOOKPROC)JournalLogProc,
HInstance,0); //安装日志钩子
}4.在Button2的OnClick事件中输入:void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (g_hLogHook!=NULL)
{UnhookWindowsHookEx(g_hLogHook);
g_hLogHook=NULL;
} //卸载日志钩子
}5.输入钩子回调函数:
HOOKPROC JournalLogProc(int iCode, 
WPARAM wParam, LPARAM lParam)
{
if (iCode< 0) return (HOOKPROC)CallNextHookEx
(g_hLogHook,iCode,wParam,lParam);
if (iCode==HC_ACTION)
{EVENTMSG *pEvt=(EVENTMSG *)lParam;
int i;
HWND hFocus; //保存当前活动窗口句柄
char szTitle[256]; //当前窗口名称
char szTime[128]; //保存当前的日期和时间
FILE *stream=fopen(“c:\\logfile.txt”,"a+t");
if (pEvt->message==WM_KEYDOWN) 
{int vKey=LOBYTE(pEvt- >paramL); // 取得虚拟键值
char ch;
char str[10];
hFocus=GetActiveWindow(); 
//取得当前活动窗口句柄
if(g_hLastFocus!=hFocus) 
//当前活动窗口是否改变
{GetWindowText(hFocus,szTitle,256);
g_hLastFocus=hFocus;
strcpy(szTime,DateTimeToStr(Now())
.c_str()); //得到当前的日期时间
fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle); //写入文件
fprintf(stream,"%c%c",32,32); 
}
int iShift=GetKeyState(0x10); 
//测试SHIFT,CAPTION,NUMLOCK等键是否按下
int iCapital=GetKeyState(0x14);
int iNumLock=GetKeyState(0x90);
bool bShift=(iShift & KeyPressMask)==KeyPressMask; 
bool bCapital=(iCapital & 1)==1;
bool bNumLock=(iNumLock & 1)==1;
if (vKey >=48 && vKey< =57) 
// 数字0-9
if (!bShift) fprintf(stream,"%c",vKey);
if (vKey >=65 && vKey< =90) 
// A-Z a-z
{if (!bCapital)
if (bShift) ch=vKey; else ch=vKey+32;
else
if (bShift) ch=vKey+32; else ch=vKey;
fprintf(stream,"%c",ch);
}
if (vKey >=96 && vKey< =105) // 小键盘0-9
if (bNumLock) fprintf(stream,"%c",vKey-96+48);
if (vKey>=186 && vKey<=222) // 其他键
{switch (vKey)
{case 186:if (!bShift) ch=';'; else ch=':';break;
case 187:if (!bShift) ch='='; else ch='+';break;
case 188:if (!bShift) ch=','; else ch='<' ;break;
case 189:if (!bShift) ch='-'; else ch='_';break;
case 190:if (!bShift) ch='.'; else ch=' >';break;
case 191:if (!bShift) ch='/'; else ch='?';break;
case 192:if (!bShift) ch='`'; else ch='~';break;
case 219:if (!bShift) ch='['; else ch='{';break;
case 220:if (!bShift) ch='\\'; else ch='|';break;
case 221:if (!bShift) ch=']'; else ch='}';break;
case 222:if (!bShift) ch='\''; else ch='\"';break;
default:ch='n';break;
}
if (ch!='n') fprintf(stream,"%c",ch);
}
// if (wParam >=112 && wParam<=123) 
// 功能键 [F1]-[F12]
if (vKey >=8 && vKey< =46) //方向键
{switch (vKey)
{case 8:strcpy(str,"[BK]");break;
case 9:strcpy(str,"[TAB]");break;
case 13:strcpy(str,"[EN]");break;
case 32:strcpy(str,"[SP]");break;
case 33:strcpy(str,"[PU]");break;
case 34:strcpy(str,"[PD]");break;
case 35:strcpy(str,"[END]");break;
case 36:strcpy(str,"[HOME]");break;
case 37:strcpy(str,"[LF]");break;
case 38:strcpy(str,"[UF]");break;
case 39:strcpy(str,"[RF]");break;
case 40:strcpy(str,"[DF]");break;
case 45:strcpy(str,"[INS]");break;
case 46:strcpy(str,"[DEL]");break;
default:ch='n';break;
}
if (ch!='n')
{if (g_PrvChar!=vKey)
{fprintf(stream,"%s",str);
g_PrvChar=vKey;
}
}
}
}
if
(pEvt- >message==WM_LBUTTONDOWN || pEvt- >message
==WM_RBUTTONDOWN)
{hFocus=GetActiveWindow();
if (g_hLastFocus!=hFocus)
{g_hLastFocus=hFocus;
GetWindowText(hFocus,szTitle,256); 
strcpy(szTime,DateTimeToStr(Now()).c_str()); 
//得到当前的日期时间
fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle); //写入文件
fprintf(stream,"%c%c",32,32); 
}
}
fclose(stream);
return (HOOKPROC)CallNextHookEx
(g_hLogHook,iCode,wParam,lParam);
}---- 将工程编译执行后,每当激活一个窗口时,就会把当前窗口名称写入文件c:\logfile.txt中,当有按键时,按键的名称也会写入此文件中,这里的并没有处理全部的按键,读者可根据需要添加相应的语句。要捕捉键盘的按键动作,用键盘钩子(Keyboard Hook)也同样可以实现,但是用日志钩子却比键盘钩子要方便许多。首先,如果要捕捉其他应用程序的按键,即做成全局钩子,键盘钩子一定要单独放在动态链接库中,而日志钩子却不必;其次,在键盘钩子函数得到的键盘按键之前,系统已经处理过这些输入了,如果系统把这些按键屏蔽掉,键盘钩子就无法检测到它们,例如,当输入屏幕保护程序密码时,键盘钩子无法检测到用户输入了那些字符,而日志钩子却可以检测到。 ---- 无论是哪种钩子, 都会增加系统处理消息的时间,从而降低系统的性能,我们只有在必要的时候才安装这些钩子,而且尽可能在不需要时移走它们。 

解决方案 »

  1.   

    copy_paste(木石三),TechnoFantasy是否在线,能否解答一下?
      

  2.   

    我来告诉你:
    1.CallNextHookEx用code的返回值来决定怎样出来hook的信息。code小于0表示继续下一个消息
    2.他是键盘掩码常量
      

  3.   

    To: cszhz(丑小鸭) 
    1.CallNextHookEx用code的返回值来决定怎样出来hook的信息。code小于0应该是继续调用钩子链中的下一个钩子。
      

  4.   

    你可以在网上查找一下,有很多关于此的介绍,包括APIHOOK,截获API函数,很好玩的
      

  5.   

    钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,这个函数的原型是HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);,其中,第一个参数是钩子的类型;第二个参数是钩子函数的地址;第三个参数是包含钩子函数的模块句柄;第四个参数指定监视的线程。如果指定确定的线程,即为线程专用钩子;如果指定为空,即为全局钩子。其中,全局钩子函数必须包含在DLL(动态链接库)中,而线程专用钩子还可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。   
      

  6.   

    to dgb(dgb):谢谢,很精华的一段话,使我又加深了理解.网上资源我查了,不过理想的好像很少,你知道那些网站或者好的东东是否可以告诉我?
      

  7.   

    在Windows系统中提供了一种系统消息挂钩的(Message hook)功能,使用消息挂钩,可以实时监视处理系统中的各种消息。很多鼠标增强软件就是利用消息挂钩来拦截所有的鼠标消息进行处理的。
    要设置鼠标消息挂钩,一般先建立一个使用鼠标消息挂钩的动态连接库(DLL)文件,然后就可以在其它程序中使用这个DLL文件处理鼠标消息。
    下面的程序介绍通过鼠标消息挂钩监视鼠标消息,从而实现类似于一些鼠标增强软件一样的使窗口上下左右滚动的功能。1.建立动态连接库
    选择菜单 File|New ,选择DLL产生一个DLL模版,保存为 MHook.Dpr
    //MHook.Dpr源程序
    library MHook;uses
    SysUtils,
    Classes,
    hkproc in 'hkproc.pas';exports
    EnableMouseHook,
    DisableMouseHook;begin
    hNextHookProc:=0;
    procSaveExit:=ExitProc;
    ExitProc:=@HotKeyHookExit;
    end.再选择菜单 File|New ,选择Unit建立一个Pas文件,保存为 HKProc.pas
    //HKProc.pas源程序
    unit hkproc;interface
    uses
    Windows,Messages;
    const
    Move_Up = 0;Move_Down=1;
    Move_Left=2;
    Move_Right=3;
    var
    hNextHookProc:HHook;
    procSaveExit:Pointer;
    M_Direct:Integer;
    LPoint:TPoint;
    NowWindow:Integer;function MouseProc(iCode:Integer;wParam:WPARAM;
    lParam:Pointer):LRESULT; stdcall;export;
    function EnableMouseHook(WndHandle:integer):BOOL;export;function DisableMouseHook:BOOL;export;
    function GetDirect(FPoint : TPoint;LPoint : TPoint):integer;
    procedure HotKeyHookExit;far;implementation//GetDirect函数根据光标的移动决定窗口滚动的方向。
    function GetDirect(FPoint : TPoint;LPoint : TPoint):integer;
    var
    iWidth,iHeight:integer;
    begin
    iWidth:=LPoint.x-FPoint.x;
    iHeight:=lPoint.y-FPoint.y;
    Result:=-1;if ((iWidth=0)or(iHeight=0))then
    exit;if ((abs(iWidth) div abs(iHeight))>=2) then
    if iWidth<0 then //Move to left
    Result:=Move_Left
    else
    Result:=Move_Rightelse if ((abs(iHeight) div abs(iWidth))>=2) then
    if iHeight<0 then //Move to top
    Result:=Move_Up
    else
    Result:=Move_Down;end;function MouseProc(iCode:Integer;wParam:WPARAM;
    lParam:Pointer):LRESULT; stdcall;export;
    var
    pMouse:^MOUSEHOOKSTRUCT;
    l:integer;
    begin
    //如果用户按下鼠标右键同时Scroll Lock键为按下状态则
    //滚动窗口。
    if ((wParam=WM_RBUTTONDOWN) and Boolean(GetKeyState(145))) then
    begin
    pMouse:=lParam;
    l:=GetDirect(lPoint,pMouse.pt);
    if l>=0 then
    M_Direct:=l;
    lPoint:=pMouse.pt;NowWindow:=WindowFromPoint(lPoint);
    if M_Direct=Move_Up then
    SendMessage(NowWindow,WM_VSCROLL,SB_PAGEUP,0)
    else if M_Direct=Move_Down thenSendMessage(NowWindow,WM_VSCROLL,SB_PAGEDOWN,0)
    else if M_Direct=Move_Left then
    SendMessage(NowWindow,WM_HSCROLL,SB_PAGELEFT,0)
    else if M_Direct=Move_Right then
    SendMessage(NowWindow,WM_HSCROLL,SB_PAGERIGHT,0);
    Result:=1;
    exit;
    end
    else if ((wParam=WM_RBUTTONUP) and Boolean(GetKeyState(145))) then
    Result:=1
    else
    begin
    Result:=0;
    if iCode<0 then
    begin
    Result:=CallNextHookEx(hNextHookProc,iCode,wParam,
    integer(lParam));
    Exit;
    end;
    end;
    end;function EnableMouseHook(WndHandle:integer):BOOL;export;
    begin
    GetCursorPos(lPoint);
    Result:=False;
    if hNextHookProc<>0 then
    exit;
    //设置Mouse hook
    hNextHookProc:=SetWindowsHookEx(WH_MOUSE,@MouseProc,
    Hinstance,0);
    Result:=hNextHookProc<>0;
    end;function DisableMouseHook:BOOL;export;
    begin
    if hNextHookProc<>0 then
    begin
    UnHookWindowsHookEx(hNextHookProc);
    hNextHookProc:=0;
    end;
    Result:=hNextHookProc=0;
    end;procedure HotKeyHookExit;
    begin
    if hNextHookProc<>0 then
    DisableMouseHook;
    ExitProc:=procSaveExit;
    end;end.
    在菜单中选择 Project|Build MHook建立DLL文件。2.建立程序调用动态连接库
    在这里我们还是使用Delphi建立程序,当然也可以使用诸如VB等调用动态连接库。
    在菜单中选 File|New Application建立一个新程序,将工程文件保存为Project1.dpr//project1的源程序
    program Project1;uses
    Forms,
    Sample1 in 'Sample1.pas' {Form1};{$R *.RES}begin
    Application.Initialize;
    //隐藏窗口
    Application.ShowMainForm := False;Application.CreateForm(TForm1, Form1);
    Application.Run;
    end. 将Form1的源程序文件保存成Sample1.pas//Form1的源程序
    unit Sample1;interfaceuses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Menus, ImgList,ShellApi, ExtCtrls;const
    WM_ICONMESSAGE=WM_USER+$100;
    type
    TForm1 = class(TForm)procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    private
    procedure WMBarIcon(var Message:TMessage);message WM_ICONMESSAGE;publicend;function EnableMouseHook(WndHandle:integer):BOOL;external 'MHook.DLL';
    function DisableMouseHook:BOOL;external'MHook.DLL';var
    Form1: TForm1;implementation{$R *.DFM}
    procedure TForm1.WMBarIcon (var Message:TMessage);
    begin
    //用户双击任务栏图标则关闭程序 
    if Message.LParam = WM_LBUTTONDBLCLK then
    close;
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
    lpData:PNotifyIconData;
    begin
    //删除任务栏图标
    lpData := new(PNotifyIconDataA);
    lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);
    lpData.Wnd := Form1.Handle;
    lpData.hIcon := Form1.Icon.Handle;
    lpData.uCallbackMessage := WM_ICONMESSAGE;
    lpData.uID :=0;
    lpData.szTip := '鼠标演示';
    lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    Shell_NotifyIcon(NIM_DELETE,lpData);
    dispose(lpData);
    //解除Mouse hook
    DisableMouseHook;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
    lpData:PNotifyIconData;
    begin
    EnableMouseHook(Form1.Handle);
    Form1.Visible := False;
    lpData := new(PNotifyIconDataA);
    lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);
    lpData.Wnd := Form1.Handle;
    lpData.hIcon := Form1.Icon.Handle;
    lpData.uCallbackMessage := WM_ICONMESSAGE;
    lpData.uID :=0;
    lpData.szTip := '鼠标演示';
    lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    Shell_NotifyIcon(NIM_ADD,lpData);
    dispose(lpData);
    end;end.运行程序,按下Scroll Lock键使其有效,将光标移动到文本窗口中(如IE、Word),移动鼠标,点击鼠标右键,窗口就可以依上一次移动的方向滚动。
    利用上面的原理,将程序做一些改动,就可以象专业的鼠标增强程序一样做出例如缩放窗口,运行程序等很多鼠标增强效果来。