winforms icon indicating copy to clipboard operation
winforms copied to clipboard

[Multi-Monitor] System.Window.Forms.Screen on different scaling factors monitors accidentially scales top(y) and left(x) on wrong screen

Open Philip-Wang01 opened this issue 11 months ago • 0 comments

.NET version

.NET 9.0.100-preview.3.24126.10

Did it work in .NET Framework?

No

Did it work in any of the earlier releases of .NET Core or .NET 5+?

No, it doesn't work in .NET 6.0/7.0/8.0, not a regression issue.

Issue description

Try to start the project in center monitor. test1978216.zip

https://github.com/dotnet/winforms/assets/86937911/41b9aae5-7175-459f-97e5-20d74e864fe6

DPI settings: Left monitor 3840x2160 150% (DISPLAY3); center monitor 3840x2160 150% (DISPLAY2, main display); right monitor 1920x1080 150% (DISPLAY1)

Output: Location: {X=266,Y=266}Factor: 144 DeviceDPI: 144 LogicalToDeviceUnit1500 Screen: \.\DISPLAY1 Bounds {X=3840,Y=579,Width=1920,Height=1080} Screen: \.\DISPLAY2 Bounds {X=0,Y=0,Width=3840,Height=2160} Screen: \.\DISPLAY3 Bounds {X=-3840,Y=3,Width=3840,Height=2160}

Comment from customer: In this scenario everything is ok. The left monitor start left with -3840 and is 3840 in width, the center monitor starts with left 0 and is 3840 in width and the right monitor start with left +3840 and is 1920 in width. so there is no gap between them.

Change the scaling of right monitor to 100%.

Output: Location: {X=114,Y=114}Factor: 144 DeviceDPI: 144 LogicalToDeviceUnit1500 Screen: \.\DISPLAY1 Bounds {X=5760,Y=869,Width=2880,Height=1620} Screen: \.\DISPLAY2 Bounds {X=0,Y=0,Width=3840,Height=2160} Screen: \.\DISPLAY3 Bounds {X=-5760,Y=5,Width=3840,Height=2160}

Comment from customer: For DISPLAY1 width and height are multiplied by 1.5 (which is ok because there is more space) but the left value is also multiplied by 1.5 which is wrong, because the center screen has not more pixels. And for the left screen the same problem: the x position is multiplied by 1.5 to -5760 which is wrong because the size of the left screen is still 3840 and x still should be -3840. If I position a new form on -5760 it is out of bounds. I still have to position it at -3840.

Steps to reproduce

  1. Prepare three monitors: left monitor 3840x2160 150% (DISPLAY3); center monitor 3840x2160 150% (DISPLAY2, main display); right monitor 1920x1080 150% (DISPLAY1).
  2. Create a VB project on center monitor.
  3. Add a button to form designer, double-click to generate the event and write the code:
Dim g As System.Drawing.Graphics = Me.CreateGraphics()
Dim factorX As Single = g.DpiX
Dim factorY As Single = g.DpiY

Debug.Write("Location: " & Me.Location.ToString)
Debug.Write("Factor: " & factorX.ToString & " DeviceDPI: " & DeviceDpi.ToString & " LogicalToDeviceUnit" & LogicalToDeviceUnits(1000))
For Each s As Screen In Screen.AllScreens
	Debug.Write("Screen: " & s.DeviceName & " Bounds " & s.Bounds.ToString)
Next
Dim f As Form = New Form
f.StartPosition = FormStartPosition.Manual
f.Left = -3800
f.Top = 10
f.Height = 200
f.Width = 200
f.Show()
  1. Build and run the application.
  2. Click the button to view the output.
  3. Change the scaling of right monitor to 100% and click the button to view the output.

More Info:

  1. The initial feedback ticket is: https://developercommunity.visualstudio.com/t/SystemWindowFormsScreen-on-different-/10601289
  2. The customer currently has a partial workaround. Please see feedback for more information.

Philip-Wang01 avatar Feb 27 '24 10:02 Philip-Wang01