开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 6341|回复: 25
打印 上一主题 下一主题
收起左侧

[闲聊] 关于 窗口_屏蔽浏览器右键bug之所见

[复制链接]

结帖率:100% (1/1)
跳转到指定楼层
发表于 2016-10-19 01:56:49 | 只看该作者 回帖奖励 |正序浏览 |阅读模式   云南省昆明市
起因:[bug反馈]贴子 窗口_屏蔽浏览器右键存在一个bug:二次打开窗口会失效http://125.confly.eu.org/forum.php?mod=viewthread&tid=13948471
模块版本:精易模块v5.36
相关源码:见附件图片
实现原理分析:
    使用SetWindowLong修改窗口过程,用精易模块自定义的消息处理子程序接管原窗口消息处理。
    LONG SetWindowLong( HWND hWnd, int nlndex, LONG dwNewLong);
     参数:
         第一个参数:要控制(修改)的窗口句柄
         第二个参数:要修改类型索引,其中-4=GWL_WNDPROC,表示修改窗口过程
         第三个参数:新值,第二个参数-4时表示新窗口过程的地址
    返回值:
        如成功,返回窗口原类型的值,在此返回的是窗口原来的消息处理程序的地址
1、先粗略分析源码:

这个是精易接管的消息处理函数:

由此可看出,窗口_屏蔽浏览器右键 子程序主要完成狸猫换太子工作,将原窗口过程替换为精易的处理过程
精易的处理过程则拦截鼠标右键消息,发生该消息时执行 窗口_屏蔽浏览器右键 指定的处理程序,在此用空参数则什么也不会做,达到拦截原弹出右键菜单的目的,除鼠标右键外的消息则转 集_浏览框窗口程序 进行处理,它是原窗口过程的处理地址,所以,其它消息不会受影响。
2、窗口_屏蔽浏览器右键  中的“如果真 (a = 0)”和 “a = 浏览器句柄” 是干嘛用的
    细心的你或许发现了,为什么这两句没注释?我的解释是:它是为防止二次修改的,注意到a是静态变量,第一次运行它的值是0,所以顺利的进行了修改,并最后运行 a = 浏览器句柄 语句,此时a 值已非0。
    第二次再运行 窗口_屏蔽浏览器右键 子程序,由于a值不为0,所以直接跳过,不作任何修改
    为什么不嵌套多个消息处理链,我的看法是模块设计者认为没必要实现复杂的消息链,假如调用两次即有两个消息处理程序,没必要实现先传到第二个处理程序处理,再传到第一个消息处理程序处理,再传到原生消息处理程序进行处理(针对的是非右键消息的情况,如果是右键消息,可能在第二个或第一个处理程序就处理了)
3、回过头来,我们看看bug贴反馈的是什么情况:
       6、BUG描述:在下面我上传的例程中,这个命令无效。在另外写的例子中,我发现存在这样一个问题:就是第一次载入带浏览框的子窗口,屏蔽右键有效。关闭这个子窗口后,再次打开,屏蔽右键命令就失效了。
   说明:楼主代码已下载,命令无效我倒没发现,win7 64位。win10没测试不予评说。
    第二个问题是第一次载入子窗口有效,关闭子窗口再次打开就无效了。
    根据前面的代码解读,我们知道,静态变量a的值最初为0,第一次载入子窗口执行一次 窗口_屏蔽浏览器右键 后该值变为非0。关闭子窗口,静态变量内存不会回收,再打开子窗口还是原非0值,这样,第二次打开子窗口时 浏览器"已就绪"事件下的 窗口_屏蔽浏览器右键 就不起效果了直接返回了。
    或许有人会问:刚才不是注册过了吗,又没关闭主窗口。
    请注意一个事实,窗口关闭会销毁的,窗口销毁后会清理资源,一切设置将不复存在(举个易懂的例子:假如浏览框不在子窗口,而在主窗口,我们不在事件中控制,而用按钮手动控制,即按下 设置 按钮后屏蔽右键。那么第一次打开并按下设置按钮后生效,不再弹出右键菜单,那我们关闭程序重新打开,此时不按设置按钮还会保存以前的状态吗?当然不会,我们没有在程序关闭时保存状态,没有在程序启动时恢复状态)
4、问题解决
    既然知道是因为静态变量a非0造成第二次设置被忽略的原因,那我们删掉那句判断语句不就成了?
    不行,刚才已经说了,我觉得模块设计者认为没必要实现多级消息,万一第一个右键处理消息是弹出“文件”菜单,第二个消息处理是弹出“编辑”菜单,点击个右键弹出两次菜单不就乱套了。
    那么,怎么办呢?
    我的处理办法是:既然是因静态变量a值在窗口关闭后不为0,阻碍了第二次的操作,那我们让第二次打开子窗口前这个a值为0不就OK了?
    聪明的你或者已经想到办法了:在子窗口第一次关闭时就把a值清0
    在哪清0,当然是在WM_DESTROY消息里。
    问题来了,我们怎么拦截子窗口,即浏览器所在窗口的消息,感觉还有点麻烦。
    不用急,没见我们拦截了浏览器窗口的消息处理程序了吗?就在这拦截,,,,,,子窗口的事没干完,主窗口不会急着退出的
    (1)首先,我们需要把这个a值由子程序的静态变量变为程序集变量或全局变量,以便使我们在消息处理函数“浏览器屏蔽右键消息处理”里能够引用并清0,这里我删除掉了静态子程序变量a,在程序集里建立了一个同类型的程序集变量 集_浏览器窗口句柄
    (2)相应修改原窗口_屏蔽浏览器右键的代码:

    (3)修改精易的消息代管程序

注意到了没有,我们其它的没变,就是在前面加了两条语句:
  1. <code class="cpp plain"><code class="cpp plain"></code><div class="blockcode"><blockquote><p>.版本 2

  2. .如果真 (消息 = 2)  ' WM_DESTROY
  3.     集_浏览器窗口句柄 = 0</p><p>消息=2即拦截WM_DESTROY消息,当子窗口关闭时会逐一通知他下面的子窗口,浏览器子窗口接到通知就会执行下面的代码:</p><p>    集_浏览器窗口句柄 = 0</p><p>这样就把原来的a值清0了,下次再载入子窗口就不再被忽视,还会得以执行,所以右键屏蔽就会实现。</p><p> </p><p>太晚了,没法再检查有无错误了,如有错误请不吝指正。</p>
复制代码




   
   
      

我的修改.rar

914.06 KB, 下载次数: 59, 下载积分: 精币 -2 枚

评分

参与人数 4好评 +2 精币 +12 收起 理由
萧阳天 -1 + 3 感谢发布原创作品,精易因你更精彩!
莱美影像 + 1 + 2 感谢分享,很给力!~
铅笔刀 + 1 + 2 666666
冰点 + 1 + 5 共同努力,共同进步

查看全部评分

24
发表于 2017-12-24 20:04:34 | 只看该作者   山西省太原市
kkkkkkkkkkkkkkkkkkkkkk
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
23
 楼主| 发表于 2016-10-24 14:35:21 | 只看该作者   云南省昆明市
莱美影像 发表于 2016-10-24 10:31
使用这个命令,在易语言里调试我的代码时,发现有一半的几率会出现:带浏览框的子窗口关闭后,程序崩溃。 ...

那你换精易模块自带的看是否出现这问题
现在忙别的事了,没时间去看
回复 支持 反对

使用道具 举报

结帖率:74% (17/23)
22
发表于 2016-10-24 10:31:00 | 只看该作者   河南省郑州市
yelaizuozuo 发表于 2016-10-21 16:12
提示“浏览器句柄无效”说明浏览器窗口没创建完成,这就是你放在启动完成事件的结果

使用这个命令,在易语言里调试我的代码时,发现有一半的几率会出现:带浏览框的子窗口关闭后,程序崩溃。子窗口上只有一个浏览框组件。
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
21
 楼主| 发表于 2016-10-21 16:12:07 | 只看该作者   云南省昆明市
莱美影像 发表于 2016-10-21 15:55
测试中遇到另外一个问题:就是不知道什么原因,弹出提示“浏览器句柄无效”,点确定按钮后,就弹出了窗 ...

提示“浏览器句柄无效”说明浏览器窗口没创建完成,这就是你放在启动完成事件的结果
回复 支持 反对

使用道具 举报

结帖率:74% (17/23)
20
发表于 2016-10-21 15:55:27 | 只看该作者   河南省郑州市
本帖最后由 莱美影像 于 2016-10-21 15:58 编辑
yelaizuozuo 发表于 2016-10-21 15:46
虚拟机测试没有你说的问题


测试中遇到另外一个问题:就是不知道什么原因,弹出提示“浏览器句柄无效”,点确定按钮后,就弹出了窗口,这是屏蔽右键命令失效了。像这种情况,应该销毁浏览器吧!

建议,窗口_屏蔽浏览器右键的返回值,可以设置为逻辑型。这样就可以根据结果,判断是否屏蔽成功了。
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
19
 楼主| 发表于 2016-10-21 15:46:13 | 只看该作者   云南省昆明市
莱美影像 发表于 2016-10-21 14:51
请楼主指正一下,这个屏蔽浏览框命令,到底是放在就绪事件下,还是放在窗口创建完毕事件下呢?
使用“改 ...

虚拟机测试没有你说的问题

QQ截图20161021154352.png (78.67 KB, 下载次数: 0)

QQ截图20161021154352.png
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
18
 楼主| 发表于 2016-10-21 15:25:00 | 只看该作者   云南省昆明市
莱美影像 发表于 2016-10-21 14:12
顶楼的例子,我测试了。貌似屏蔽命令,应该放在窗口创建完毕子程序里。精易模块里的注释是,放在浏览器就绪 ...

1、放在浏览器就绪子程序里
2、二次载入子窗口,子窗口关闭后崩溃,我在win10 64位虚拟机上测试没遇到
3、调用 改进意见 模块,静态编译后丢虚拟机测试,结果正常(命令放就绪事件,屏蔽成功)

QQ截图20161021152245.png (76.45 KB, 下载次数: 0)

屏蔽右键成功

屏蔽右键成功

QQ截图20161021152308.png (72.21 KB, 下载次数: 0)

关闭子窗口未崩溃

关闭子窗口未崩溃
回复 支持 反对

使用道具 举报

结帖率:74% (17/23)
17
发表于 2016-10-21 14:51:31 | 只看该作者   河南省郑州市
yelaizuozuo 发表于 2016-10-21 13:24
这个是我的修改意见,请指正
@萧阳天
@冰点

请楼主指正一下,这个屏蔽浏览框命令,到底是放在就绪事件下,还是放在窗口创建完毕事件下呢?
使用“改正意见”下的代码,我放在窗口创建完毕事件下,多次打开窗口测试。暂时还没有发现窗口崩溃的情况。还有待继续观察。如果有问题,我会在此帖回复的。谢谢!
回复 支持 反对

使用道具 举报

结帖率:74% (17/23)
16
发表于 2016-10-21 14:12:21 | 只看该作者   河南省郑州市
本帖最后由 莱美影像 于 2016-10-21 14:27 编辑

顶楼的例子,我测试了。貌似屏蔽命令,应该放在窗口创建完毕子程序里。精易模块里的注释是,放在浏览器就绪子程序里。我放在就绪里是无效的。另外测试中,发现二次载如子窗口,子窗口关闭后会崩溃。不知道是我的原因,还是模块命令的原因。

下面的例子,调用了“改进意见”里面的源码编译的模块:
在我的win10 64下测试,命令无效(命令放在就绪事件里无效,放在窗口创建完毕事件里有效)。
屏蔽右键.zip (201.15 KB, 下载次数: 9)


回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
15
 楼主| 发表于 2016-10-21 13:28:41 | 只看该作者   云南省昆明市
本帖最后由 yelaizuozuo 于 2016-10-21 13:31 编辑
萧阳天 发表于 2016-10-20 21:39
不好意思,好评点错了,我给你补回来

@冰点
@萧阳天
怎么@不了,重来
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:[email protected]
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表