Browse Source

fix bugs in FormLocationHelper if working on high DPI displays

4.1
Siegfried Pammer 15 years ago
parent
commit
50a678c30c
  1. 36
      src/Main/Base/Project/Src/Gui/FormLocationHelper.cs
  2. 2
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
  3. 9
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

36
src/Main/Base/Project/Src/Gui/FormLocationHelper.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (isResizable) { if (isResizable) {
form.Bounds = Validate(PropertyService.Get(propertyName, GetDefaultBounds(form))); form.Bounds = Validate(PropertyService.Get(propertyName, GetDefaultBounds(form)));
} else { } else {
form.Location = Validate(PropertyService.Get(propertyName, GetDefaultLocation(form)), form.Size); form.Location = Validate(new System.Drawing.Rectangle(PropertyService.Get(propertyName, GetDefaultLocation(form)), form.Size)).Location;
} }
form.Closing += delegate { form.Closing += delegate {
if (isResizable) { if (isResizable) {
@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (isResizable) { if (isResizable) {
Rect bounds = PropertyService.Get(propertyName, GetDefaultBounds(window)); Rect bounds = PropertyService.Get(propertyName, GetDefaultBounds(window));
bounds.Offset(ownerLocation.X, ownerLocation.Y); bounds.Offset(ownerLocation.X, ownerLocation.Y);
bounds = Validate(bounds); bounds = Validate(bounds.TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = bounds.X; window.Left = bounds.X;
window.Top = bounds.Y; window.Top = bounds.Y;
window.Width = bounds.Width; window.Width = bounds.Width;
@ -50,9 +50,9 @@ namespace ICSharpCode.SharpDevelop.Gui
Size size = new Size(window.ActualWidth, window.ActualHeight); Size size = new Size(window.ActualWidth, window.ActualHeight);
Point location = PropertyService.Get(propertyName, GetDefaultLocation(window)); Point location = PropertyService.Get(propertyName, GetDefaultLocation(window));
location.Offset(ownerLocation.X, ownerLocation.Y); location.Offset(ownerLocation.X, ownerLocation.Y);
location = Validate(location, size); var bounds = Validate(new Rect(location, size).TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = location.X; window.Left = bounds.X;
window.Top = location.Y; window.Top = bounds.Y;
} }
window.Closing += delegate { window.Closing += delegate {
var relativeToOwner = GetLocationRelativeToOwner(window); var relativeToOwner = GetLocationRelativeToOwner(window);
@ -88,35 +88,25 @@ namespace ICSharpCode.SharpDevelop.Gui
return new Point(owner.Left, owner.Top); return new Point(owner.Left, owner.Top);
} }
public static Rect Validate(Rect bounds) /// <remarks>Requires Pixels!!!</remarks>
public static System.Drawing.Rectangle Validate(System.Drawing.Rectangle bounds)
{ {
// Check if form is outside the screen and get it back if necessary. // Check if form is outside the screen and get it back if necessary.
// This is important when the user uses multiple screens, a window stores its location // This is important when the user uses multiple screens, a window stores its location
// on the secondary monitor and then the secondary monitor is removed. // on the secondary monitor and then the secondary monitor is removed.
LoggingService.InfoFormatted("Number of screens: {0}", Screen.AllScreens.Length);
foreach (var screen in Screen.AllScreens) { foreach (var screen in Screen.AllScreens) {
var rect = System.Drawing.Rectangle.Intersect(bounds.ToSystemDrawing(), screen.WorkingArea); var rect = System.Drawing.Rectangle.Intersect(bounds, screen.WorkingArea);
LoggingService.InfoFormatted("Screen {2}: Validating {0}; intersection {1}", bounds, rect, screen.Bounds);
if (rect.Width > 10 && rect.Height > 10) if (rect.Width > 10 && rect.Height > 10)
return bounds; return bounds;
} }
// center on primary screen // center on primary screen
LoggingService.InfoFormatted("Validating {0}; center on screen", bounds);
// TODO : maybe use screen where main window is most visible? // TODO : maybe use screen where main window is most visible?
var targetScreen = Screen.PrimaryScreen; var targetScreen = Screen.PrimaryScreen;
return new Rect((targetScreen.WorkingArea.Width - bounds.Width) / 2, (targetScreen.WorkingArea.Height - bounds.Height) / 2, bounds.Width, bounds.Height); return new System.Drawing.Rectangle((targetScreen.WorkingArea.Width - bounds.Width) / 2, (targetScreen.WorkingArea.Height - bounds.Height) / 2, bounds.Width, bounds.Height);
}
static Point Validate(Point location, Size size)
{
return Validate(new Rect(location, size)).Location;
}
static System.Drawing.Rectangle Validate(System.Drawing.Rectangle bounds)
{
return Validate(bounds.ToWpf()).ToSystemDrawing();
}
static System.Drawing.Point Validate(System.Drawing.Point location, System.Drawing.Size size)
{
return Validate(location.ToWpf(), size.ToWpf()).ToSystemDrawing();
} }
static System.Drawing.Rectangle GetDefaultBounds(Form form) static System.Drawing.Rectangle GetDefaultBounds(Form form)

2
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.SharpDevelop.Gui
void EnsureFloatingWindowsLocations() void EnsureFloatingWindowsLocations()
{ {
foreach (var window in dockingManager.FloatingWindows) { foreach (var window in dockingManager.FloatingWindows) {
var newLocation = FormLocationHelper.Validate(new Rect(window.Left, window.Top, window.Width, window.Height)); var newLocation = FormLocationHelper.Validate(new Rect(window.Left, window.Top, window.Width, window.Height).TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = newLocation.Left; window.Left = newLocation.Left;
window.Top = newLocation.Top; window.Top = newLocation.Top;
} }

9
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -82,6 +82,13 @@ namespace ICSharpCode.SharpDevelop.Gui
{ {
base.OnSourceInitialized(e); base.OnSourceInitialized(e);
HwndSource.FromHwnd(this.MainWin32Window.Handle).AddHook(SingleInstanceHelper.WndProc); HwndSource.FromHwnd(this.MainWin32Window.Handle).AddHook(SingleInstanceHelper.WndProc);
// validate after PresentationSource is initialized
Rect bounds = new Rect(Left, Top, Width, Height);
bounds = FormLocationHelper.Validate(bounds.TransformToDevice(this).ToSystemDrawing()).ToWpf().TransformFromDevice(this);
this.Left = bounds.Left;
this.Top = bounds.Top;
this.Width = bounds.Width;
this.Height = bounds.Height;
} }
public void Initialize() public void Initialize()
@ -554,7 +561,7 @@ namespace ICSharpCode.SharpDevelop.Gui
public void SetMemento(Properties memento) public void SetMemento(Properties memento)
{ {
Rect bounds = memento.Get("Bounds", new Rect(10, 10, 750, 550)); Rect bounds = memento.Get("Bounds", new Rect(10, 10, 750, 550));
bounds = FormLocationHelper.Validate(bounds); // bounds are validated after PresentationSource is initialized (see OnSourceInitialized)
this.Left = bounds.Left; this.Left = bounds.Left;
this.Top = bounds.Top; this.Top = bounds.Top;
this.Width = bounds.Width; this.Width = bounds.Width;

Loading…
Cancel
Save