Positioning window in per monitor aware v2
Hi! I am trying to position the wpf window perfectly within the selected screen. When I am using the unaware option everything works fine, but in per monitor aware v2 it's a little bit complicated. I have information about screen scalling and bounds. Firstly I thought that I can just multiplicate scalling and bounds to get the correct position. I was wrong. When the selected screen is under the primary screen, then the top/y position should not be scaled, but when is above it should. What would happen if there were three monitors in the row, primary first, then some monitor with weird scaling and then selected screen? Is there some option to easily get these bounds? I want to make this clean, because now I have a temporary solution. When creating a new window I am changing dpi aware to unaware.
39 Replies
This is my constructor of Screen class
when is above it shouldwhat does this mean? wdym above/under? what are you trying to do? center a window in the screen the window is in?
It's about layout
Set window's initial position into specified screen, that it's filling its full width and height
I have got this working in dpi unaware, but I don't have any idea how to achieve this in per monitor v2
so like maximized but not actually maximized?
Yes
can you maximize, get the size and pos, then unmaximize and set the pos?
user wont notice
It's a working solution too
When the selected screen is under the primary screen, then the top/y position should not be scaled, but when is above it should.youre scaling the dimentions of the screen?
But I am looking for a method based on windows api
NativeMethods.GetMonitorInfo(monitor, info); returns a width and height without scalling
And when using it's dimensions windows is too big
For 125% scaling for example
But when scaling it (value / scalingfactor) where scalingfactor is equal to dpi / 96 and selected screen is under primary screen, top value is too low
ah
so
setting the window position sets it via the virtual screen coords right?
iirc
Right
its been a while since ive done winapi stuff
so how are you calculating the top of the screen you want?
easiest way to to calculate the raw values
and then at the end when setting the window position scale it to the screen
so that you dont miss scaling something somwhere
It's the thing I am looking for. Previously it was needed only to get selected screen bounds with NativeMethods.GetMonitorInfo and scale it by system's scale factor and it was enought for wpf coordinates for unaware(default) mode
oh i dont know how wpf handles dpi
i think it allows you to set the coords before scaling or something
Raw values = values from getmonitorinfo?
values without the scaling
So basicly it is what I said
\
Scale by? Only width and height? Left and top too?
only width and height
iirc
it must be mentioned somewhere in the docs
It will work for this situations
It wont for in this situation for example
that's weird
It's because x is based on 2'nd screen width not on 1st screen width like in the first image
I have a solution for this
Just calculate where is monitor based on primary monitor
But how to calculate this situation
Selected screen is number 3
Sorry wrong image
wdym where the monitor is?
Primary is number 1
How to calculate x for third monitor?
With this scaling
I cannot just take x(left) and multiply by 3rd scalling, or just left it without scaling
And I could write code to calculate this, and find screen by screen and add all scalled coordinates, but there is a lot of edge cases
Or maybe there is easier solution
right
i don't know how windows handles this
Maybe there is some windows api method that I can call
yeah I'd hope lol
what a pain in the ass
sorry i don't know haha
Maybe another person here know how to solve it easily
Okay I found something interesting
Everything works fine with normal bounds, when using SetWindowPlacement
Oh it's interesting, when I set window top to -720, after a second, wpf translate to -480
Oh my problem is related to wpf issue
GitHub
Window.Left and Window.Top are broken when usign PerMonitorV2 · Iss...
.NET Core Version: FW 4.8 Windows version: 10.0.19042.746 Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes Example In this example, the user is using Windows 10, the app is PerMonito...
This is my solution
oh
For next person looking
And there are api calls that I am using
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowplacement
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowplacement
https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-windowplacement
15h of research RIP, and I am still not satisfied
well at least it works now haha
saved 15h of research for the next person
I was just randomly checking difference between screen boundries and restoreboundries of the window after show method. I was amazed that my -720 top was converted to -480. I thought it is impossible and just googled it and this came up as a first research. Spoiler, every previous search did not show this