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.
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
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)
If Screen(ScreenNumber).Top > Screen(0).Height - 1 Then
Y = Y + Screen(ScreenNumber).Height
If Screen(ScreenNumber).Left > Screen(0).Width - 1 Then
X = X + Screen(ScreenNumber).Width
win.Left = X
win.Top = Y
Dim ScreenNumber As Integer = ScreenFromXY(System.MouseX, System.MouseY)
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.