Unplanned
Last Updated: 06 Dec 2018 07:15 by ADMIN
ADMIN
Dimitar
Created on: 23 Feb 2018 09:06
Category: Form
Type: Bug Report
7
FIX. RadForm - the StartPosition is not correct on HDPI displays
To reproduce:
- Set the StartPosition to CenterScreen
- Show the form on a HDPI monitor

Workaround:
var form = new RadForm();

float dpiX, dpiY;
Graphics graphics = this.CreateGraphics();
dpiX = graphics.DpiX /100;
dpiY = graphics.DpiY /100;

form.StartPosition = FormStartPosition.Manual;
var monSize = Screen.FromControl(this).Bounds;
var centerX = (monSize.Width / 2) - (form.DesktopBounds.Width * dpiX / 2);
var centerY = (monSize.Height / 2) - (form.DesktopBounds.Height * dpiY/ 2);
form.Location = new Point((int)centerX,(int) centerY);
form.Show();


2 comments
ADMIN
Dimitar
Posted on: 06 Dec 2018 07:15
Hi,

You are correct. Thanks for sharing your solution.

Regards, 
Dimitar
QwizdomDev
Posted on: 05 Dec 2018 19:42
I modified the code to differentiate between CenterScreen and CenterParent and to put the form on the current monitor. Also, DPI should be divided by 96 instead of 100.

        /// <summary>
        /// RadForms are not centered properly to parent/screen when using
        /// a StartPosition of CenterScreen or CenterParent. This method
        /// calculates a new location for the form based on the current
        /// DPI scaling. It then sets the StartPosition to manual and 
        /// sets the form location.
        /// </summary>
        /// <param name="form">Form to determine new location for.</param>
        /// <param name="dpiControl">Control used to obtain current DPI.</param>
        /// <remarks>https://feedback.progress.com/Project/154/Feedback/Details/242556-fix-radform-the-startposition-is-not-correct-on-hdpi-displays</remarks>
        public static void CenterRadForm(Form form, Control ownerControl = null)
        {
            if (form.StartPosition != FormStartPosition.CenterScreen &&
                form.StartPosition != FormStartPosition.CenterParent)
                return;

            double dpiX, dpiY;
            Graphics graphics = form.CreateGraphics();
            dpiX = graphics.DpiX / 96;
            dpiY = graphics.DpiY / 96;

            Screen appScreen = null;

            Process appProcess = Process.GetCurrentProcess();
            IntPtr mainWindowHandle = IntPtr.Zero;
            if (appProcess != null)
                mainWindowHandle = appProcess.MainWindowHandle;
            if (mainWindowHandle != IntPtr.Zero)
                appScreen = Screen.FromHandle(mainWindowHandle);
            else if (ownerControl != null)
                appScreen = Screen.FromControl(ownerControl);
            else
                appScreen = Screen.PrimaryScreen;

            // Make sure form can be seen over owner if owner is TopMost.
            if (ownerControl != null && ownerControl is Form &&
                (ownerControl as Form).TopMost)
                form.TopMost = true;

            double centerX, centerY;
            if (form.StartPosition == FormStartPosition.CenterScreen)
            {
                Rectangle monSize = appScreen.Bounds;

                centerX = (monSize.Width - form.DesktopBounds.Width * dpiX) / 2 + appScreen.Bounds.Left;
                centerY = (monSize.Height - form.DesktopBounds.Height * dpiY) / 2 + appScreen.Bounds.Top;
            }
            else
            {
                Rectangle parentBounds;
                if (ownerControl != null)
                    parentBounds = ownerControl.Bounds;
                else
                    parentBounds = appScreen.Bounds;

                centerX = (parentBounds.Width / 2) - (form.DesktopBounds.Width * dpiX / 2) + parentBounds.X;
                centerY = (parentBounds.Height / 2) - (form.DesktopBounds.Height * dpiY / 2) + parentBounds.Y;
            }
            form.StartPosition = FormStartPosition.Manual;
            form.Location = new Point((int)centerX, (int)centerY);
        }
	}