diff --git a/OnTopReplica/AspectRatioForm.cs b/OnTopReplica/AspectRatioForm.cs
index 06e298d..87f99f7 100644
--- a/OnTopReplica/AspectRatioForm.cs
+++ b/OnTopReplica/AspectRatioForm.cs
@@ -116,7 +116,8 @@ namespace OnTopReplica {
MinimumSize.Width);
//Determine new height while keeping aspect ratio
- int newHeight = (int)((newWidth - ExtraPadding.Horizontal - clientSizeConversionWidth) / AspectRatio) + ExtraPadding.Vertical + clientSizeConversionHeight;
+ var clientConversionDifference = ClientWindowDifference;
+ int newHeight = (int)((newWidth - ExtraPadding.Horizontal - clientConversionDifference.Width) / AspectRatio) + ExtraPadding.Vertical + clientConversionDifference.Height;
//Apply and move form to recenter
Size = new Size(newWidth, newHeight);
@@ -161,11 +162,13 @@ namespace OnTopReplica {
///
protected override void WndProc(ref Message m) {
if (KeepAspectRatio && m.Msg == WM.SIZING) {
+ var clientSizeConversion = ClientWindowDifference;
+
var rc = (Native.NRectangle)Marshal.PtrToStructure(m.LParam, typeof(Native.NRectangle));
int res = m.WParam.ToInt32();
- int width = (rc.Right - rc.Left) - clientSizeConversionWidth - ExtraPadding.Horizontal;
- int height = (rc.Bottom - rc.Top) - clientSizeConversionHeight - ExtraPadding.Vertical;
+ int width = (rc.Right - rc.Left) - clientSizeConversion.Width - ExtraPadding.Horizontal;
+ int height = (rc.Bottom - rc.Top) - clientSizeConversion.Height - ExtraPadding.Vertical;
if (res == WMSZ.LEFT || res == WMSZ.RIGHT) {
//Left or right resize, adjust top and bottom
@@ -173,7 +176,7 @@ namespace OnTopReplica {
int diffHeight = height - targetHeight;
rc.Top += (int)(diffHeight / 2.0);
- rc.Bottom = rc.Top + targetHeight + ExtraPadding.Vertical + clientSizeConversionHeight;
+ rc.Bottom = rc.Top + targetHeight + ExtraPadding.Vertical + clientSizeConversion.Height;
}
else if (res == WMSZ.TOP || res == WMSZ.BOTTOM) {
//Up or down resize, adjust left and right
@@ -181,15 +184,15 @@ namespace OnTopReplica {
int diffWidth = width - targetWidth;
rc.Left += (int)(diffWidth / 2.0);
- rc.Right = rc.Left + targetWidth + ExtraPadding.Horizontal + clientSizeConversionWidth;
+ rc.Right = rc.Left + targetWidth + ExtraPadding.Horizontal + clientSizeConversion.Width;
}
else if (res == WMSZ.RIGHT + WMSZ.BOTTOM || res == WMSZ.LEFT + WMSZ.BOTTOM) {
//Lower corner resize, adjust bottom
- rc.Bottom = rc.Top + (int)(width / AspectRatio) + ExtraPadding.Vertical + clientSizeConversionHeight;
+ rc.Bottom = rc.Top + (int)(width / AspectRatio) + ExtraPadding.Vertical + clientSizeConversion.Height;
}
else if (res == WMSZ.LEFT + WMSZ.TOP || res == WMSZ.RIGHT + WMSZ.TOP) {
//Upper corner resize, adjust top
- rc.Top = rc.Bottom - (int)(width / AspectRatio) - ExtraPadding.Vertical - clientSizeConversionHeight;
+ rc.Top = rc.Bottom - (int)(width / AspectRatio) - ExtraPadding.Vertical - clientSizeConversion.Height;
}
Marshal.StructureToPtr(rc, m.LParam, false);
@@ -202,15 +205,15 @@ namespace OnTopReplica {
#region ClientSize/Size conversion helpers
- int clientSizeConversionWidth, clientSizeConversionHeight;
-
///
/// Converts a client size measurement to a window size measurement.
///
/// Size of the window's client area.
/// Size of the whole window.
public Size FromClientSizeToSize(Size clientSize) {
- return new Size(clientSize.Width + clientSizeConversionWidth, clientSize.Height + clientSizeConversionHeight);
+ var difference = ClientWindowDifference;
+
+ return new Size(clientSize.Width + difference.Width, clientSize.Height + difference.Height);
}
///
@@ -219,18 +222,24 @@ namespace OnTopReplica {
/// Size of the whole window.
/// Size of the window's client area.
public Size FromSizeToClientSize(Size size) {
- return new Size(size.Width - clientSizeConversionWidth, size.Height - clientSizeConversionHeight);
- }
+ var difference = ClientWindowDifference;
- protected override void OnShown(EventArgs e) {
- base.OnShown(e);
-
- clientSizeConversionWidth = Size.Width - ClientSize.Width;
- clientSizeConversionHeight = Size.Height - ClientSize.Height;
+ return new Size(size.Width - difference.Width, size.Height - difference.Height);
}
#endregion
+ ///
+ /// Gets the difference in pixels between a client size value and a window size value (depending on window decoration).
+ ///
+ protected Size ClientWindowDifference {
+ get {
+ long style = WindowMethods.GetWindowLong(this.Handle, WindowMethods.WindowLong.Style).ToInt64();
+ long exStyle = WindowMethods.GetWindowLong(this.Handle, WindowMethods.WindowLong.ExStyle).ToInt64();
+ return WindowMethods.ConvertClientToWindowRect(new NRectangle(0, 0, 0, 0), style, exStyle).Size;
+ }
+ }
+
}
}
diff --git a/OnTopReplica/Native/Rectangle.cs b/OnTopReplica/Native/Rectangle.cs
index cb138c8..1166648 100644
--- a/OnTopReplica/Native/Rectangle.cs
+++ b/OnTopReplica/Native/Rectangle.cs
@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
+using System.Drawing;
namespace OnTopReplica.Native {
+
/// A native Rectangle Structure.
[StructLayout(LayoutKind.Sequential)]
struct NRectangle {
@@ -52,4 +54,13 @@ namespace OnTopReplica.Native {
}
}
+
+ static class NRectangleExtensions {
+
+ public static NRectangle ToNativeRectangle(this Size size) {
+ return new NRectangle(0, 0, size.Width, size.Height);
+ }
+
+ }
+
}
diff --git a/OnTopReplica/Native/WindowMethods.cs b/OnTopReplica/Native/WindowMethods.cs
index 56d315b..7345218 100644
--- a/OnTopReplica/Native/WindowMethods.cs
+++ b/OnTopReplica/Native/WindowMethods.cs
@@ -56,17 +56,6 @@ namespace OnTopReplica.Native {
return String.Empty;
}
- const int MaxClassLength = 255;
-
- public static string GetWindowClass(IntPtr hwnd) {
- var sb = new StringBuilder(MaxClassLength + 1);
- RealGetWindowClass(hwnd, sb, MaxClassLength);
- return sb.ToString();
- }
-
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- static extern uint RealGetWindowClass(IntPtr hwnd, [Out] StringBuilder lpString, uint maxCount);
-
public enum WindowLong {
WndProc = (-4),
HInstance = (-6),
@@ -77,11 +66,6 @@ namespace OnTopReplica.Native {
Id = (-12)
}
- public enum ClassLong {
- Icon = -14,
- IconSmall = -34
- }
-
[Flags]
public enum WindowStyles : long {
None = 0,
@@ -131,7 +115,23 @@ namespace OnTopReplica.Native {
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, WindowLong nIndex, IntPtr dwNewLong);
- #region Class styles
+ #region Window class
+
+ const int MaxClassLength = 255;
+
+ public static string GetWindowClass(IntPtr hwnd) {
+ var sb = new StringBuilder(MaxClassLength + 1);
+ RealGetWindowClass(hwnd, sb, MaxClassLength);
+ return sb.ToString();
+ }
+
+ [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ static extern uint RealGetWindowClass(IntPtr hwnd, [Out] StringBuilder lpString, uint maxCount);
+
+ public enum ClassLong {
+ Icon = -14,
+ IconSmall = -34
+ }
[DllImport("user32.dll", EntryPoint = "GetClassLongPtrW")]
static extern IntPtr GetClassLong64(IntPtr hWnd, int nIndex);
@@ -153,5 +153,28 @@ namespace OnTopReplica.Native {
[DllImport("user32.dll")]
public static extern IntPtr GetMenu(IntPtr hwnd);
+ ///
+ /// Converts client size rectangle to window rectangle, according to window styles.
+ ///
+ /// Client area bounding box.
+ /// Style of window to compute.
+ /// Extended style of window to compute.
+ public static NRectangle ConvertClientToWindowRect(NRectangle clientRectangle, long windowStyle, long extendedWindowStyle) {
+ NRectangle tmp = clientRectangle;
+ if (AdjustWindowRectEx(ref tmp, windowStyle, false, extendedWindowStyle)) {
+ return tmp;
+ }
+ else {
+#if DEBUG
+ throw new InvalidOperationException("Failed to convert client rectangle to window rectangle");
+#else
+ return clientRectangle;
+#endif
+ }
+ }
+
+ [DllImport("user32.dll")]
+ private static extern bool AdjustWindowRectEx(ref NRectangle clientToWindowRect, long windowStyle, bool hasMenu, long extendedWindowStyle);
+
}
}
diff --git a/OnTopReplica/Platforms/WindowsSeven.cs b/OnTopReplica/Platforms/WindowsSeven.cs
index c24ee7c..4114f3b 100644
--- a/OnTopReplica/Platforms/WindowsSeven.cs
+++ b/OnTopReplica/Platforms/WindowsSeven.cs
@@ -33,29 +33,6 @@ namespace OnTopReplica.Platforms {
form.Show();
}
- /*public override void OnFormStateChange(MainForm form) {
- //SetWindowStyle(form);
- }*/
-
- ///
- /// Used to alter the window style. Not used anymore.
- ///
- private void SetWindowStyle(MainForm form) {
- if (!form.FullscreenManager.IsFullscreen) {
- //This hides the app from ALT+TAB
- //Note that when minimized, it will be shown as an (ugly) minimized tool window
- //thus we do not minimize, but set to transparent when hiding
- long exStyle = WindowMethods.GetWindowLong(form.Handle, WindowMethods.WindowLong.ExStyle).ToInt64();
-
- exStyle |= (long)(WindowMethods.WindowExStyles.ToolWindow);
- //exStyle &= ~(long)(WindowMethods.WindowExStyles.AppWindow);
-
- WindowMethods.SetWindowLong(form.Handle, WindowMethods.WindowLong.ExStyle, new IntPtr(exStyle));
-
- //WindowMethods.SetWindowLong(form.Handle, WindowMethods.WindowLong.HwndParent, WindowManagerMethods.GetDesktopWindow());
- }
- }
-
}
}