拦截窗口试图窃取全球对Windows的重点 [英] Intercepting a window's attempt to steal global focus on Windows

查看:165
本文介绍了拦截窗口试图窃取全球对Windows的重点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名开发人员,也是一位长期使用Windows的用户,对于尽可能方便地使用我的系统非常着迷。

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

惹恼我的事情是当windows偷窃的时候。例如,我可以运行某个程序的安装程序。当它工作时,我会切换到我的浏览器并浏览,也许在浏览器中输入一些文本到电子邮件中。然后突然,安装程序完成,其窗口窃取焦点。现在我正在编写一封电子邮件,所以我可能会按一个键绑定到该安装程序上的一个按钮,那么该按钮被调用,做一些我从来没有打算发生的行动!

这对我来说非常恼人,因为我使用了一个名为DexPot的多桌面程序,当一个窗口窃取焦点时,它也将自己带到我目前正在使用的桌面上,这可能真的很烦人,因为那样我就不得不把它放回原来的桌面。

我对这个问题的理想解决方案是如何工作的:每当一个窗口试图窃取焦点时,我们拦截这个问题,而不要让它泄漏。我们展示了一个类似于烤面包机的消息:Foobar安装程序需要关注焦点,按Win-Whatever切换到它。如果和当你按下组合键,它切换到窗口。

问题是:有没有简单的方法来调整Windows,使之发生?我对Windows编程知之甚少。我知道AHK,如果有可能的话,这将是伟大的。

解决方案

不,没有一个简单的添加此行为的方式,但Windows会自动尝试这样做。



从理论上讲,应用程序不能在主动使用其他应用程序时窃取前台。不幸的是,有些情况下,Windows无法区分应该改变前景和不必要的前景盗用的合法用户操作。窗口管理器通常会在Windows的每个新版本上都加紧一些孔,但是也需要确保应用程序在用户需要时能够到达前台,即使间接表达了这个愿望也是如此。

b
$ b

例如,当前前台进程启动的进程可以将窗口放到前台。这是必要的,以便当用户从资源管理器启动一个窗口新启动的进程可以打开它的主窗口。此权限只会持续到下一个用户输入,所以如果应用程序启动缓慢,并开始使用电子邮件应用程序可能会失去其前台权限,才可以使用它。



请参阅 SetForegroundWindow函数文档获取进程的需求列表,以便能够将窗口设置为前台。

还有一些应用程序专门使用这些要求窃取权限(通过加入前台队列或合成用户输入到自己),但我怀疑在你的安装程序的情况下,这是偶然。



我不确定究竟是什么但我怀疑问题来自安装程序作为服务运行,并意外地窃取前台权限,当它试图启动当前桌面上的应用程序。



这将是理论上的位置可以为外部进程挂钩到前台系统来覆盖这一点,并显示您的确认敬酒,但它会是棘手的要得到正确的,并将需要大量低水平的代码(我可能会开始一个 CbtHook )。在像AHK这样的脚本程序包中(假设你的意思是AutoHotKey)是不可能的,但是需要将本地C / C ++代码注入到每个正在运行的进程中。


I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.

Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.

The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!

This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.

How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.

The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.

解决方案

No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.

In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.

For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.

See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.

There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.

I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.

It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.

这篇关于拦截窗口试图窃取全球对Windows的重点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆