Delphi XE4 - 获取窗体当前显示的监视器

3
在多显示器环境下,当关闭表单时,我希望能够获取当前显示器和活动显示器,以保存信息。在以后重新打开表单时,表单将显示在它上次显示的位置。当显示表单时,我会进行所有检查(如果监视器编号-i-存在等),如果一切正常,我将在正确的显示器(i)上显示表单。
Form1.BoundsRect := Screen.Monitors[i].BoundsRect;

我希望能够在Form1.onCloseQuery事件中获取当前显示表单的监视器和活动监视器,以便我可以将该信息保存在Ini、DB或其他地方,但似乎我找不到正确的方法来正确实现它。

有什么想法吗?


3
屏幕有'MonitorFromPoint'、'MonitorFromRect'和'MonitorFromWindow'函数。TForm类拥有'.Monitor'属性。 - Sertac Akyuz
1
我最近在博客上写了这个主题。我的代码完全符合您的要求。请参见http://francois-piette.blogspot.be/2014/03/persistent-form-with-f11-to-fullscreen.html。 - fpiette
1个回答

8
如果您想保存窗体的位置,可以使用屏幕坐标。请将信息保存在TForm.BoundsRect中,它给出了屏幕相关坐标。请注意,屏幕相关坐标包括所有连接到屏幕的监视器。
换句话说,您实际上不需要担心窗体位于哪个监视器上。例如,假设您有两个800x600的相邻监视器。屏幕坐标将是:
  • 对于左边的显示器,坐标为(0, 0, 800, 800)。
  • 对于右边的显示器,坐标为(800, 0, 1600, 800)。
在首次显示窗体时,最好检查窗体是否在屏幕边界内。也许当您记住其位置时,它在随后被移除的监视器上。或者,用户已重新配置其监视器以使先前的屏幕坐标无效。
要回答您的问题,请使用表单的Monitor属性查找与表单关联的监视器。这是通过调用Win32 API函数MonitorFromWindow来实现的,传递MONITOR_DEFAULTTONEAREST参数。

如果监视器被移除,那么我将把窗体定位在Monitor[0]的屏幕中央。但是,如果知道监视器编号、左侧和顶部坐标以及所有内容都正常(监视器存在、窗体尺寸和位置在边界内),则可以更轻松地相应地显示窗体。请问您能否提供一些代码示例来检索窗体的监视器编号? - Bashk
但这对你没有实际用处。如果你在窗体不在屏幕上时尝试它,它会给你一个AV。因为“Monitor”可能是“nil”。 - David Heffernan
1
你想要做的是测试 Form.Monitor 是否为 nil。如果是,那么你的窗体就在屏幕外。监视器编号在程序的每次运行中都不会保留其含义。一个明显的例子是:你的程序在第二个监视器上运行。程序关闭后,用户移除了第二个监视器。 - David Heffernan
你能给我一个样例代码吗?以正确和无病毒的方式实现。 - Bashk
我知道你所说的。我在谈论使用你提到的重叠方法来搜索表单监视器的正确方式。 - Bashk
显示剩余3条评论

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