WEB开发网
开发学院软件开发VC 《魔高一丈2.0》开发实例 阅读

《魔高一丈2.0》开发实例

 2006-07-19 11:35:31 来源:WEB开发网   
核心提示: 我前面讲过,系统通过调用放在DLL中的钩子回调函数来实现全局钩(钩取所有窗口的鼠标消息),《魔高一丈2.0》开发实例(4),操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去,也就是说,临了,希望大家能对我上文中含糊、混沌的地方提出批评指正,DLL函数中的代码所创建的

我前面讲过,系统通过调用放在DLL中的钩子回调函数来实现全局钩(钩取所有窗口的鼠标消息),操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。也就是说,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。“DLL在WIN32中什么都不拥有”——这句话很重要。比如我们在DLL里建立了一个变量a,而我们的这个DLL文件又被两个进程所调用,这两个进程的中都用到了a可这绝对是两个不同存储单元中存储的两个a,它们之间没有丝毫的联系。给其中一个赋值也绝对不会影响到另一个。而对于本程序的一些数据是需要在不同的进程中保持唯一的(也可以说是一致),比方说: HWND GlobalWndHandle[100]它是用来保存程序做了隐藏的窗口之句柄的数组。当程序运行,我在任意窗口A中同时按下了鼠标左、右键,由于设置了鼠标钩子,系统会调用DLL中的钩子处理函数截获消息并加以处理,即把目前的可见窗口隐藏并把窗口句柄保存到GlobalWndHandle[100]数组中以备将来显示之用。如果不把GlobalWndHandle[100]放到一个共享的数据段里,系统就会在目前我们截获鼠标消息的A窗口的进程的地址空间里开辟HWND GlobalWndHandle[100]来存储窗口句柄。这样对于其他进程就不能方便地得到这个进程存入GlobalWndHandle[100]数组的数据了。这时只能将GlobalWndHandle[100]等需要跨进程访问的变量数据放在一个共享的数据段里了。另外,需要特别注意——必须给这些变量赋初值(就象我在程序代码里傻呼呼地写了100个NULL一样。你可以不初始化这个数组试验一下,有助于你理解我上面的话),否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。

第4步:编译生成dll文件,并用MFC AppWizard(exe)建立一个基于对话框的项目,在里面添加一个名为“Mousehook.h”的头文件其内容与dll项目中的“Mousehook.h”文件一致,打开菜单的“Project Settings”对话框在“Link”选项标签的“Object/library modules”编辑框里填入Mousehook.lib(此文件是与dll一起生成的,当编译一个隐式调用dll的exe时,lib文件起到提供dll引出函数接口地址的作用,如果此路径设置不正确程序是无法进行连接的)文件的存放路径。这样就可以放心使用dll里定义的CMousehook类的成员了。如下:

1 在HideWindowDlg.h中加入#include "MouseHook.h"并在CHideWindowDlg中定义一个CMousehook类对象hook。

2 在CHideWindowDlg::OnInitDialog()函数中加入hook.starthook()并初始化相关变量,这样当对话框初始时就会启动鼠标钩子。

3 在CHideWindowDlg::~CHideWindowDlg()函数中加入hook.stophook()。用以释放对话框对象时解除鼠标钩。

为了不忽略读者的智力水平我只对主要的代码进行了说明,其余有关托盘、Check控件的部分代码都比较传统也没什么好说明的。最后,编译成exe文件以后还须把Mousehook.dll文件拷贝到同exe相同的目录下才能正确运行exe。

临了,希望大家能对我上文中含糊、混沌的地方提出批评指正,也欢迎大家来信(me@sanlian.com.cn)切磋。

上一页  1 2 3 4 

Tags:魔高一丈 开发实例

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接