However, one of the things I discovered today is that some of my applications don't respect the second monitor. For example, I have a class called SFPersistentForm that I drop on most of my forms. It saves the form size and position when the form is closed and restores it when the form is reopened, giving the user the experience they expect when working with that form. However, I discovered that if I opened a form and moved it to the second monitor then closed it, when I reopened it, the form displayed on the primary monitor instead (this was a form with Desktop set to .T. so it can exist outside the application's window).
I quickly found out why: the persistence code was trying to prevent the situation where the form may open outside the screen boundaries, making it invisible. The following code handled that:
Thisform.Width = min(max(Thisform.Width, 0, Thisform.MinWidth), ;("- 50" is used to ensure the form doesn't start at exactly the right or bottom boundaries of the monitor, making it essentially invisible.)
_screen.Width)
Thisform.Height = min(max(Thisform.Height, 0, Thisform.MinHeight), ;
_screen.Height)
Thisform.Left = min(max(Thisform.Left, 0), _screen.Width - 50)
Thisform.Top = min(max(Thisform.Top, 0), _screen.Height - 50)
There are actually two problems with this code. First, the reliance on _SCREEN assumed the form exists within _SCREEN; with a top-level form or one with Desktop set to .T., that's not necessarily the case. Second, even if _SCREEN is maximized, that only fits it in the current monitor. If the form is on the other monitor, _SCREEN's dimension are irrelevant.
I initially changed the code to:
if Thisform.Desktop or Thisform.ShowWindow = 2However, it turns out that SYSMETRIC() only returns values for the primary monitor. So, I changed those two statements to:
lnWidth = sysmetric(1)
lnHeight = sysmetric(2)
else
lnWidth = _screen.Width
lnHeight = _screen.Height
endif Thisform.Desktop ...
Thisform.Width = min(max(Thisform.Width, 0, Thisform.MinWidth), ;
lnWidth)
Thisform.Height = min(max(Thisform.Height, 0, Thisform.MinHeight), ;
lnHeight)
Thisform.Left = min(max(Thisform.Left, 0), lnWidth - 50)
Thisform.Top = min(max(Thisform.Top, 0), lnHeight - 50)
declare integer GetSystemMetrics in Win32API integerNow the form reopens in the exact same size and position, including the monitor it was on.
#define SM_CXVIRTUALSCREEN 78 && Virtual Width
#define SM_CYVIRTUALSCREEN 79 && Virtual Height
lnWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN)
lnHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN)
Update: As I posted in a comment, this code correctly handle the situation where the form was originally placed on a second monitor but now that monitor doesn't exist. However, it didn't handle the case where the secondary monitor is on the left, so the starting X position is negative. See the code in the comment to deal with that.









