Control which monitor an application appears on

Hello,

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?

Thanks!!!

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.

It’s not clear to me how the Xojo app would know where the parent app is displayed unless you tell it somehow.

Yes, you have to use coordinates to figure it out.

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:

The old forum had a solution (from @Dave S) for restoring window positions using screen coordinates, which looks useful:

http://forums.realsoftware.com/viewtopic.php?f=1&t=47624&hilit=screen+coordinates

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.

Thanks a million guys, with all of your input, i managed to position my windows on the correct monitor !

LOL… I was about to repost the code I had on the old forum when I noticed that Paul had linked it already :slight_smile:

Oh, another stupid spammer.