1

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

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

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

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

谢谢

4

1 回答 1

2

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

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

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

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

然后添加一个TApplicationEventstoResultsForm并添加一个事件处理程序OnDeactivate

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

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

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

于 2015-11-09T11:18:29.090 回答