windows - 拦截窗口试图窃取 Windows 的全局焦点

标签 windows keyboard focus usability

我是一名开发人员和长期的 Windows 用户,痴迷于让我的系统尽可能方便使用。

昨天,我想到了一些在 Windows 中一直让我烦恼并且我认为是理所当然的事情,我意识到我对它的工作原理有了更好的想法,我现在想知道是否可以调整Windows 那样工作。

令我烦恼的是 Windows 窃取焦点。例如,我可能正在运行某个程序的安装程序。当它工作时,我将切换到我的浏览器并浏览,也许在我的浏览器中将一些文本输入到电子邮件中。然后安装程序突然结束并且它的窗口窃取了焦点。现在我正在写一封电子邮件,所以我可能会按下一个恰好绑定(bind)到该安装程序上的按钮的键,并且然后该按钮被调用,执行一些我从未打算发生的操作!

这对我来说是双重烦人的,因为我正在使用一个名为 DexPot 的多桌面程序,当一个窗口窃取焦点时,它也会将自己带到我当前所在的桌面,这真的很烦人,因为我必须将它放回原来的桌面。

我对这个问题的理想解决方案是如何工作的: 每次窗口试图窃取焦点时,我们都会拦截它,不让它发生。我们显示类似 toastr 的消息,说“Foobar 安装程序需要焦点,按 Win-Whatever 切换到它”。如果当您按下组合键时,它会切换到窗口。

问题是:是否有一种简单的方法可以调整 Windows 来实现这一点?我对 Windows 编程知之甚少。我确实知道 AHK,如果可能的话,那就太好了。

最佳答案

不,没有简单的方法来添加此行为,但 Windows 会尝试自动执行此操作。

理论上,当您正在使用另一个应用程序时,应用程序不应该能够窃取前台。不幸的是,在某些情况下,Windows 无法区分应该更改前台的合法用户操作与不需要的前台窃取行为之间的区别。窗口管理器通常会在每个新版本的 Windows 中稍微收紧漏洞,但也需要确保应用程序可以在用户需要时进入前台,即使这种愿望是间接表达的。

比如当前前台进程启动的进程可以把一个窗口放到前台。这是必要的,以便当用户从资源管理器启动窗口时,新启动的进程可以打开其主窗口。此权限仅持续到下一次用户输入,因此如果应用程序启动缓慢并且您开始处理电子邮件,该应用程序可能会在使用它们之前失去其前台权限。

参见 SetForegroundWindow function一个进程能够将窗口设置到前台的要求列表的文档。

还有一些应用程序专门利用这些要求来窃取权限(通过加入前台队列或将用户输入合成给自己),但我怀疑在您的安装程序场景中这是偶然的。

我不确定到底发生了什么,但我怀疑问题出在作为服务运行的安装程序,并且当它尝试在您当前的桌面上启动应用程序时意外窃取了前台权限。

从理论上讲,外部进程可以连接到前台系统以覆盖它并显示您的确认消息,但要做到这一点会很棘手,并且需要大量的低级代码(我可能会从CbtHook)。这在像 AHK 这样的脚本包中是不可能的(假设您指的是 AutoHotKey),但需要将 native C/C++ 代码注入(inject)到每个正在运行的进程中。

关于windows - 拦截窗口试图窃取 Windows 的全局焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26323767/

相关文章:

objective-c - 如何手动启用或禁用键盘上的返回键?

python - wxPython 对话框 : "Enter" keyboard button would not "ok" the dialog

android - 停止 dpad 焦点超出 android 中的当前 fragment

c# - WPF 的 IsKeyboardFocusWithin 属性的 UWP 替代方案

不同浏览器上的 Javascript/Flash 焦点问题

c - 我如何知道在 Linux 上编写的 C 程序是否可以在其他地方运行

windows - 有没有办法直接查询文件系统设备驱动程序以列出目录中的文件?

android - 键盘隐藏时显示 View ,反之亦然

c - Windows 和 Linux 中 printf 的区别

windows - Windows 上 Matlab 64 位版本的免费 SCM