-
Notifications
You must be signed in to change notification settings - Fork 982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WinForms HighDPI PerMonitorV2 windows launched on secondary monitor is incorrectly scaled #4854
Comments
Here is a workaround until this is fixed: internal const uint WM_DPICHANGED = 0x02E0;
[DllImport("user32.dll")]
internal static extern int GetDpiForWindow(IntPtr hwnd);
[DllImport("user32.dll")]
internal static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref RECT lParam);
internal static IntPtr MakeLParam(int lowWord, int highWord)
{
return (IntPtr)((highWord << 16) | (lowWord & 0xffff));
}
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
int realDpi = GetDpiForWindow(this.Handle);
double scaleFactor = (double)realDpi / (double)this.DeviceDpi;
int newWidth = (int)(this.Size.Width * scaleFactor);
int newHeight = (int)(this.Size.Height * scaleFactor);
int dpiLeft = this.Location.X + ((this.Size.Width - newWidth) / 2);
int dpiTop = this.Location.Y + ((this.Size.Height - newHeight) / 2);;
int dpiRight = dpiLeft + newWidth;
int dpiBottom = dpiTop + newHeight;
RECT rect = new RECT() { left = dpiLeft, top = dpiTop, right = dpiRight, bottom = dpiBottom };
SendMessage(this.Handle, WM_DPICHANGED, MakeLParam(realDpi, realDpi), ref rect);
} |
@Balkoth , i think you mentioned same scenario in a different issue. Can you please elaborate on how "quickly focusing a window on another monitor so that this monitor gets the focus" is helping you launching application on secondary screen? |
I don't know how to say this in simpler words, but there is another method. Just put the windows explorer on the monitor in question and launch the exe via doubleclick from there. |
No worries. Sample app attached helped understand that you were explicitly setting position on Form to CenterScreen. Will be looking into it. |
…th different DPI settings. In this case, Form Handle is created according to the Secondary monitor DPI hence, doesn't receive `DPI_CHANGED` message. Fix is making sure we scale the Form according to DPI when Handle is created. Fixes #4854 and related issues.
…th different DPI settings. (#5557) * Fixing scaling issue with initializing Form on non-primary monitor with different DPI settings. In this case, Form Handle is created according to the Secondary monitor DPI hence, doesn't receive `DPI_CHANGED` message. Fix is making sure we scale the Form according to DPI when Handle is created. Fixes #4854 and related issues.
…th different DPI settings. (dotnet#5557) * Fixing scaling issue with initializing Form on non-primary monitor with different DPI settings. In this case, Form Handle is created according to the Secondary monitor DPI hence, doesn't receive `DPI_CHANGED` message. Fix is making sure we scale the Form according to DPI when Handle is created. Fixes dotnet#4854 and related issues.
@dreddy-work verify this issue in HDPI full testing again on .Net 7.0 build, I found this issue was not fixed well on both .Net 7.0 and .Net 6.0 builds: the Form deviceDpi value is not correct on secondary screen. Please see following testing result: |
…th different DPI settings. (dotnet#5557) * Fixing scaling issue with initializing Form on non-primary monitor with different DPI settings. In this case, Form Handle is created according to the Secondary monitor DPI hence, doesn't receive `DPI_CHANGED` message. Fix is making sure we scale the Form according to DPI when Handle is created. Fixes dotnet#4854 and related issues.
.NET Core Version:
SDK: 5.0.202 (db7cc87d51)
Runtime: 5.0.5 (2f740adc14)
Problem description:
If the main application window is not launched on the main monitor it scales wrong, because Form.DeviceDpi has the DPI-Settings of the main monitor.
Minimal repro:
-> Build and run the project by launching it not on your primary monitor, but on a secondary monitor with different DPI from the primary monitor. You can do this for example by launching debugging from Visual Studio and quickly focusing a window on another monitor so that this monitor gets the focus.
I have attached a sample project with the repro steps described above here:
TestDpiChanging.zip
The text was updated successfully, but these errors were encountered: