【问题标题】:Creating a new form with the same z-order as another form创建与另一个表单具有相同 z 顺序的新表单
【发布时间】:2009-07-17 14:00:43
【问题描述】:

Windows 窗体,.net 2.0

我的主应用程序线程有一个表单 (A)。我有一个后台线程,它通过计时器运行以确定是否发生了活动 - 当它发生时,它会导致主应用程序表单隐藏(使用 BeginInvoke),并在它自己的线程中创建一个新表单(B)(单独消息泵)。

两个线程的事情听起来很复杂,但不幸的是需要它。

新消息泵上的新表单显示在非最顶层表单的顶部(如您所料!)。但是,如果原始应用程序不在桌面上,这很烦人。

所以,我想在隐藏之前确定原始表单 (A) 的 z 顺序是什么;然后创建我的新表单 (B),镜像原始表单的 z 顺序。

有什么想法吗?

[如果表单 B 位于当前用户桌面(即非密码)上,这也有在屏幕保护程序上弹出表单 B 的副作用,如果我无法按照上面的方式修复它,我会想避免这种情况...]

【问题讨论】:

  • 我很想听听您将第二种形式放在自己的线程上的原因。我见过无数次开发人员确信他们需要“多线程”他们的表单,直到有人要求他们解释原因而他们不能。我并不是说没有理由这样做,但用户往往有错误的方法。
  • 主线程是一个复杂的 LOB 应用程序,它包含许多表单、子表单等。第二个线程是一个安全程序,它通过隐藏所有表单(包括当前对话框)来“锁定”主应用程序,它可以稍后恢复。其中一些表单是由不受我们控制的第三方库创建的。如果从设计的第一天起就存在安全要求,则可能不需要第二个应用程序泵,但这确实意味着锁“通用”足以处理第三方表单等
  • 您是否尝试过使用 .ShowDialog(Me) 或 .ShowDialog(this) 将对话框向前推进。将 ShowDialog 与对父级的引用一起使用将锁定父级表单,使其无法输入任何内容并阻止焦点。

标签: windows winforms


【解决方案1】:

我通过使用 Win32 GetWindow 函数来确定前一个窗口用于我的主窗体,从而解决了这个问题。然后,当我在第二个线程上创建新表单时,我可以使用 SetWindowPos 将 z 顺序设置为我在第一步中获得的值。

我还使用 nobugz 建议来确定应用程序是否是焦点应用程序,如果不是,我使用 ShowWithoutActivation 覆盖来确保我的新表单不会开始激活

【讨论】:

  • 似乎 nobugz 答案已被删除,所以这个答案没有多大帮助:-(
【解决方案2】:

AFAIK,您可以调用 Form.Activate() 将其置于最前面,但我不知道 WinForms 中的 Windows 级 z 顺序。在 Win32 中你可能会有更好的运气。

【讨论】:

  • 是的,我不想把它带到前面——这就是重点。我宁愿假设我需要从 Win32 调用/调用某些东西,但我不知道是什么......
猜你喜欢
  • 1970-01-01
  • 2011-08-19
  • 2021-12-16
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
相关资源
最近更新 更多