Hello:
Does the Xojo Framework provide the capability of knowing which display (in a multi-monitor setup) a given Window is currently displayed on for Mac, Windows, and Linux or should I look into using OS-specific APIs for that via Declare statement?
The framework doesn’t provide a “which screen” function, but it’s relatively simple math that has been done so many times on here that if you ask an AI I’m sure it will regurgitate stolen code you can use.
1 Like
It’s relatively simple. There are two schools of thought to deciding which screen a Windows is visible on, since there can be multiple answers. The simpler is deciding based on the top left corner, and the other is majority overlap. Majority overlap is the technique I use.
The idea is you get your window bounds, get the bounds for each screen, and see which screen has the largest amount of intersection.
Function GetCurrentDisplay (Extends Win As DesktopWindow) As DesktopDisplay
Var WinBounds As Xojo.Rect = Win.Bounds
Var LargestScreen As DesktopDisplay
Var LargestArea As Double
For ScreenIndex As Integer = 0 To DesktopDisplay.LastDisplayIndex
Var Screen As DesktopDisplay = DesktopDisplay.DisplayAt(ScreenIndex)
Var ScreenBounds As New Xojo.Rect(Screen.Left, ScreenTop, Screen.Width, Screen.Height)
Var Overlap As Xojo.Rect = ScreenBounds.Intersection(WinBounds)
Var Area As Double = Overlap.Width * Overlap.Height
If Area > LargestArea Then
LargestArea = Area
LargestScreen = Screen
End If
Next
Return LargestScreen
End Function
2 Likes
Thanks for everyone’s assistance with this. I finally figured it out. Here’s the code:
I created a Structure with the following elements:
LeftX As integer
TopY As integer
MonitorNumber As integer
I created the following Method:
Private Function GetWindowCoordinates() As structWindowCoordinates
Var LeftX As Integer = Self.Left
Var TopY As Integer = Self.Top
Var monitorNum As Integer = 0
var coordinates As structWindowCoordinates
For i As Integer = 0 To DesktopDisplay.DisplayCount - 1
Var dd As DesktopDisplay = DesktopDisplay.DisplayAt(i)
If LeftX >= dd.AvailableLeft And _
LeftX < dd.AvailableLeft + dd.AvailableWidth And _
TopY >= dd.AvailableTop And _
TopY < dd.AvailableTop + dd.AvailableHeight Then
monitorNum = i
Exit
End If
Next
coordinates.LeftX = LeftX
coordinates.TopY = TopY
coordinates.MonitorNumber = monitorNum
return coordinates
Once I retrieve the coordinates and the monitor number where the Window is displayed, I can then pretty much do whatever I want. In this case, I simply center the Window on that particular monitor like this:
Var c As structWindowCoordinates = GetWindowCoordinates()
Var dd As DesktopDisplay = DesktopDisplay.DisplayAt(c.MonitorNumber)
// Move the window to center of the monitor where it is being displayed
Self.Left = dd.AvailableLeft + (dd.AvailableWidth - Self.Width) / 2
Self.Top = dd.AvailableTop + (dd.AvailableHeight - Self.Height) / 2
I have tested it with 1-3 monitors and thus far, it’s working well. I’ll likely roll this into a library and create it as an Extension Method.