I know, it does... ;)
But for this particular case I don't want to use a Plugin... That's why I'm asking here.
Here is a program that confirms the 180% when you are at 200% scale, and also a way to calculate the scale with SetProcessDPIAware.
Some of the details of HiDPI are mentioned in this Xojo blog: Writing High-DPI Aware Windows Apps
It is presumed that the native primary native resolution is 96 DPI, and this can be retrieved with another API call called GetDeviceCaps. I just used the default 96 value. My system has 1-HiDPI screen and 2-non HiDPI screens. Moving the cursor through the different screens will then show the monitor number that the cursor is located, and also the HiDPI ratio using the default 96 dpi value. Global mouse coordinates are also shown so that you can quickly determine where the screen origin is located. The timer refreshes the information every 200 milliseconds. I added the SetProcessDPIAware function in the Window1 Open event.
This is all with Windows 10 API declares and it works on my machine with Xojo 2018 r3. LOL, don't mind the spaghetti code, as I quickly put this together.
Let me know if this works on your computer. :)
Thanks, @Eugene D. I think I've seen this example in another thread.
While it works, I still have the same question… Your example for example reports:
\\.\DISPLAY4 or Monitor Number 4.
Xojo refers to this as
Screen(0). So I still wonder how to make the "link" between Xojo's Screen-Objects and the Monitors from the Windows API.
If you're interested, have a look at this example project .
What it does: simply shows a modal dialog centerred within the parent window.
With the buttons on the Left, it will do that using Xojo methods (position with .Left/.Top or .Bounds).
The button on the right will do that using Windows API. And the "Fit on Monitor" just makes sure that the "main window" is fully visible within it's current screen.
With Xojo 2018r3, Windows 10 and 2-3 Monitors (all with different ScaleFactors), the Xojo methods are a mess… It seems to me that this example WindowsAPI approach at least positions the modal dialogs appropriately.
So back to what's missing… There are situations, where I know that I have to position Dialog Y on (Xojo)Screen(1).
So that's where I'm still struck… how do I get to know which MonitorHandle is repesenting Xojo's Screen(1)?
@Jürg O So that's where I'm still struck… how do I get to know which MonitorHandle is repesenting Xojo's Screen(1)?
I implemented a method from Michel's code on the forum called WhichScreen, and here is an example which shows the MonitorHandle and the Xojo Screen that the mouse pointer is located:
Here is a screen grab from the program which shows both the handle and screen number:
In my example program the location of the mouse shows that there are three different screens. In the helpful Monitors_v1 example program you provided, there are only two screens shown. In the TextArea1 control it shows there are three. When I run the Monitors_v1 program and place the Window1 near the far-right location on Screen 1 of my configuration (seen below), then the centered modal window appears partially in Screen 3 and Screen 1.
Code will need to be adjusted in the Monitors_v1 program to determine where Screen 3 stops and Screen 1 begins. The DPIResolutionV2 example program does this change between monitor screen numbers which has a different handle.
@Eugene D a method called WhichScreen
The thing with Screen(i).left is, that it reports different values in 2016r3 or 2018r3 (same Multi-Monitors/Multi-ScaleFactors)… so I guess I can't trust that…?
Or maybe it needs to be different depending on XojoVersion…
Anyway, I'll probably only come back to this next week - weekend start here ;)
@Jürg Otter The thing with Screen(i).left is, that it reports different values in 2016r3 or 2018r3 (same Multi-Monitors/Multi-ScaleFactors)… so I guess I can't trust that…?
It looks like you found a bug :)
I get two different screen numbers when changing the x-axis value on the far-right screen (Screen 2 and Screen 0) at about the half-way point in the third screen. I am also not able to place the mouse at x-axis position 3421.
A feedback case was created
Feedback Case #54234
Have a relaxing weekend!
Edit: Changed wording to far-right screen.
@Eugene D It looks like you found a bug :)
There are quite some related to Screen and Positioning in Multi-Monitor/Multi-Scale situations on Windows... :(
And for this very reason I'm trying to find a way to be able to place "child windows/dialogs" in a way that works.
I've updated the example above with a "position a dialog relative to a parent window", which seems to work, too.
Once we have a Window, we can do positioning and monitor-querying from that, using the window as "parent" and go relative from there.
It's just the situation at the very beginning - where to reliably place the first window (at a specific monitor and position)?
Or if you want/need to show a dialog on a specific screen (where you haven't had another Window before to get the Monitor Handle).
That's where my question comes in: how to match Xojo's Screen(X) with MonitorHandle. Doing it by using the Screen's values is likely going to be wrong. There has to be some API-way to get the all the Monitor Handles in the same order as Xojo's Screens - I hope ;)
@Eugene D When I run the Monitors_v1 program and place the Window1 near the far-right location on Screen 1 of my configuration (seen below), then the centered modal window appears partially in Screen 3 and Screen 1.
This occurs when positioning using the WindowsAPI? If so - let me know if you figure out why that happens... I haven't seen this in a 3-monitor-situation (at work - so I won't be able to trying to reproduce it over the weekend).
btw: if you don't align your monitors with all the same Top-y-Position, things will go even worse (with Xojo's methods).
I've updated the example project .
The 'Pos' Buttons on the bottom allow to position a Window relative to a currently visible one. Compared to the previous example I've fixed to respect the Window Decoration.
While doing that, I've discovered yet another bug :( Feedback Case #54242
oWnd2.Left=some-value, the Window's .Height gets unexpectedly a different value (+/- 1). This is also "fixed" when using the Windows API to position.
Now all that is missing is a way to enumerate and build an array of Monitor Handles (which has the same order such as Xojo's Screens). That would allow us to use this as a workaround to handle Multi-Monitors/Multi-ScaleFactor situations with the current and recent XojoVersions...
Any ideas, suggestions, attempts or solutions are greatly appreciated :)
Another update to the example project . The TextAreas on the Top shows Xojo's Screens, and now on the right I hope I could retrieve the Monitors via WindowsAPI.
I only have 1 Monitor right now... so I don't know what happens with multiple monitors (and if the retrieved Handles are in the same order such as Xojo's Screens).
Could anyone with 2-3 Monitors run the example and drag the window between the monitors?
then please let me know if:
If that's working and matching Xojo's order of Screens, then this would allow to reliably position windows/modal-dialogs at specific screens/monitors and position...
@Jürg O If that's working and matching Xojo's order of Screens, then this would allow to reliably position windows/modal-dialogs at specific screens/monitors and position...
While I still hope someone gets to test this with 2-3 Monitors... I already prepared for absolute positioning in the example project (v3) .
The goal of v3 is:
It should now be possible to position windows/dialogs both relative to a parent, and on a specified Monitor at a specified Position, working around the Xojo Frameworks bugs in MultiMonitor/MultiScaleFactor situations. And... it should work on macOS, too.
Since I couldn't test over the weekend, this v3 might still need a couple of tweaks. I'm curious to read how it works for you in your multi-monitor-environment. I hope it's better compared to what the buttons on the left are doing ;)
I downloaded your program and using the Windows API Center Modal button works on all three monitors in the correct order.
Using Xojo's API, the Center modal works on both of the lower resolution monitors and fails on the high resolution HiDPi monitor.
Thanks @Eugene D for testing.
I'd like to know if this example is working for others, too. And/or if the 3 positioning possibilities (relative to a parent Window | absolute | on a specific Screen at a specific position) are working in various Multi-Monitor (and Multi-Scale-Factor) situations.
I've updated v3 with some fixes - so please re-download it again.
I hope this example provides a way to reliably position a Window/dialog in the situations that often occur:
If that's working as a workaround for now (I really hope Xojo fixes these Screen/Positioning/HiDPI/ScaleFactor issues sooner rather than later or never)… then HiDPI might be an option to enable for Windows apps built with Xojo that are not only used internally.
@Jürg O if the 3 positioning possibilities (relative to a parent Window | absolute | on a specific Screen at a specific position) are working
Let me rephrase "absolute". What I mean with that I've written now like this in the example project : Position at Xojo Window .Left/Top
That's for the situation where you store aWindow.Left, aWindow.Top (once aWindow .Close's - and maybe temporarily save the 'last position' somewhere), in order to restore that Window at some later time at the previous location where the user has closed it. So you need a way to assign that .Left and .Top value again - in a way that the Window shows at the expected position.
I think to have that working, but could only test on 2 Monitors until now :)
@Jürg O Position at Xojo Window .Left/Top
Such as @Graham B and @David M have mentioned and explained at the beginning of this Thread, it is very well possible that on 3 monitors a Xojo Window will report .Left=2100 on both Screen(1) and Screen(2). So it's still not reliably possible to use these .Left/.Top positions to place a dialog.
What is working for me: The example project reports the "at relative Monitor Position (x, y)". That along with the MonitorIndex allows to place a dialog on every available Monitor, at a relative Monitor position.
You can test this by showing "Window2" in the example project (by clicking any of the positioning buttons), then move it to some Monitor of yours. Read the "relative Monitor Position", and place the values in the appropriate fields. Set the "on Screen/Monitor", and the "Pos" on the right.
This seems to be working for me, even if monitors 1,2 are place above/below each other.
@David M I just spent a while flipping "off" the HiDPI switch and retesting. As expected, everything "works properly" under Win10 this way, regardless of the screen arrangement and individual screen scaling factors.
What it means to me at the moment is: I can't use HiDPI for a potential production release build without going down the route of making my own fixed Screen() function and getting it to "line up" correctly with how Window properties behave when a Window is placed and positioned on that screen - and even then, not feeling this will be solid enough to release. It's a shame, because Retina support works fine on the Mac and there are many graphics in the UI that are nice and ready-to-go at upscaled resolutions. A fix in the framework - which is where it "should" be fixed - is the right thing to wait for.
I'm hopeful....! It's easy for me to test: a fix in the framework, I can just switch HiDPI back on, rebuild, and run it. It'll be obvious whether it starts doing the right thing.
In the meantime: what would be useful in the r3 alphas would be: separate, per-platform settings having to do with higher DPI builds. Right now, the HiDPI switch covers both OSX and Windows and you have to remember to set it one way or the other. How about adding a new "Retina" switch that applies only to OSX builds; to go along with the existing "HiDPI" switch (and have it only apply to Windows builds)? (Just like, there's now a Dark Mode switch in the same part of the IDE, which only applies to OSX builds but which would be ignored for Windows builds - there's room for some platform specificity there).
very good thanks bro
My solution which appears to work on Windows HDPI for setting the screen position to take up entire second / third screen is as follows, it uses MBS plugins to get correct values - i am sure the api's are easy enough to find.
I have tests on a lot of different screen sizes / scalings / resolutions and hardware (Screens) and all appear to work as expected.
If you are wanting to save and load screen locations i assume using left and top from xojo would work but aligning to something else you need to do half of it outside of Xojo.
Meanwhile: what might be valuable in the r3 alphas would be: independent, per-stage settings having to do with higher DPI fabricates. At this moment, the HiDPI switch covers both OSX and Windows and you need to make sure to set it one way or the other. What about including another "Retina" switch that applies just to OSX works; to oblige the current "HiDPI" switch (and have it just apply to Windows assembles)? (Much the same as, there's presently a Dark Mode switch in a similar piece of the IDE, which just applies to OSX assembles yet which would be overlooked for Windows constructs - there's space for some stage particularity there