前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >锁屏的一个有趣的问题:HWND_TOP 与 HWND_TOPMOST 漫谈

锁屏的一个有趣的问题:HWND_TOP 与 HWND_TOPMOST 漫谈

作者头像
战神伽罗
发布2020-05-21 00:20:43
1.4K0
发布2020-05-21 00:20:43
举报

一、引言

今天遇到了一个非常有趣的问题,问题背景是一个用户反馈了这么一个问题:

当软件已经被锁屏了: 1. 用户点击出一个窗口显示(这是一个真窗口) 2. 此时用户再通过停靠在侧边的 QQ 界面,仍然可以通过点击里面的 QQ空间 图标点开网页,从而进入浏览器界面

根据我们软件的需求,进入了锁屏界面,就不应该再能让用户进入其他软件界面了才对。

那么,这个问题究竟是什么原因呢?

是什么原因引起的,我们的锁屏机制就那么简单的被破解了吗? 二、探索:WS_EX_NOACTIVATE

猜测1:是否是新建的窗口夺取了主窗口的输入焦点,而导致主窗口被夺取了焦点,然后丧失了锁屏功能呢?

这里,我经过 CreateWindow() 传入了 WS_EX_NOACTIVATE 参数创建了非激活窗口(类似我们的输入法的候选窗口),经过测试,这个方法并没有解决问题。

结论:这个问题与新建的窗口是否获取焦点或者激活没有关系。 三、探索:SWP_NOACTIVATE

猜测2: 是否可以通过 SetWindowPos 函数设置属性 SWP_NOACTIVATE 不激活窗口来解决问题呢?

这里,我抱着估计也不行的想法还是厚着脸皮去试了下,仍然还是不行。

结论:这个问题绝对与新建的窗口是否获取焦点没有关系。 四、探索:锁屏机制

猜测3: 是否与锁屏机制有关?

这里,我去看了看锁屏实现的那个类,顺便说下,这个类的注释非常有趣:

//////////////////////////////////////////////////////////////// // MSDN Magazine -- September 2002 // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. // Compiles with Visual Studio 6.0 and Visual Studio .NET on Windows XP. //

1 2 3 4 5 6

哈哈哈

不过问题还是要解决,通过查看代码,我发现锁屏机制的实现其实非常简单,通过注册表设置,将主窗口置顶锁住。

而触发锁屏破解的原因是什么呢?

是我们新建了一个窗口,这个窗口是拥有句柄的真实窗口,并且默认新建置顶。

注意了,这个新建窗口后的置顶操作,是导致锁屏失败的最重要原因,为什么呢?

想想,因为我们设置了主窗口为 HWND_TOP(也就是 z-order 上的最顶层窗口),而我们通过新建窗口,将主窗口的 z-order 向后移动了一位,也就是说此时最顶层窗口已经不是主窗口,而是新建的窗口了;然后新建的窗口并没有锁屏属性,因此 QQ界面 点击出 QQ空间 就可以呼叫浏览器打开网页了。

原因找到了,怎么解决呢?

很简单:

首先设置新建窗口的 z-order 为 HWND_TOPMOST(也就是所有非顶层窗口的最上面)

::SetWindowPos(newWindowHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

1

然后再设置主窗口的 z-order 为 HWND_TOP(也就是最顶层窗口)

::SetWindowPos(mainHWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

1

通过测试,修改后就没有问题了。

花了一个下午的时间,问题终于搞定了 _ 五、总结

锁屏机制的实现,是与最顶层窗口息息相关的,一旦最顶层窗口的 z-order 更改了,锁屏机制也就相当于被破解了。

这真是一个非常有趣的问题,从表入里分析问题,本身就是一件很快乐的事情 :)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档