屏幕外出现的Windows(Delphi)

4
我的应用程序中的窗口弹出屏幕边缘,这当然是个问题,因为一些窗口是模态的,不能关闭(你甚至不知道它们在那里)。
我使用TurboPower Orpheus组件来记住每个表单的位置和大小,在表单再次显示时恢复它。它将大小和位置保存在INI文件中。
有什么办法可以防止窗口从屏幕边缘弹出?

Alt+Space,M,箭头键。(M表示移动。我从未使用过英语Windows,所以我不确定这是否是正确的热键。) - Andreas Rejbrand
@Andreas Rejbrand - 如果只有我遇到这个问题,那可能会起作用,但我不能要求用户知道或经历多个键盘组合。还是谢谢你的建议,将来对我可能会有帮助。 - Daisetsu
当然。我只是这样写是为了防止你不知道它。这将有助于调试,即使没有其他的... - Andreas Rejbrand
@Andreas - 提醒一下,是的,在英语版Windows中,“M”是移动任务的适当键。 - Scott W
3个回答

9
如果您使用多个显示器并断开其中一个,例如从笔记本电脑中拆卸,则此类问题很常见。或者如果将笔记本电脑连接到具有更高分辨率的屏幕上。或者使用远程桌面等。 解决方法是通过健全检查来覆盖“记住我的位置”行为,以查看左侧+宽度是否超过屏幕(实际上是Screen.Monitors数组 - 感谢各位),反之亦然,对于顶部+高度也是如此。
理想情况下,您可以通过减去差异来“碰撞”,从而使窗口紧贴着要跨越的边缘。
此外,请查看Orpheus的更新是否修复了此问题。如果没有,您可以获取源代码,进行更正(可选),并将其贡献回项目中。据我所知,这是OSS。

2
@Daisetsu:即使有超过2个显示器,这也并不复杂。我的做法是:1)遍历所有当前连接的监视器,以查看要放置窗口的中心点是否在其中一个监视器的区域内。如果是这样,窗口的坐标可以调整,以便它不会与监视器边界相交(尽管这不是最优的,因为用户可能故意将窗口部分移出屏幕)。2)如果第1步失败,则将窗口放置在其中心距离要放置窗口的中心最近的监视器上。 - mghie
1
@Daisetsu,处理多个显示器并不难:看一下Screen.Monitors和Screen.MonitorFromPoint;每个TMonitor对象都有一个“WorkareaRect”属性可供使用。 - Cosmin Prund
1
@Chris Thornton:自 Delphi 4 开始,“屏幕”的宽度和高度已经不再有意义了, Monitors 数组(以及它们各自的坐标)是唯一重要的。除此之外,我同意你的回答,加一! - mghie
2
@mghie - 你说得对,谢谢。这也提醒我要提到,现在不再可以使用poDesktopCenter来设置初始窗体位置了,因为它会在多个显示器之间分割。有点离题了,但在这里值得一提。 - Chris Thornton
不是验证位置,而是使用将表单位置+大小存储在注册表分支中的系统,该分支包括完整的桌面大小(即CONFIG.1920x1080和CONFIG.3840x1080)。这样,用户还可以根据当前屏幕分辨率在对话框位置(和大小)之间具有不同的设置,例如单个监视器和双(或三)监视器的不同设置。 - HeartWare
显示剩余2条评论

2

为了在表单出现在不再可用的区域(因为屏幕被拔出或分辨率变化)时,召回表单之前的位置,只需调用以下代码:

TForm.MakeFullyVisible;

就是这样。请参阅文档


太棒了!这帮助了我。 - Lars

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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接