Delphi - Win7 窗口焦点问题
我通过 CreateProcess() 执行 exe 文件并通过 SetForegroundWindow() 设置前台进程。 但它在Win7中不起作用,所以我必须单击任务栏中的图标。
如何实现我想要的行为(即 Launch 和 BringToForeground)?
I execute exe file by CreateProcess() and set foreground process by SetForegroundWindow().
but it doesn't work in Win7 so I have to click icon in taskbar.
How can I implement the behaviour I want (which is to Launch and BringToForeground)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你甚至不应该尝试这样做。 SetForegroundWindow 中的更改是有意为之 - 它阻止了应用程序会窃取用户想要获得焦点的焦点。请参阅上面链接的备注部分。
Win7 可能不会让非管理用户更改所需的注册表设置,更不用说在不重新启动系统的情况下进行更改。
您应该只使用 FlashWindow 来获取正如微软建议的那样,引起用户的注意。任何坚持窃取我选择执行的操作焦点的应用程序都将被立即卸载。
You shouldn't even try to do this. The change in SetForegroundWindow was intentional - it prevents applications from stealing the focus from what the user wants to have focus. See the Remarks section of the link above.
Win7 probably won't let non-administrative users change the needed registry setting, much less do it without a restart of the system.
You should just use FlashWindow instead to get the user's attention, as Microsoft recommends. Any application that insists on stealing focus away from what I choose to do will be uninstalled immediately.
我打算在一段代码中发布一个链接(在评论中),我曾经必须应用该代码来解决我自己的问题。现在该链接已损坏,因此我在这里发布代码以了解其价值(它已在 Windows XP Pro SP2 和 Windows Server 2003 中进行了测试,但未在 Windows 7 中进行了测试) :
除了一个小注释“bingo”之外,我没有在函数中添加任何内容,它标记了实际带来所需效果的行。
为了让你们不要认为我在利用这个功能滥用用户体验,这里有一些解释。
该功能用于借助用户平板电脑上安装的 Citrix 软件远程调用的应用程序,并且该应用程序以全屏方式运行。典型的工作会话几乎完全由该应用程序组成(其他部分只是用户从未与之交互的系统组件)。
现在,我们应用程序的某些部分必须作为单独的小应用程序来实现,并且它们被设计为保留在所有其他窗口之上,直到关闭为止,就像模态窗口一样。有时它们会丢失 Z 顺序并隐藏在主应用程序的主窗口下,这对用户来说是一场彻底的灾难。在那里使用“最顶层”属性不是一个选择,因此我们必须找到一种方法来维持它们的 Z 顺序位置。所以我们使用了这个函数。
I was going to post a link (in a comment) to a piece of code that I once had to apply to solve a problem of my own. The link has turned out to be broken now, so I'm posting the code here for what it's worth (it has been tested in Windows XP Pro SP2 and Windows Server 2003, but not in Windows 7):
I didn't add anything to the function apart from a small comment 'bingo', which marks the line which actually brought about the desired effect.
Just so you guys didn't think I was abusing users' experience with this function, here's some explanation.
This function was used in an application that was called remotely with the help of Citrix software set up on users' Tablet PCs, and the application ran in full screen. A typical working session almost entirely consisted of that application (other parts were just system components which user never interacted with).
Now some parts of our application had to be implemented as separate small applications, and they were designed to stay on top of all other windows until closed, just like modal windows. Once in a while they used to lose their Z order and hide under the main application's main window, and that was a total disaster for users. Using the 'top-most' property wasn't an option there, so we had to find a way to sustain their Z-order positions. And so we used this function.
ForceForegroundWindow 在 Win10 中为我工作。但是,它不会激活外部程序。它只会使其可见并位于顶部。该程序也仅在调用自身时执行相同的操作。我假设如果它被激活,它也会为用户适当地设置焦点。
Rick
我找到了激活和设置焦点的解决方案...在“SetAppRestore”过程中,我使用“MainFrm.visible:= false”启动它。然后它转到 SwitchApp,并调用 ForceForegroundWindow。返回到“SetAppRestore”后,我插入了“MainFrm.visible:= true”。这触发应用程序变得活跃并关注定义的组件:DataPge.SetFocus。
我很抱歉没有将代码放在代码块中。我无法理解说明。所以我把它全部放在 2 ===== 条之间。
//==========================
//==================== ======
ForceForegroundWindow worked for me in Win10. However, it does not activate the external program. It only makes it visible and on top. The program also only does the same when calling itself. I am assuming that if it activated it would also setfocus appropriately for the user.
Rick
I found a resolution for activating and setting focus... In the "SetAppRestore" procedure I initiated it with "MainFrm.visible:= false". Then it goes to SwitchApp, and it calls ForceForegroundWindow. After it returns to "SetAppRestore", I inserted "MainFrm.visible:= true". This triggered the app to become active and have focus on defined component: DataPge.SetFocus.
I apologize for not placing the code in a code block. I couldn't understand the instructions. So I put it all between 2 ===== bars.
//==========================
//==========================