【问题标题】:Windows appearing off edge of screen (Delphi)窗口出现在屏幕边缘(Delphi)
【发布时间】:2010-07-01 19:08:00
【问题描述】:

我的应用程序中的窗口从屏幕边缘弹出,这当然是个问题,因为有些窗口是模态的,无法关闭(你甚至不知道它们在那里)。

我正在使用 TurboPower Orpheus 组件,它会记住每个表单的位置和大小,然后在再次显示表单时恢复它。它将大小和位置保存在 INI 文件中。

我可以做些什么来防止窗口从屏幕的一侧显示出来?

【问题讨论】:

  • Alt+空格、M、箭头键。 (M 和 Move 一样。我从未使用过英文 Windows,所以我不确定这是否是正确的热键。)
  • @Andreas Rejbrand - 如果我是唯一一个遇到问题的人,这可能会起作用,但我不能要求用户知道这一点或通过多个组合键。仍然感谢您的想法,将来可能会对我有所帮助。
  • 当然。我只是这么写的,以防你不知道。如果不出意外,它将有助于调试...
  • @Andreas - 仅供参考,是的 M 是英语 Windows 中移动任务的适当键。

标签: delphi location screen turbopower


【解决方案1】:

如果您使用多台显示器然后断开其中一台显示器,这种情况很常见,例如在卸下笔记本电脑时。或者,如果您将笔记本电脑连接到分辨率更高的屏幕。或者使用远程桌面等。 补救措施是通过健全性检查覆盖“记住我的位置”行为,查看 left+width 是否超过屏幕宽度(Screen.Monitors 数组,实际上 - 谢谢大家),反之亦然 top+高度。

理想情况下,您通过减去差异来“碰撞”,因此您正在与窗口想要跨越的边缘对接。

另外,请查看 Orpheus 是否有修复此问题的更新。如果没有,您可以获取源代码,进行更正(可选)并将其贡献回项目。我记得是 OSS。

【讨论】:

  • 如果您要处理 2 个以上的显示器,此逻辑可能会变得非常复杂。我希望有一个组件或一些库可以处理这种类型的事情。如果需要,我可以自己写。
  • @Daisetsu:即使有 2 台以上的显示器,也没有那么复杂。我所做的是 1) 循环遍历所有当前连接的监视器,以查看要放置的窗口的中心点是否在其中一个监视器的区域内。如果是这样,则可以调整窗口的坐标,使其不与监视器边框相交(但这不是最佳选择,因为用户可能故意将窗口部分留在屏幕外)。 2) 如果 1) 失败,则将窗口放置在离要放置的窗口中心最近的监视器上。
  • @Daisetsu,处理多个监视器并没有那么糟糕:看看 Screen.Monitors 和 Screen.MonitorFromPoint;每个 TMonitor 对象都有一个可以使用的“WorkareaRect”属性。
  • @Chris Thornton:由于Delphi 4“屏幕”的宽度和高度不再有意义,Monitors 的数组(以及它们各自的坐标)是唯一重要的东西。除此之外,我同意你的回答,+1。​​
  • @mghie - 你是对的,谢谢。这提醒我要提一下,不再可以使用 poDesktopCenter 作为初始表单位置。它会在显示器之间分开。有点离题,但在这里值得一提。
【解决方案2】:

您可能想看看他们的DefaultMonitor 属性并阅读TCustomForm.SetWindowToMonitor 的代码以了解如何处理相对于Screen.Monitors 的定位。

Use DefaultMonitor to associate a form with a particular monitor in a multi-monitor application. The following table lists the possible values: 

Value        Meaning  
dmDesktop    No attempt is made to position the form on a specific monitor.   
dmPrimary    The form is positioned on the first monitor listed in the global screen object's Monitors property.   
dmMainForm   The form appears on the same monitor as the application's main form.   
dmActiveForm The form appears on the same monitor as the currently active form.   

Note: DefaultMonitor has no effect if the application does not have a main form.

【讨论】:

    【解决方案3】:

    要调用表单的先前位置,而不是突然将其置于不再可用的区域(由于屏幕堵塞或更改分辨率),您只需调用

    TForm.MakeFullyVisible;
    

    就是这样。请参阅documentation

    【讨论】:

    • 太棒了!这对我有帮助
    猜你喜欢
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多