【发布时间】:2012-06-23 07:31:33
【问题描述】:
我的 Delphi-7 应用程序显示:
Screen.DesktopWidth
Screen.DesktopHeight
Screen.Monitors[0].Width
Screen.Monitors[0].Height
而且,如果选择了第二台显示器,还:
Screen.Monitors[1].Width
Screen.Monitors[1].Height
在我的 WinXP-Pro PC 上运行该应用程序后,我转到控制面板/显示/设置,然后更改第二台显示器的设置(添加或删除)。
然后我单击刷新按钮以显示 4 个(或 6 个)参数的新值,并且发生了一些意想不到的事情:Screen.DesktopWidth 和 Screen.DesktopHeight 显示正确的新值,但其他 2 个(或 4) 参数非常错误。
像 Screen.Monitors[0].Width = 5586935 一样,应该是 1680 。
在 Delphi 7 中使用 TScreen 是否有一些特殊规则?
【问题讨论】:
-
我无法模拟它,因为我有一台显示器和 Delphi 2009,但我想问题可能出在显示器列表刷新上(在 Delphi 2009 中,这是通过私有过程
Screen.GetMonitors完成的) .我猜您在重新启动应用程序时会得到正确的值,不是吗?如果我没记错的话,也许 Sertac 在某处写道,销毁Screen实例并重新创建它是安全的。如果是这样,那么下面应该会刷新这些数据Screen.Free; Screen := TScreen.Create(nil);,但是我真的不知道这个动作有多安全。 -
您是引用 TMonitor 实例 Screen.Monitors[0] 还是每次都获取 Screen.Monitors[0]?
-
@TLama “我猜你在重新启动应用程序时会得到正确的值,不是吗?”这是正确的 。当显示 4 个(或 6 个)参数的语句之前有一个 ShowMessage 语句时,我也会得到正确的值。
-
ShowMessage 将导致消息队列被抽出。但我不希望排队的消息在这里发挥作用。
-
那么我认为您的主监视器已经更改了它的句柄并且函数(内部调用
GetMonitorInfo)由于不是实际句柄而失败(并返回 random 值) .问题似乎在于监视器列表 (TScreen.FMonitors),它是 cached 并且不会更改(在任何时候?我必须看看...)。同时尝试检查Monitor.Width的值(之前没有Screen,只有Monitor.Width)。这应该顺便说一句。更新Screen.Monitors缓存列表,以防MonitorFromWindow调用获得的监视器不包含在该列表中。