Chinaunix首页 | 论坛 | 博客
  • 博客访问: 485986
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1916
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-11 22:01
个人简介

从事实时计算多年,熟悉jstorm/spark/flink/kafka/rocketMq, 热衷于开源,希望在这里和前辈们一起学习与分享,得到长足的进步!邮箱:hustfxj@gmail.com 我的githup地址是:https://github.com/hustfxj。欢迎和大家一起交流探讨问题。

文章分类

全部博文(80)

文章存档

2017年(11)

2015年(3)

2014年(33)

2013年(33)

分类: C/C++

2013-12-10 09:27:43

              在网上搜索“键盘记录C++”实现可以找到很多相关文章,我也是照着上面的介绍去研究去试着做的,从懂到不懂。那么为什么有那么多材料我还要去写这样一篇 文章,我想这个是我个人需要关心的问题,我不是那种ctrl+c ctrl+v的复制党,我只想将我所学的东西做个记录。我想每个人对知识的理解是站在不同角度的,希望我的文章可以给读者一些新的理解。

               实现钩子的主要API函数:SetWindowsHookEx()。对于没有过研究的人(0基础),建议去百度搜索下这个函数,里面讲解的很详细了。其实 有很多时候一些常用的函数在百度百科里都可以搜到的,讲解的很详细很好了。那么针对这个函数,我还是先照顾那些不爱去动手搜索的人,说说它的几个参数。

HHOOK SetWindowsHookEx(         

    int idHook,

    HOOKPROC lpfn,

    HINSTANCE hMod,

    DWORD dwThreadId

)

int idHook int型的参数,一般我们在传递参数时用定义好的宏进行传递,该参数表示安装钩子的类型,比如要安装一个鼠标的钩子那么参数可以写WH_MOUSE或者 WH_MOUSE_LL,他们的区别是前者是当调用GetMessage 或者 PeekMessage 函数所触发的鼠标消息,后者是当有鼠标消息事件产生即触发。同理WH_KEYBOARDWH_KEYBOARD_LL。还有其他类型的钩子,那么可以根 据你的程序需要去定制了。

HOOKPROC lpfn :传递一个处理过程(子程),也就是说当触发了你的钩子,该处理过程负责对产生的消息处理。也就是说,当你安装了键盘钩子去监视键盘消息,当产生了消息就需要调用这个处理过程了。这个过程是自己写的,但它有预先定义好的形式,在下面会讲到。

HINSTANCE hMod :应用程序实例句柄,传递的是所调用的子程的指针地址。如果子程是在程序内部定义的那么该参数必须为NULL

DWORD dwThreadId:线程标识符,该参数表示与子程相关联的线程ID。通常情况下该参数写0时为全局钩子。

钩子子程:不同类型的钩子对应不同的处理子程,子程也是一个函数,函数内部由程序员自己设计对消息的处理。看下定义:

LRESULT CALLBACK HookProc(

    int nCode,

    WPARAM wParam,

    LPARAM lParam

)

int nCode nCode参数是Hook代码,Hook子程使用这个参数来确定任务。该参数取不同的值代表不同类型的钩子以调用不同的子程。你可以暂时忽略这个参数,照写就行。

WPARAM wParam LPARAM lParam :分别是传给钩子子程的wParam值,其具体含义与钩子类型有关。可以说这两个参数包含了我们所要处理的鼠标、键盘、以及其他类型钩子的信息。

                  当钩子子程的返回值为1时表示该子程已经对消息进行过了处理,将不再向下传递。在鼠标、键盘钩子中的效果就是屏蔽了所有的鼠标点击和键盘按下消息,对于该类型的输入操作程序将不予响应。

下面帖上个程序代码:

#define _WIN32_WINNT 0x0500

#include

using namespace std;

HHOOK g_hMouse ;//鼠标钩子全局变量

HHOOK g_hKeyb ;//键盘钩子全局变量

LRESULT CALLBACK MouseProc(         

         int nCode,

         WPARAM wParam,

         LPARAM lParam

         )

{

//添加任意自定义代码,对wParamlParam消息进行处理。

 

 

//将消息向下一个钩子传递

return CallNextHookEx(NULL, nCode, wParam, lParam);

}

LRESULT CALLBACK KeybdProc(         

         int nCode,

         WPARAM wParam,

         LPARAM lParam

         )

{

     //添加任意自定义代码,对wParamlParam消息进行处理。

 

 

     //将消息向下一个钩子传递

     return CallNextHookEx(NULL, nCode, wParam, lParam);

}

void SetHook() {

//钩子的安装

g_hMouse = SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("HookDll"),0);

g_hKeyb = SetWindowsHookEx(WH_KEYBOARD_LL,KeybdProc,GetModuleHandle("HookDll"),0);

//GetModuleHandle函数用来获取调用子程DLL的指针地址。

}

void UnHook(){

//卸载鼠标、键盘钩子

UnHookWindowsHookEx(g_hMouse);

UnHookWindowsHookEx(g_hKeyb);

 

}

如上代码是写在一个简单的钩子DLL中的框架,当然它是不能运行的了,可以用来参考学习。

里面有两个函数是上面没说过的:

CallNextHookEx():将消息向下一个钩子传递。

UnHookWindowsHookEx():卸载钩子。

            下面给出我写的一个简单实例:

  1. LRESULT CALLBACK CMessMangerApp::GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
  2. {
  3.     AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  4.     LPMSG lpMsg = (LPMSG) lParam;

  5.     if(AfxGetApp()->PreTranslateMessage(lpMsg))
  6.     {        
  7.         lpMsg->message = WM_NULL;
  8.         lpMsg->lParam = 0L;
  9.         lpMsg->wParam = 0;        
  10.     }

  11.     // Passes the hook information to the next hook procedure in
  12.     // the current hook chain.
  13.     return ::CallNextHookEx(hHook, nCode, wParam, lParam);
  14. }

  15. BOOL CMessMangerApp::InitInstance()
  16. {
  17.     hHook = ::SetWindowsHookEx(
  18.         WH_GETMESSAGE,
  19.         GetMessageProc,
  20.         AfxGetInstanceHandle(),
  21.         GetCurrentThreadId());

  22.     ASSERT (hHook);
  23.     return CWinApp::InitInstance();    
  24. }

  25. int CMyApp::ExitInstance()
  26. {
  27.     UnhookWindowsHookEx((HHOOK)hHook);    
  28.     return CWinApp::ExitInstance();
  29. }




 

阅读(3983) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~