【问题标题】:How to keep a child form on top of everything, but the parent doesn't have to be?如何将子表单保持在所有内容之上,但父表单不必如此?
【发布时间】:2015-11-09 03:20:04
【问题描述】:

我看到了一些与这个问题相似的帖子,但这有一个微妙的区别。我有一个程序,它的用户界面可以位于其他程序之后,但是它有一个显示在左上角显示结果的子窗体,这部分监视器被复制并显示给公众,它是一个“记分牌”。我希望这个“结果”表单位于所有内容之上(Taskmanager 可以,我可以忍受)。将运行的任何其他应用程序都不会尝试爬到顶部,例如“Word”、“IE”、“Excel”等。

如果我将父级“SetWindowPos”设置为“TopMost”,子级也设置为“TopMost”,我的两个窗口都在顶部,但是,用户界面表单也位于任何内容之上。如果用户需要启动另一个应用程序,我们的表单将位于它上方,使其他应用程序无法使用,但是,它将位于我们的结果表单下方。我们不能使用计时器将其移动到顶部,因为它会在计时器触发之前被覆盖,这是不允许发生的。

如果我只将结果表单设置为最顶部,它不会停留在所有内容的顶部。看来父母也必须是最顶层的?有没有办法解决这个问题,让孩子在上面,但它的父母可以坐在下面?还是父母必须在最顶层才能让孩子也处于最顶层?当我抓住移动事件并阻止它在孩子身上移动时,父母不能坐在孩子身上。

我在 Delphi 中编程,所以任何答案在 Delphi 中都是最好的,但任何更通用的都可以,我希望它无论如何都是对 Windows 的调用。

谢谢

【问题讨论】:

  • 将运行的任何其他应用程序都不会尝试爬到顶部 - 由于What if Two Programs did this - rule,您无法可靠地执行此操作
  • 感谢您的想法,正如我在 Tom 的帖子中所指出的那样,在对他的建议进行了一些测试后,情况确实如此。尽管“两个计划”实际上是我们的,但协调它们的“领先”地位需要更多的思考。

标签: windows delphi always-on-top stayontop


【解决方案1】:

如果我理解正确,您的程序有一个主表单 (MainForm) 和一个结果表单 (ResultsForm),可能还有其他一些表单,但它们应该“正常运行”。

MainForm 也应该正常运行,也就是说,如果其他应用程序被激活,则移动到后台,但 ResultsForm 应该始终位于所有其他表单之上,包括其他应用程序的那些。

以下内容仅在 Windows 7 中测试,因此可能适用于其他操作系统,也可能不适用于其他操作系统。我将在今天晚些时候使用 Windows 10 进行测试。

首先评论任何可能干扰的先前尝试。将MainForm.FormStyle 保留为默认fsNormal。将ResultsForm.FormStyle 设置为fsStayOnTop

然后将TApplicationEvents 添加到ResultsForm 并为OnDeactivate 添加事件处理程序:

procedure TResultsForm.ApplicationEvents1Deactivate(Sender: TObject);
begin
  SetForegroundWindow(Handle);
end;

ResultsForm 现在将位于其他窗口以及其他应用程序的顶部。

警告:如果您启动第二个实例(或者如果其他一些应用程序正在执行相同的操作),您最终会陷入应用程序争夺领先地位的循环。

【讨论】:

  • 是的,你的理解是正确的!我今天早上试过了,但意识到了一个我没有意识到的“问题”,就像你的警告一样。我们确实有其他可能正在战斗的应用程序。当得分时,例如。板球得分为 6,我们在结果表的顶部显示视频。所以我不得不让这个表格“更多”地出现在前面!但仍然将结果置于其他一切之上。视频结束后,其表单将关闭,结果需要再次“置顶”。所以“在上面”的处理看起来已经比我想象的要难了。
  • @Trevor Heh,我并不感到惊讶;)但好在只有您的应用程序可能会争夺屏幕,因此您可以创建一个禁用某些“onTop”的屏幕警察并允许另一个。要暂时禁用,只需将 OnDeactivate 事件设为 nil 并稍后再次重置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 2011-09-08
相关资源
最近更新 更多