Calling GetDpiForWindow before setting StartPosition will cause the display position to be incorrect.
.NET version
.NET 9.0
Did it work in .NET Framework?
Not tested/verified
Did it work in any of the earlier releases of .NET Core or .NET 5+?
No response
Issue description
Calling GetDpiForWindow before setting StartPosition will result in an incorrect display position. Setting StartPosition after calling GetDpiForWindow will display it in the correct position.
Steps to reproduce
namespace WinFormsApp1
{
public partial class Form1 : Form
{
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetDpiForWindow(IntPtr hwnd);
public Form1()
{
InitializeComponent();
if (true)
{ // NG
double scaling = (double)GetDpiForWindow(this.Handle) / 96;
StartPosition = FormStartPosition.CenterScreen;
}
else
{ // OK
StartPosition = FormStartPosition.CenterScreen;
double scaling = (double)GetDpiForWindow(this.Handle) / 96;
}
}
}
}
This issue is not a regression, the same behavior exists in .NET Framework.
Calling double scaling = (double)GetDpiForWindow(this.Handle) / 96; inside the constructor forces the creation of the form’s handle earlier than expected. When the handle is created, the layout logic for StartPosition = FormStartPosition.CenterScreen;
has not yet been applied, so the form does not appear centered on the screen.
If you must access the DPI in the constructor, you can use CenterToScreen(); to manually center it.