python钩子函数教学 钩子函数使用场景( 三 )


return CallNextHookEx(oldkeyhook,nCode,wParam,lParam);
}
void EndHook(void)
{
UnhookWindowsHookEx(oldkeyhook);
}
这个动态连接库的源代码hookdll.cpp包含了键盘处理函数,设置钩子,退出钩子函数 。并将键盘敲下的键以值的格式存入到c:hookkey.txt文件中 。以下是对该文件的详细的解释 。
使用包含在DLL的函数,必须将其导入 。导入操作时通过dllimport来完成的 , dllexport和dllimport都是vc(visual C++)和bc(Borland C++)所支持的扩展的关键字 。但是dllexport和dllimport关键字不能被自身所使用,因此它的前面必须有另一个扩展关键字__declspec 。通用格式如下:__declspec(specifier)其中specifier是存储类标示符 。对于DLL , specifier将是dllexport和dllimport 。而且为了简化说明导入和导出函数的语句 , 用一个宏名来代替__declspec.在此程序中 , 使用的是DllExport 。如果用户的DLL被编译成一个C++程序 , 而且希望C程序也能使用它,就需要增加“C”的连接说明 。#define DllExport extern "C"__declspec(dllexport),这样就避免了标准C++命名损坏 。(当然,如果读者正在编译的是C程序,就不要加入extern “C”,因为不需要它 , 而且编译器也不接受它) 。有了宏定义,现在就可以用一个简单的语句就可以导出函数了,比如:
DllExport LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam, LPARAM lParam );DllExport void InstallHook(int nCode);DllExport void EndHook(void);
第一个#pragma 语句创造数据段,这里命名为hookdata 。其实也可以命名为您喜欢的任意的一个名称 。#pragma 语句之后的所有初始化的变量都进入hookdata段中 。第二个#pragma语句是数据段的结束标志 。对变量进行专门的初始化是很重要的,否则编译程序将把它们放在普通的未初始化的段中而不是放在hookdata中 。
但是链接程序必须直到有一个hookdata段 。我们可以在Project Setting(vc6.0) 对话框中选择Link选项,选中HOOKDLL时在Project Options域(在Release 和Debug配置中均可),包含下面的连接语句:/SECTION:hookdata,RWS字母RWS是表明该段具有读、写、和共享属性 。当然,您也可以直接用DLL源代码指定链接程序就像HOOKDLL.c那样:#pragma comment(linker,"/SECTION:hookdata,RWS") 。
由于有些DLL需要特殊的启动和终止代码 。为此,所有的DLL都有一个名为DllMain()的函数 , 当初始化或终止DLL时调用该函数 。一般在动态连结库的资源文件中定义此函数 。不过如果没有定义它,则编译器会自动提供缺省的形式 。
原型为:BOOL WINAPI DllMain(HINSTANCE hInstance,ULONG What,LPVOID NotUsed)
参数:
hInstance:DLL实例句柄
What:指定所发生的操作
NotUsed:保留参数
其中What的值可以为以下值:
DLL_PROCESS_ATTACH:进程开始使用DLL
DLL_PROCESS_DETACH:进程正在释放DLL
DLL_THREAD_ATTACH:进程已创建一个新的线程
DLL_THREAD_DETACH:进程已舍弃了一个线程
总的来说,无论何时调用DllMain()函数,都必须根据What的内容来采取适当的动作 。这种适当的动作可以什么都不做,但不是返回非零值 。
DllMain()接下来的便是设置钩子,键盘处理,和释放钩子 。
2:建立头文件
正如应用程序所使用的其它任何库函数一样,程序也必须包含dll内的函数的原型 。所有得Windows程序都必须包含windows.h的原因 。所以我们现在建立一个头文件hookdll.h如下:
#define DllImport extern"C"__declspec(dllimport)
DllImport void InstallHook(int nCode);
DllImport LRESULT CALLBACK KeyBoardProc (int nCode,WPARAM wParam, LPARAM lParam );
DllImport void EndHook(void);
使用dllimport主要是为了使代码更高效 , 因此推荐使用它 。但是在导入数据时是需要dllimport的 。当完成了上面的程序后 , 建一个项目工程 , 不妨为hookdll,然后将hookdll.c插入导项目工程中,编译,则可以生成了hookdll.dll和hookdll.lib 。

推荐阅读