【发布时间】:2014-05-17 18:59:51
【问题描述】:
首先,我知道这是一个有争议的讨论,但我希望我们可以保持技术性。
我有一个在后台启动的应用程序,我希望它能够激活/使窗口聚焦在不同的进程中。但是,即使我要激活其窗口的进程调用了 AllowSetForegroundWindow(ASFW_ANY),调用 SetForegroundWindow 总是会失败。
原因是(IMO)启动应用程序是后台进程,并且由于它没有收到输入,因此不允许设置前台窗口。所以一切都出现在任务列表中,但没有显示出来。
所以我尝试创建一个虚拟窗口来接收立即关闭的输入,之后能够成功调用 SetForegroundWindow。但即使是我显示的虚拟窗口也显示在背景中。
但是,如果我打电话
AttachThreadInput(
GetWindowThreadProcessId(GetForegroundWindow(), NULL),
GetCurrentThreadId(), TRUE);
在创建虚拟窗口之前,该窗口确实是在前台创建的,我可以之后在不同的进程中为不同的 HWND 调用 SetForegroundWindow。
但是:如果我不创建虚拟窗口,尽管我使用 AttachThreadInput,但 SetForegroundWindow 仍然返回零。
我不明白为什么如果我创建一个自己的窗口(然后为其他窗口成功),为什么 AttachThreadInput hack 会成功,但如果我不先创建自己的窗口则不成功。
我的后台进程如何在不同进程中的不同窗口上调用 SetForegroundWindow而不创建虚拟窗口?
[*] 后台应用程序实际上是 gpg-agent.exe,它在请求密码时调用 pinentry.exe(我的应用程序)。 pinentry.exe(作为后台进程运行)必须向另一个正在运行的应用程序请求密码,因此它必须将其窗口置于前台...
【问题讨论】:
-
不,在我看来不是,因为我不想创建自己的虚拟窗口。即使使用 AttachThreadInput,其他窗口/进程的 SetForegroundWindow 也不起作用;当我创建自己的(虚拟)窗口时,它可以工作。
-
你做不到。如果你没有有焦点,你就不能放弃它。正如雷蒙德所说,“你不能放弃不属于你的东西”。这是 Windows 中一个非常深思熟虑的设计决定。 blogs.msdn.com/b/oldnewthing/archive/2009/02/20/9435239.aspx
-
正如开头提到的,我希望我们可以保持这个讨论的技术性。所以在这种情况下,它必须是可能的,因为我的后台应用程序可以做它想做的任何事情(直到将自己注入到不同的进程中)。正如我所提到的:当我创建一个虚拟窗口时它也可以工作。问题是:什么是侵入性最小的方式?
-
什么是后台进程?
标签: winapi setforegroundwindow