丢掉的LBUTTONDOWN - ocx消息处理 和 AfxGetApp的使用注意

来源:互联网 发布:怎么测试80端口 编辑:程序博客网 时间:2024/06/07 00:34
        近日在做的一个MFC项目,需要做一个类似于word2007里面鼠标选中文本后的出现浮动工具条的功能,经过分析后,决定将该模块封装进一个已有的ocx中。实现的方式是创建一个操作方式类似于CTooltipCtrl的CWnd对象,然后在该对象上通过添加button控件和自绘来达到效果,消息的处理也CTooltipCtrl的方式:鼠标放到某个文本区域上时,弹出该浮动窗体。

        方法确定后就是实现,实现的过程很顺利,一气呵成,界面也基本达到了预期的效果,正心里边美着边加最后的左键按下消息的时候,却发现该消息丢了,确切的说在浮动窗体的父类中没能截获(父类也是个自绘的CWnd的对象),然后跳到最外层OCX的PreTranslateMessage中也是没截获,感到很困惑,于是使用SPY++,定位到程序进行调试,发现只能截获到窗体激活的消息,居然真的没有鼠标按下的消息。。。

        既然SPY++不行,就只好想别的办法了,于是冷静一下去趟WC,在回来的路上还在想,根据以往的经验,这次肯定又是某处愚蠢的细节遗漏导致的。。。

        回来坐到座位上,重新翻看代码,突然想起 该ocx用到了一个进程内的消息钩子,为了解决ocx无法响应 PreTranslateMessage 而加的,是不是这里出问题了呢? 于是对该函数进行调试,发现在消息过滤前,也就是消息转发给 PreTranslateMessage前, LBUTTONDOWN可以响应,之后就不行了。 转发消息的时候是做了一些判断的,粗略看了一下,判断没问题,但是消息就是没过去,坑爹啊。。。

        接杯水发散一下思维:既然消息转发前好用,转发之后就没了,说明还是转发的时候出了问题,或者所转发的对象不对?? 突然想起该判断发消息的语句是: AfxGetApp()->PreTranslateMessage(lpMsg), 难道说 AfxGetApp() 不是当前ocx的对象??? 于是使用OutputDebugString输出了一下,果然! 其获取的根本就不是什么ocx对象,居然直接就是浮动窗体的对象! 之前我考虑到浮动窗体有爹的,既然都有爹,消息应该都从爹那来吧,于是乎,没在浮动窗体中加PreTranslateMessage消息,而是父类传递消息过来。。原来以为有爹就行了,现在看来光有爹也不稳妥。

查了一下MSDN中AfxGetApp的说明:

The pointer returned by this function can be used to access application information such as the main message-dispatch code or the topmost window.

原来指针指向了当前进程中的顶层窗口。

是不是说,AfxGetApp获取的就是当前进程的顶层窗体呢? 晚上会家验证一下 :P

        最后的解决办法就是直接在浮动窗体中添加PreTranslateMessage消息,响应鼠标按下事件。至于为什么使用spy也跟不到,是因为先执行的进程HOOK。
原创粉丝点击