one of my xojo applications is a generic ‘about’ box which is called from another application (PowerPoint) using the shell call.
All is fine on a system with just one monitor, but on one with multiple displays, the ‘about’ box pops up on the main screen no matter which display the ‘parent’ application is on.
I found some (Windows) API calls which could help me find out which screen the mouse is on and then perhaps position the window within that monitor’s coordinates — before i do all that however, is there some mechanism which xojo provides to simplify all that?
I’m interested in this as well. I currently restore windows sizes but I haven’t figured out how to restore them to their original locations in the corresponding monitor (or when that monitor isn’t available and have some smart resizing and positioning in the main one).
You can access the monitors using screen but I haven’t found how to figure in what screen is the current window in or how to send it to one.
Reading the docs I seem to gather that coordinates might have to be used, but considering how irregular coordinates may be I don’t know if this is the best way.
Yes, you have to use coordinates to figure it out.[/quote]
But I surely am missing something there.
“Screen” lists screens as main, secondary, third, etc.
Coordinates would give an absolute position on an irregular layout.
Changing the monitor positions would break the coordinates, but getting the screen index wouldn’t. A combination of coordinates and screen index would be the best.
How can I get what screen is being used from the coordinates? I may be misunderstanding, I’m imagining draging a poly with all the coordinates of all monitors.
I usually have a monitor layout like this:
But I’ve often had something like this, when I have the iPad connected as an external monitor:
Given X and Y screen coordinates, the following method returns the index of the containing Screen object that can be passed to the Screen() method.
Function ScreenFromXY(X As Integer, Y As Integer) As Integer
Dim rect As New REALbasic.Rect
Dim pt As New REALbasic.Point
pt.X = X
pt.Y = Y
For i As Integer = 0 To ScreenCount - 1
rect.Top = Screen(i).Top
rect.Left = Screen(i).Left
rect.Width = Screen(i).Width
rect.Height = Screen(i).Height
If rect.Contains(pt) Then
Return i
End If
Next
Return -1
End Function
Something like this? (Tested only on my vanilla system with side-by-side identical screens.)
Sub ShowCentered(Win As Window, ScreenNumber As Integer = 0)
' Shows the passed window centered on the specified Screen.
Dim X, Y As Integer
X = (0.5 * Screen(ScreenNumber).Width) - (0.5 * Win.Width)
Y = (0.5 * Screen(ScreenNumber).Height) - (0.5 * Win.Height)
win.Show
If Screen(ScreenNumber).Top > Screen(0).Height - 1 Then
Y = Y + Screen(ScreenNumber).Height
End If
If Screen(ScreenNumber).Left > Screen(0).Width - 1 Then
X = X + Screen(ScreenNumber).Width
End If
win.Left = X
win.Top = Y
End Sub
Example use:
Dim ScreenNumber As Integer = ScreenFromXY(System.MouseX, System.MouseY)
ShowCentered(MyWindow, ScreenNumber)
Thanks, Paul. I should’ve known better than not searching.
Thanks, Andrew. This looks like a similar approach to what Dave did, but summarises the getter and setter.
Thanks to both. Both use the same solution I hadn’t thought of, but now it’s obvious.
I’ll extend the logic to store the relative and absolute coordinates, as well as the screen number. If the former change but not the latter (repositioning the screen) I can restore recalculating the absolutes from the relatives. If the screen disappears I can then restore in the main screen using the default positioning rules for the platform.