winforms icon indicating copy to clipboard operation
winforms copied to clipboard

Calling GetDpiForWindow before setting StartPosition will cause the display position to be incorrect.

Open hampex opened this issue 2 months ago • 1 comments

.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;
            }
        }
    }
}

hampex avatar Nov 06 '25 09:11 hampex

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.

LeafShi1 avatar Nov 10 '25 02:11 LeafShi1