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();
Hi, You are correct. Thanks for sharing your solution. Regards, Dimitar
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);
}
}