编写钩子程序实例

合集下载

快速在方框打钩的代码

快速在方框打钩的代码

快速在方框打钩的代码在很多软件开发公司,我们经常需要在界面中使用方框打钩的形式来表示用户的选择状态。

这种形式简单明了,易于操作,通常都能够得到很好的用户反馈。

为了实现这一功能,我们可以采用一些简单的代码实现。

首先,我们需要设计一个单选框的图形,这个图形可以采用图片、字体、Unicode字符等多种方式来完成,下面我们采用Unicode字符,其符号为“✓”(U+2713)。

在代码中,可以这样写一个打钩的函数:```pythondef tick_box(checked):'''返回一个方框打钩的字符串,如果checked为True,表示已选中;否则表示未选中'''if checked:return '✓'else:return '□'```这个函数很简单,当传入的参数checked为True时,返回一个✓字符,否则返回一个□字符。

接着,我们可以将这个打钩函数和一个文本框绑定在一起,例如:```pythonfrom tkinter import *root = Tk()textvar = BooleanVar()text = Checkbutton(root, text=tick_box(textvar.get()), variable=textvar, onvalue=True, offvalue=False, anchor='w') text.pack(fill='x')root.mainloop()```这里我们使用了Tkinter模块来创建一个简单的窗口程序,当用户勾选或取消勾选这个文本框时,会自动更新文本框中的内容(即方框中的打钩状态)。

在这个程序中,我们将文本框和布尔变量textvar 绑定在一起,使用onvalue和offvalue参数指定勾选和未勾选的值,默认为True和False。

钩子函数的写法

钩子函数的写法

钩子函数的写法钩子函数(Hook functions)是一种在特定时机执行的函数,常用于插件开发、事件处理等场景。

在编写钩子函数时,可以按照以下方式进行:1. 定义一个函数,作为钩子函数的具体实现。

2. 根据需要确定触发钩子函数的时机,例如在特定事件发生前、后或中间进行处理。

3. 在相应的时机调用钩子函数,传递必要的参数。

4. 根据业务逻辑和需求,在钩子函数内部执行相应的操作,可以修改数据、调用其他函数等。

5. 根据具体情况,可能需要在钩子函数中返回一个值或进行错误处理。

以下是一个示例,展示了钩子函数的基本写法:```pythondef pre_processing_hook(data):# 钩子函数的前置处理逻辑print("执行钩子函数前置处理")# 可以修改传入的数据data += " modified"# 返回修改后的数据return datadef main_process(data):# 主要处理逻辑print("执行主要处理逻辑")# 调用钩子函数processed_data =pre_processing_hook(data)# 处理钩子函数返回的数据print("处理钩子函数返回的数据:", processed_data)# 调用示例data = "原始数据"main_process(data)```在上述示例中,`pre_processing_hook` 函数作为一个钩子函数,在`main_process` 函数的执行过程中被调用。

钩子函数在这里扮演了对数据进行预处理的角色,并返回处理后的数据供主要处理逻辑使用。

需要注意的是,钩子函数的具体实现和调用方式可能因编程语言、框架或应用场景而异,上述示例仅为一种通用写法的示意。

在实际开发中,根据具体需求和开发环境进行相应的调整和扩展。

mfc 键盘hook例子

mfc 键盘hook例子

mfc 键盘hook例子全文共四篇示例,供读者参考第一篇示例:MFC是Microsoft Foundation Classes的缩写,是微软公司开发的一种面向对象的C++库。

它提供了许多对Windows编程常用的类和函数,方便开发人员编写Windows应用程序。

在MFC中,键盘hook是一种用于监控键盘消息的技术。

通过键盘hook,我们可以在程序运行时捕获、处理键盘输入,实现自定义的按键响应逻辑。

在本文中,我们将以一个简单的MFC键盘hook例子来演示如何实现键盘消息的拦截和处理。

通过这个例子,读者可以了解MFC中如何使用键盘hook,并学习如何在程序中对键盘消息进行相应的处理。

我们需要创建一个MFC应用程序。

在Visual Studio中新建一个MFC应用程序项目,选择“桌面应用程序(MFC)”模板,并按照向导设置好项目名称和路径。

在新建的MFC应用程序项目中,我们可以添加一个新的类来处理键盘hook。

右键单击项目名称,选择“添加”->“类”,在“添加类”对话框中选择“MFC类from General”模板,填写类的名称(比如CHookManager)并点击“添加”。

在CHookManager类中,我们需要实现键盘hook的安装和卸载函数。

在类的.h文件中定义以下成员变量和函数:```cppclass CHookManager{public:CHookManager();virtual ~CHookManager();在类的.cpp文件中实现这些函数:```cppBOOL g_bHookInstalled = FALSE;HHOOK g_hHook = NULL;CHookManager::CHookManager(){}LRESULT CALLBACK CHookManager::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){if (nCode >= 0){// 处理键盘消息KBDLLHOOKSTRUCT* pKbdStruct = (KBDLLHOOKSTRUCT*)lParam;if (pKbdStruct->vkCode == VK_ESCAPE){// 拦截ESC键return 1;}}return CallNextHookEx(g_hHook, nCode, wParam, lParam);}void CHookManager::InstallHook(){if (!g_bHookInstalled){g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(NULL), 0);g_bHookInstalled = TRUE;}}在上面的代码中,我们定义了一个HHOOK类型的全局变量g_hHook和一个BOOL类型的全局变量g_bHookInstalled,用于存储键盘hook的句柄和安装状态。

不依赖的DLL的全局钩子编写

不依赖的DLL的全局钩子编写

不依赖的DLL的全局钩子编写(例:WH_KEYBOARD_LL)在VC中捕按键可以在OnKeyDown 或OnKeyUp 事件中进行捕获,不过这有很大的局限性,这里只能捕获用户按键。

但在一些特殊的工程(项目)中往往需要捕获某些系统按键以完成特殊的功能,我们就不得不选择钩子了,一般情况下大家都会选择WH_KEYBOARD 这个钩子类型,但是在编写过程会发现这个钩子类型并不能捕获所有的系统按键,怎么办呢?那就得选择WH_KEYBOARD_LL (低级键盘钩子)了,使用它可以捕获全部的系统按键,一个不漏……在使用低级键盘钩子之前,先在StdAfx.h 的第一行添加一条:#define _WIN32_WINNT 0x400(这里假定你是用的MFC 的DLL),不然在编译的时候会提示说WH_KEYBOARD_LL 没有定义。

网上还有另一种方法:首先定义#define WH_KEYBOARD_LL 13; 然后Winuser.h 中定义的tagKBDLLHOOKSTRUCT 代码拷贝到工程中。

下面代码用以捕获系统按键:/*用户模块return TRUE; --->丢弃该消息*/LRESULT CALLBACK LowLevelKeyboardProc(int nCode, // hook codeWPARAM wParam, // message identifierLPARAM lParam // message data){PKBDLLHOOKSTRUCT pm = NULL;if (nCode == HC_ACTION){pm = (PKBDLLHOOKSTRUCT)lParam;switch(pm->vkCode){//屏蔽win键case VK_LWIN:case VK_RWIN:return 1;break;//屏蔽alt+tabcase VK_TAB:if(pm->flags & LLKHF_ALTDOWN){return 1;}break;//屏蔽esc alt+esc ctrl+esccase VK_ESCAPE:return 1;break;//屏蔽ALT+F4case VK_F4:if(pm->flags & LLKHF_ALTDOWN){return 1;}break;//屏蔽F1case VK_F1:return 1;break;//屏蔽CTRL+ALT+DELcase VK_DELETE:if(pm->flags & LLKHF_ALTDOWN){if (GetKeyState(VK_CONTROL) < 0){return 1;}}break;default:break;}}}// if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN)// //如果按键为按下状态// {// if (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) // //屏敝WIN(左右) 键// {// return TRUE;// }// if (Key_Info->vkCode == 0x4D && ((GetKeyState(VK_LWIN) & 0x8000) || // (GetKeyState(VK_RWIN) & 0x8000)))// //屏敝WIN+D 组合键(左右)// {// return TRUE;// }// if (Key_Info->vkCode == 0x44 && ((GetKeyState(VK_LWIN) & 0x8000) ||// (GetKeyState(VK_LWIN) & 0x8000)))// //屏敝WIN+M 组合键(左右)// {// return TRUE;// }// if (Key_Info->vkCode == 0x1b && GetKeyState(VK_CONTROL) & 0x8000) // //屏敝CTRL + ESC 组合键// {// return TRUE;// }// if (Key_Info->vkCode == VK_TAB && Key_Info->flags & LLKHF_ALTDOWN)// //屏敝ATL + TAB 组合键// {// return TRUE;// }// if (Key_Info->vkCode == VK_ESCAPE && Key_Info->flags & LLKHF_ALTDOWN)// //屏敝ATL + ESC 组合键// {// return TRUE;// }// if (Key_Info->flags & LLKHF_ALTDOWN)// //屏敝CTRL 键// {// return TRUE;// }// }return CallNextHookEx(g_hhk, nCode, wParam, lParam);}BOOL CTestHookDlg::OnInitDialog(){CDialog::OnInitDialog();// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization hereg_hhk = SetWindowsHookEx(13, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);return TRUE; // return TRUE unless you set the focus to a control}*** 注意***此钩子必须是系统级的钩子,也就是说在安装钩子的时候,ThreadID 的值必须为0。

HOOKAPI(一)——HOOK基础+一个鼠标钩子实例

HOOKAPI(一)——HOOK基础+一个鼠标钩子实例

HOOKAPI(⼀)——HOOK基础+⼀个⿏标钩⼦实例HOOK API (⼀)——HOOK基础+⼀个⿏标钩⼦实例code: https:///hfl15/windows_kernel_development/tree/master/demo_source_code/MouseHook0x00 起因最近在做毕业设计,有⼀个功能是需要实现对剪切板的监控和进程的防终⽌保护。

原本想从内核层实现,但没有头绪。

最后决定从调⽤层⼊⼿,即采⽤HOOK API的技术来挂钩相应的API,从⽽实现预期的功能。

在这样的需求下,就开始学习了HOOK API。

0x01什么是HOOK APIHOOK(钩⼦,挂钩)是⼀种实现Windows平台下类似于中断的机制。

HOOK机制允许应⽤程序拦截并处理Windows消息或指定事件,当指定的消息发出后,HOOK程序就可以在消息到达⽬标窗⼝之前将其捕获,从⽽得到对消息的控制权,进⽽可以对该消息进⾏处理或修改,加⼊我们所需的功能。

钩⼦按使⽤范围分,可分为线程钩⼦和系统钩⼦,其中,系统钩⼦具有相当⼤的功能,⼏乎可以实现对所有Windows消息的拦截、处理和监控。

这项技术涉及到两个重要的API,⼀个是SetWindowsHookEx,安装钩⼦;另⼀个是UnHookWindowsHookEx,卸载钩⼦。

本⽂使⽤的HOOK API技术,是指截获系统或进程对某个API函数的调⽤,使得API的执⾏流程转向我们指定的代码段,从⽽实现我们所需的功能。

Windows下的每个进程均拥有⾃⼰的地址空间,并且进程只能调⽤其地址空间内的函数,因此HOOK API尤为关键的⼀步是,设法将⾃⼰的代码段注⼊到⽬标进程中,才能进⼀步实现对该进程调⽤的API进⾏拦截。

然⽽微软并没有提供HOOK API的调⽤接⼝,这就需要开发者⾃⼰编程实现,⼤家所熟知的防毒软件、防⽕墙软件等均采⽤HOOK API实现。

⼀般来说,HOOK API由两个组成部分,即实现HOOK API的DLL⽂件,和启动注⼊的主调程序。

c#编程钩子hook实例

c#编程钩子hook实例

#pragma data_seg("SharedDataName")
HHOOK hHook=NULL;
#pragma data_seg() 在
#pragma data_seg("SharedDataName")

#pragma data_
seg()
之间的所有变量将被访问该
(
int nCode,
WPARAM wParam,
LPARAM lParam
);
HookProc
是应用程序定义的名字。
nCode
参数是
Hook
代码,
Hook
子程使用这个参数来确定任务。这
个参数的值依赖于
的;而在
Win32
环境中,情况却发生了变化,
DLL
函数中的代码所创
建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载

DLL
时,操作系统自动把
DLL
地址映射到该进程的私有空间,也就
是进程的虚拟地址空间,而且也复制该
DLL
的全局数据的一份拷贝到
控制权。
Windows
并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当
有一个钩子被卸载,
Windows
便释放其占用的内存,并更新整个
Ho
ok
链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,
那么系统会自动为它做卸载钩子的操作。
钩子子程是一个应用程序定义的回调函数
程的消息同时发送给钩子子程,且被钩子子程先处理。

C++钩子,HOOK编程,全局钩子

C++钩子,HOOK编程,全局钩子

C++钩⼦,HOOK编程,全局钩⼦全局钩⼦,HOOK编程,建⽴DLL项⽬:代码如下:#include"pch.h"#define _DLL_API#include"MyDLL.h"HHOOK MouseHook = NULL;HHOOK KeyBoargHook = NULL;HINSTANCE g_hinst; //获取主模块的句柄,//创建⼀个节,只要是包含在节内的数据,多进程是共享的,节内的数据必须初始化,dumpbin /headers 查看dll信息#pragma data_seg("MySec")HWND g_hwnd = NULL;#pragma data_seg()#pragma comment(linker,"/section:MySec,RWS") //使⽤linker连接⽅式,设置MySec读写共享权限//⿏标钩⼦LRESULT __stdcall MouseProc(int nCode, WPARAM wparam, LPARAM lparam){return1;}//键盘钩⼦LRESULT __stdcall KeyBoardHook(int nCode, WPARAM wparam, LPARAM lparam){if (wparam == VK_F2) //当按下F2时退出{::SendMessage(g_hwnd, WM_CLOSE, 0, 0);UnhookWindowsHookEx(KeyBoargHook);}return1;}//接⼝void SetMouseHook(HWND hwnd){g_hwnd = hwnd;MouseHook = SetWindowsHookExW(WH_MOUSE, MouseProc, g_hinst, 0);}//接⼝void SetKeyBoardHook(HWND hwnd) //为了给主窗⼝发消息,我们定义了⼀个窗⼝句柄参数。

Hook钩子C#实例

Hook钩子C#实例

Hook钩⼦C#实例转过来的⽂章,出处已经不知道了,但只这篇步骤⽐较清晰,就贴出来了。

⼀。

写在最前本⽂的内容只想以最通俗的语⾔说明钩⼦的使⽤⽅法,具体到钩⼦的详细介绍可以参照下⾯的⽹址:⼆。

了解⼀下钩⼦从字⾯上理解,钩⼦就是想钩住些东西,在程序⾥可以利⽤钩⼦提前处理些Windows消息。

例⼦:有⼀个Form,Form⾥有个TextBox,我们想让⽤户在TextBox⾥输⼊的时候,不管敲键盘的哪个键,TextBox⾥显⽰的始终为“A”,这时我们就可以利⽤钩⼦监听键盘消息,先往Windows的钩⼦链表中加⼊⼀个⾃⼰写的钩⼦监听键盘消息,只要⼀按下键盘就会产⽣⼀个键盘消息,我们的钩⼦在这个消息传到TextBox之前先截获它,让TextBox显⽰⼀个“A”,之后结束这个消息,这样TextBox得到的总是“A”。

消息截获顺序:既然是截获消息,总要有先有后,钩⼦是按加⼊到钩⼦链表的顺序决定消息截获顺序。

就是说最后加⼊到链表的钩⼦最先得到消息。

截获范围:钩⼦分为线程钩⼦和全局钩⼦,线程钩⼦只能截获本线程的消息,全局钩⼦可以截获整个系统消息。

我认为应该尽量使⽤线程钩⼦,全局钩⼦如果使⽤不当可能会影响到其他程序。

三。

开始通俗这⾥就以上⽂提到的简单例⼦做个线程钩⼦。

第⼀步:声明API函数使⽤钩⼦,需要使⽤WindowsAPI函数,所以要先声明这些API函数。

// 安装钩⼦[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);// 卸载钩⼦[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);// 继续下⼀个钩⼦[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);// 取得当前线程编号[DllImport("kernel32.dll")]static extern int GetCurrentThreadId();声明⼀下API函数,以后就可以直接调⽤了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编写钩子程序的步骤分为三步:定义钩子函数、安装钩子和卸载钩子。

1.定义钩子函数钩子函数是一种特殊的回调函数。

钩子监视的特定事件发生后,系统会调用钩子函数进行处理。

不同事件的钩子函数的形式是各不相同的。

下面以鼠标钩子函数举例说明钩子函数的原型:LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam)参数wParam和lParam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。

nCode包含有关消息本身的信息,比如是否从消息队列中移出。

我们先在钩子函数中实现自定义的功能,然后调用函数CallNextHookEx.把钩子信息传递给钩子链的下一个钩子函数。

CallNextHookEx.的原型如下:LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam )参数hhk是钩子句柄。

nCode、wParam和lParam 是钩子函数。

当然也可以通过直接返回TRUE来丢弃该消息,就阻止了该消息的传递。

2.安装钩子在程序初始化的时候,调用函数SetWindowsHookEx安装钩子。

其函数原型为:HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )参数idHook表示钩子类型,它是和钩子函数类型一一对应的。

比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。

Lpfn是钩子函数的地址。

HMod是钩子函数所在的实例的句柄。

对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。

dwThreadId 指定钩子所监视的线程的线程号。

对于全局钩子,该参数为NULL。

SetWindowsHookEx返回所安装的钩子句柄。

3.卸载钩子当不再使用钩子时,必须及时卸载。

简单地调用函数BOOL UnhookWindowsHookEx( HHOOK hhk)即可。

值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。

线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中,实现起来要麻烦一些。

线程钩子的编程实例:按照上面介绍的方法实现一个线程级的鼠标钩子。

钩子跟踪当前窗口鼠标移动的位置变化信息。

并输出到窗口。

(1)在VC++6.0中利用MFCAPPWizard(EXE)生成一个不使用文档/视结构的单文档应用mousehook。

打开childview.cpp 文件,加入全局变量:HHOOK hHook;//鼠标钩子句柄CPoint point;//鼠标位置信息CChildView *pV iew;// 鼠标钩子函数用到的输出窗口指针在CChildView::OnPaint()添加如下代码:CPaintDC dc(this);char str[256];sprintf(str,“x=%d,y=%d",point.x,point.y);//构造字符串dc.TextOut(0,0,str); //显示字符串(2)childview.cpp文件中定义全局的鼠标钩子函数。

LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam){//是鼠标移动消息if(wParam==WM_MOUSEMOVE||wParam ==WM_NCMOUSEMOVE){point=((MOUSEHOOKSTRUCT *)lParam)->pt;//取鼠标信息pView->Invalidate(); //窗口重画}return CallNextHookEx(hHook,nCode,wParam,lParam);//传递钩子信息}(3)CChildView类的构造函数中安装钩子。

CChildView::CChildView(){pView=this;//获得输出窗口指针hHook=SetWindowsHookEx(WH_MOUSE,MouseProc,0,GetCurrentThreadId());}(4)CChildView类的析构函数中卸载钩子。

CChildView::~CChildView(){if(hHook)UnhookWindowsHookEx(hHook);}系统钩子的编程实例:由于系统钩子要用到dll,所以先介绍下win32 dll的特点:Win32 DLL与Win16 DLL有很大的区别,这主要是由操作系统的设计思想决定的。

一方面,在Win16 DLL中程序入口点函数和出口点函数(LibMain和WEP)是分别实现的;而在Win32 DLL中却由同一函数DLLMain来实现。

无论何时,当一个进程或线程载入和卸载DLL时,都要调用该函数,它的原型是BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);,其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;这里主要介绍一下第二个参数,它有四个可能的值:DLL_PROCESS_A TTACH(进程载入),DLL_THREAD_A TTACH(线程载入),DLL_THREAD_DETACH(线程卸载),DLL_PROCESS_DETACH(进程卸载),在DLLMain 函数中可以对传递进来的这个参数的值进行判别,并根据不同的参数值对DLL进行必要的初始化或清理工作。

举个例子来说,当有一个进程载入一个DLL时,系统分派给DLL的第二个参数为DLL_PROCESS_A TTACH,这时,你可以根据这个参数初始化特定的数据。

另一方面,在Win16环境下,所有应用程序都在同一地址空间;而在Win32环境下,所有应用程序都有自己的私有空间,每个进程的空间都是相互独立的,这减少了应用程序间的相互影响,但同时也增加了编程的难度。

大家知道,在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,当进程在载入DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,也就是说每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。

因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。

亦即把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。

在VC6中有三种形式的MFC DLL(在该DLL中可以使用和继承已有的MFC类)可供选择,即Regular statically linked to MFC DLL(标准静态链接MFC DLL)和Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。

第一种DLL的特点是,在编译时把使用的MFC代码加入到DLL中,因此,在使用该程序时不需要其他MFC动态链接类库的存在,但占用磁盘空间比较大;第二种DLL的特点是,在运行时,动态链接到MFC类库,因此减少了空间的占用,但是在运行时却依赖于MFC动态链接类库;这两种DLL既可以被MFC程序使用也可以被Win32程序使用。

第三种DLL的特点类似于第二种,做为MFC类库的扩展,只能被MFC程序使用。

下面说说在VC6中全局共享数据的实现在主文件中,用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:#pragma data_seg ("shareddata")HWND sharedwnd=NULL;//共享数据#pragma data_seg()仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的(其效果是相同的),一种方法是在.DEF文件中加入如下语句:SETCTIONS shareddata READ WRITE SHARED另一种方法是在项目设置链接选项中加入如下语句:/SECTION:shareddata,rws好了,准备知识已经学完了,让我们开始编写个全局的钩子程序吧!由于全局钩子函数必须包含在动态链接库中,所以本例由两个程序体来实现。

1.建立钩子Mousehook.DLL(1)选择MFC AppWizard(DLL)创建项目Mousehook;(2)选择MFC Extension DLL(共享MFC拷贝)类型;(3)由于VC5没有现成的钩子类,所以要在项目目录中创建Mousehook.h文件,在其中建立钩子类:class AFX_EXT_CLASS Cmousehook:public CObject{public:Cmousehook();//钩子类的构造函数~Cmousehook();//钩子类的析构函数BOOL starthook(HWND hWnd);//安装钩子函数BOOL stophook();卸载钩子函数};(4)在Mousehook.app文件的顶部加入#include"Mousehook.h"语句;(5)加入全局共享数据变量:#pragma data_seg("mydata")HWND glhPrevTarWnd=NULL;//上次鼠标所指的窗口句柄HWND glhDisplayWnd=NULL;//显示目标窗口标题编辑框的句柄HHOOK glhHook=NULL;//安装的鼠标钩子句柄HINSTANCE glhInstance=NULL;//DLL实例句柄#pragma data_seg()(6)在DEF文件中定义段属性:SECTIONSmydata READ WRITE SHARED(7)在主文件Mousehook.cpp的DllMain函数中加入保存DLL实例句柄的语句:DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved){//如果使用lpReserved参数则删除下面这行UNREFERENCED_PARAMETER(lpReserved);if (dwReason == DLL_PROCESS_A TTACH){TRACE0("MOUSEHOOK.DLL Initializing!\n");//扩展DLL仅初始化一次if (!AfxInitExtensionModule(MousehookDLL, hInstance))return 0;new CDynLinkLibrary(MousehookDLL);//把DLL加入动态MFC类库中glhInstance=hInstance;//插入保存DLL实例句柄}else if (dwReason == DLL_PROCESS_DETACH){TRACE0("MOUSEHOOK.DLL Terminating!\n");//终止这个链接库前调用它AfxTermExtensionModule(MousehookDLL);}return 1;}(8)类Cmousehook的成员函数的具体实现:Cmousehook::Cmousehook()//类构造函数{}Cmousehook::~Cmousehook()//类析构函数{stophook();}BOOL Cmousehook::starthook(HWND hWnd)//安装钩子并设定接收显示窗口句柄{BOOL bResult=FALSE;glhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);if(glhHook!=NULL)bResult=TRUE;glhDisplayWnd=hWnd;//设置显示目标窗口标题编辑框的句柄return bResult;}BOOL Cmousehook::stophook()//卸载钩子{BOOL bResult=FALSE;if(glhHook){bResult= UnhookWindowsHookEx(glhHook);if(bResult){glhPrevTarWnd=NULL;glhDisplayWnd=NULL;//清变量glhHook=NULL;}}return bResult;}(9)钩子函数的实现:LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam){LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lparam;if (nCode>=0){HWND glhTargetWnd=pMouseHook->hwnd;//取目标窗口句柄HWND ParentWnd=glhTargetWnd;while (ParentWnd !=NULL){glhTargetWnd=ParentWnd;ParentWnd=GetParent(glhTargetWnd);//取应用程序主窗口句柄}if(glhTargetWnd!=glhPrevTarWnd){char szCaption[100];GetWindowText(glhTargetWnd,szCaption,100);//取目标窗口标题if(IsWindow(glhDisplayWnd))SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);glhPrevTarWnd=glhTargetWnd;//保存目标窗口}}return CallNextHookEx(glhHook,nCode,wparam,lparam);//继续传递消息}(10)编译项目生成mousehook.dll。

相关文档
最新文档