郁闷的SetTimer和Dll写入式拷贝

      开始准备毕业设计了,我的题目是:实验室监控系统。听着名字很牛X,实际没什么,就是监控下学生有没正常上机(即有没有缺席早退之类的)。为监视学生是否早退决定hook鼠标,我的想法大致是这样的:一般情况下一定时间内学生们都会移动鼠标,我对鼠标消息进行hook,然后再MouseProc中设置定时,当然在规定时间只要有鼠标消息定时就会被重置。为了对这个路进行验证,我写了一个dll,代码如下:

头文件:


 

 

源文件:

 

 


编译完成后我又新建了一个MFC对话框程序进行测试,结果大失所望。整个程序要是没鼠标消息还只是按设置的时间弹头MessageBox,一旦有鼠标消息,哎,不得了,那个MessageBox就连续不停往外冒,结果怎样那得看有多少鼠标消息了。

      经过一番苦苦思索,最终将问题锁定在两个地方,第一个是SetTimer函数,第二个是g_hWnd这个全局变量。最后,问题也确实出在这两个地方。

      MSDN对SetTimer的第一个参数hWnd有这样一个描述:This window must be owned by the calling thread。意思是说这个窗口句柄必须属于调用线程。对于DLL,它本身就不属于某个线程,我个人的理解是:哪个线程调用dll,那么在调用那个时间内dll就属于哪个线程。这样的理解可能有些不对,但是针对我现在这个问题我觉得是这样的。第一个错误原因分析出来了,既然是这样那么当我hook到本窗体以外的鼠标消息是程序自然会出错。我的解决方法是,将SetTimer和TimerProc从dll中移到我的对话框程序中,在dll中的依然是对鼠标消息进行hook,在hook鼠标消息后使用SendMessage向我的对话框发送一个自定义消息,在这个消息的效应函数中再来SetTimer。重写了代码后测试,问题依然没有解决,MessageBox依然猖狂往外弹着。

      最后,焦点全部集中到g_hWnd这个全局变量。原来对于dll有一个写入式拷贝的机制,该机制是这样的:dll中的数据存放于不同的节中,对于像g_hWnd这样的变量当程序试图对他写入时,系统就会针对它和访问它的线程重新生成一个节,那么这个线程访问的就只是这个新生成的节,公共的节依然没变。对照我的程序,在SetMouseHook中写入g_hWnd时便生成了一个针对我的测试程序节,也就是说我传入的窗口句柄被保存到了一个我的测试程序私有的节当中,这样以来其它的线程便访问不到这个g_hWnd,错误就这样产生了。知道原因再要解决问题就变得不那么困难了,我的方案是为g_hwnd准备一个读写共享的节,实现方法如下:

  

         最后在测试一下,OK问题解决。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值