为什么我的 Windows 应用程序按照规则不应获得焦点?
到目前为止,每个为 Windows 编写内容的人可能都知道应用程序无法(正式)从前台进程窃取焦点,并且 为什么。但我只是无意中转移了注意力,而且不明白这怎么可能。
我有一个 Delphi 应用程序,用户可以使用热键(或通过单击鼠标,或通过 Alt+Tab)调出,选择一段文本并按 Enter 键。然后,我的应用程序最小化(甚至隐藏到托盘),并将用户刚刚选择的文本粘贴到活动窗口中。这里没有什么新东西,有很多类似的项目 - 剪贴板扩展程序、术语表、宏程序等。
令我困惑的是,在完成上述所有操作然后休眠 1500 毫秒后,我恢复了我的主窗体并它重新获得焦点!它成为前台窗口,即使它不是 1500 毫秒前(已测试;Windows 7 32 位)。
事实上,我根本不想要这个,所以在恢复我的主窗体之前,我记录了哪个窗口有前景,并在将其交给我后将其返回给该窗口。我只是好奇为什么我的应用程序会出现在前台,而按照规则它不应该出现在前台。也许我并不像我想象的那样完全理解规则?
By now everyone writing for Windows probably knows that applications cannot (officially) steal focus from foreground processes, and why. But I have just managed to steal focus, inadvertently, and don't understand how this is even possible.
I have a Delphi app that user brings up with a hotkey (or by a mouse click, or by Alt+Tab), selects a piece of text and hits Enter. My app then minimizes (hides to the tray, even), and pastes the text user just selected into the active window. Nothing new here, plenty of similar projects out there - clipboard extenders, glossaries, macro programs, etc.
What is puzzling to me is that after doing all the above and then sleeping for 1500 ms, I restore my main form and it gets the focus back! It becomes the foreground window, even though it wasn't 1500 ms ago (tested; Windows 7 32-bit.).
In fact, I don't want this at all, so before restoring my main form I record which window has foreground and I give it back to that window after it's been given to me. I'm just curious why my app gets to be in the foreground when by rules it should not. Maybe I don't understand the rules as fully as I thought I did?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您查看 的文档SetForegroundWindow 您会看到调用成功的条件列表,其中之一是“进程收到最后一个输入事件”。因此,如果用户在您的应用程序中按 Enter 键后没有执行任何操作,您仍然有权窃取焦点。我不知道当窗口恢复时 Delphi 是否为您调用 SetForegroundWindow,但这可能值得研究。
我不知道如何恢复窗口,但将
SW_SHOWNOACTIVATE
与ShowWindow
一起使用可能会有所帮助...If you look at the documentation for SetForegroundWindow you see a list of conditions for the call to succeed, one of them is "The process received the last input event." So if the user does not do anything after pressing enter in your app you still have the right to steal focus. I don't know if Delphi calls SetForegroundWindow for you when the window is restored but it might be something to look into.
I don't know how you restore your window but using
SW_SHOWNOACTIVATE
withShowWindow
might help...