diff options
author | Dimitrij <kvarkas@gmail.com> | 2022-05-13 03:39:00 +0300 |
---|---|---|
committer | Dimitrij <kvarkas@gmail.com> | 2022-05-13 03:39:00 +0300 |
commit | ec2f3024b641b8c46438415facb5a73ea76ea016 (patch) | |
tree | 070aeb7cc9fbdb2240f37010850e78de9f951bb9 | |
parent | 25543f656121582bdb9d0b28a2faf32a77cd70a2 (diff) |
implement DPIAware, change splash screen to wpf
-rw-r--r-- | mRemoteNG/App/CompatibilityChecker.cs | 11 | ||||
-rw-r--r-- | mRemoteNG/App/ProgramRoot.cs | 40 | ||||
-rw-r--r-- | mRemoteNG/App/Runtime.cs | 2 | ||||
-rw-r--r-- | mRemoteNG/App/Startup.cs | 3 | ||||
-rw-r--r-- | mRemoteNG/Properties/Resources.resx | 6 | ||||
-rw-r--r-- | mRemoteNG/Properties/app.manifest | 100 | ||||
-rw-r--r-- | mRemoteNG/Tools/MiscTools.cs | 11 | ||||
-rw-r--r-- | mRemoteNG/UI/DPI_Per_Monitor.cs | 162 | ||||
-rw-r--r-- | mRemoteNG/UI/Font/HandelGotDBol.ttf | bin | 0 -> 52792 bytes | |||
-rw-r--r-- | mRemoteNG/UI/Forms/FrmSplashScreen.Designer.cs | 76 | ||||
-rw-r--r-- | mRemoteNG/UI/Forms/FrmSplashScreen.cs | 48 | ||||
-rw-r--r-- | mRemoteNG/UI/Forms/FrmSplashScreen.resx | 60 | ||||
-rw-r--r-- | mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml | 22 | ||||
-rw-r--r-- | mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml.cs | 45 | ||||
-rw-r--r-- | mRemoteNG/UI/Forms/frmMain.cs | 24 | ||||
-rw-r--r-- | mRemoteNG/mRemoteNG.csproj | 9 |
16 files changed, 356 insertions, 263 deletions
diff --git a/mRemoteNG/App/CompatibilityChecker.cs b/mRemoteNG/App/CompatibilityChecker.cs index cc60270d..dff841c2 100644 --- a/mRemoteNG/App/CompatibilityChecker.cs +++ b/mRemoteNG/App/CompatibilityChecker.cs @@ -37,14 +37,9 @@ namespace mRemoteNG.App messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true); //About to pop up a message, let's not block it... - FrmSplashScreen.getInstance().Close(); - - var ShouldIStayOrShouldIGo = CTaskDialog.MessageBox(Application.ProductName, - Language.CompatibilityProblemDetected, errorText, "", - "", - Language.CheckboxDoNotShowThisMessageAgain, - ETaskDialogButtons.OkCancel, ESysIcons.Warning, - ESysIcons.Warning); + FrmSplashScreenNew.GetInstance().Close(); + + var ShouldIStayOrShouldIGo = CTaskDialog.MessageBox(Application.ProductName, Language.CompatibilityProblemDetected, errorText, "", "", Language.CheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.OkCancel, ESysIcons.Warning, ESysIcons.Warning); if (CTaskDialog.VerificationChecked && ShouldIStayOrShouldIGo == DialogResult.OK) { messageCollector.AddMessage(MessageClass.ErrorMsg, "User requests that FIPS check be overridden", true); diff --git a/mRemoteNG/App/ProgramRoot.cs b/mRemoteNG/App/ProgramRoot.cs index 93a92d22..84c79f69 100644 --- a/mRemoteNG/App/ProgramRoot.cs +++ b/mRemoteNG/App/ProgramRoot.cs @@ -1,6 +1,8 @@ using System; using System.Diagnostics; +using System.Drawing; using System.Threading; +using System.Windows; using System.Windows.Forms; using mRemoteNG.Properties; using mRemoteNG.UI.Forms; @@ -26,11 +28,28 @@ namespace mRemoteNG.App private static void StartApplication() { CatchAllUnhandledExceptions(); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - var frmSplashScreen = FrmSplashScreen.getInstance(); + System.Windows.Forms.Application.EnableVisualStyles(); + System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); + var frmSplashScreen = FrmSplashScreenNew.GetInstance(); + + Screen targetScreen = (Screen.AllScreens.Length > 1) ? Screen.AllScreens[1] : Screen.AllScreens[0]; + + Rectangle viewport = targetScreen.WorkingArea; + frmSplashScreen.Top = viewport.Top; + frmSplashScreen.Left = viewport.Left; + //mainWindow.Show(); + Screen[] screens = Screen.AllScreens; + //if (screens.Length > 1) + //{ + // normaly it should be screens[1] however due DPI apply 1 size "same" as default with 100% + frmSplashScreen.Left = viewport.Left + (targetScreen.Bounds.Size.Width / 2) - (frmSplashScreen.Width / 2); + frmSplashScreen.Top = viewport.Top + (targetScreen.Bounds.Size.Height / 2) - (frmSplashScreen.Height / 2); + //frmSplashScreen.Top = 50; + //} + + //frmSplashScreen.Show(); frmSplashScreen.Show(); - Application.Run(FrmMain.Default); + System.Windows.Forms.Application.Run(FrmMain.Default); } public static void CloseSingletonInstanceMutex() @@ -78,15 +97,15 @@ namespace mRemoteNG.App private static void CatchAllUnhandledExceptions() { - Application.ThreadException += ApplicationOnThreadException; - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + System.Windows.Forms.Application.ThreadException += ApplicationOnThreadException; + System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; } private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e) { - if (!FrmSplashScreen.getInstance().IsDisposed) - FrmSplashScreen.getInstance().Close(); + // if (PresentationSource.FromVisual(FrmSplashScreenNew)) + FrmSplashScreenNew.GetInstance().Close(); if (FrmMain.Default.IsDisposed) return; @@ -97,8 +116,9 @@ namespace mRemoteNG.App private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) { - if (!FrmSplashScreen.getInstance().IsDisposed) - FrmSplashScreen.getInstance().Close(); + //TODO: Check if splash closed properly + //if (!FrmSplashScreenNew.GetInstance().IsDisposed) + // FrmSplashScreenNew.GetInstance().Close(); var window = new FrmUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); window.ShowDialog(FrmMain.Default); diff --git a/mRemoteNG/App/Runtime.cs b/mRemoteNG/App/Runtime.cs index 8177b780..278f37ce 100644 --- a/mRemoteNG/App/Runtime.cs +++ b/mRemoteNG/App/Runtime.cs @@ -115,7 +115,7 @@ namespace mRemoteNG.App } catch (Exception ex) { - FrmSplashScreen.getInstance().Close(); + FrmSplashScreenNew.GetInstance().Close(); if (Properties.OptionsDBsPage.Default.UseSQLServer) { diff --git a/mRemoteNG/App/Startup.cs b/mRemoteNG/App/Startup.cs index 7fb7a5eb..9a2f041a 100644 --- a/mRemoteNG/App/Startup.cs +++ b/mRemoteNG/App/Startup.cs @@ -38,8 +38,7 @@ namespace mRemoteNG.App public void InitializeProgram(MessageCollector messageCollector) { - Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + - Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture)); + Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture)); var startupLogger = new StartupDataLogger(messageCollector); startupLogger.LogStartupData(); CompatibilityChecker.CheckCompatibility(messageCollector); diff --git a/mRemoteNG/Properties/Resources.resx b/mRemoteNG/Properties/Resources.resx index 697396b1..ff9c62a1 100644 --- a/mRemoteNG/Properties/Resources.resx +++ b/mRemoteNG/Properties/Resources.resx @@ -112,12 +112,12 @@ <value>2.0</value> </resheader> <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> - <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> + <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <data name="ConnectedOverlay" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\ConnectedOverlay.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> diff --git a/mRemoteNG/Properties/app.manifest b/mRemoteNG/Properties/app.manifest index 1869411d..b0f71974 100644 --- a/mRemoteNG/Properties/app.manifest +++ b/mRemoteNG/Properties/app.manifest @@ -1,50 +1,56 @@ <?xml version="1.0" encoding="utf-8"?> -<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" - xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" - xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" - xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <assemblyIdentity version="1.0.0.0" name="MyApplication.app" /> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> - <security> - <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> - <!-- UAC Manifest Options - If you want to change the Windows User Account Control level replace the - requestedExecutionLevel node with one of the following. +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <assemblyIdentity version="1.77.3.0" name="mRemoteNG" /> + <asmv3:application> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings"> + <activeCodePage>UTF-8</activeCodePage> + </asmv3:windowsSettings> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> + <dpiAwareness>PerMonitorV2</dpiAwareness> + </asmv3:windowsSettings> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> + <dpiAware>true</dpiAware> + </asmv3:windowsSettings> + <asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> + <ws2:longPathAware>true</ws2:longPathAware> + </asmv3:windowsSettings> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings"> + <heapType>SegmentHeap</heapType> + </asmv3:windowsSettings> + </asmv3:application> + + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> + <security> + <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> + <!-- UAC Manifest Options + If you want to change the Windows User Account Control level replace the + requestedExecutionLevel node with one of the following. - <requestedExecutionLevel level="asInvoker" uiAccess="false" /> - <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> - <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> + <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> - If you want to utilize File and Registry Virtualization for backward - compatibility then delete the requestedExecutionLevel node. - --> - <requestedExecutionLevel level="asInvoker" uiAccess="false" /> - </requestedPrivileges> - <applicationRequestMinimum> - <PermissionSet Unrestricted="true" ID="Custom" SameSite="site" /> - <defaultAssemblyRequest permissionSetReference="Custom" /> - </applicationRequestMinimum> - </security> - </trustInfo> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!-- Windows 10 --> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - <!-- Windows 8.1 --> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <!-- Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - <!-- Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!-- Windows 8 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - </application> - </compatibility> - - <asmv3:application> - <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> - <dpiAware>true</dpiAware> - </asmv3:windowsSettings> - </asmv3:application> -</asmv1:assembly>
\ No newline at end of file + If you want to utilize File and Registry Virtualization for backward + compatibility then delete the requestedExecutionLevel node. + --> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </requestedPrivileges> + <applicationRequestMinimum> + <PermissionSet Unrestricted="true" ID="Custom" SameSite="site" /> + <defaultAssemblyRequest permissionSetReference="Custom" /> + </applicationRequestMinimum> + </security> + </trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <!-- Windows 10, 11 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + </application> + </compatibility> +</assembly>
\ No newline at end of file diff --git a/mRemoteNG/Tools/MiscTools.cs b/mRemoteNG/Tools/MiscTools.cs index 98047926..bd1ba250 100644 --- a/mRemoteNG/Tools/MiscTools.cs +++ b/mRemoteNG/Tools/MiscTools.cs @@ -13,6 +13,7 @@ using mRemoteNG.UI.Forms; using MySql.Data.Types; using mRemoteNG.Resources.Language; using static System.String; +using System.Windows; namespace mRemoteNG.Tools { @@ -43,9 +44,10 @@ namespace mRemoteNG.Tools public static Optional<SecureString> PasswordDialog(string passwordName = null, bool verify = true) { - var splash = FrmSplashScreen.getInstance(); - if (!splash.IsDisposed && splash.Visible) - splash.Close(); + var splash = FrmSplashScreenNew.GetInstance(); + //TODO: something not right there + //if (PresentationSource.FromVisual(splash)) + // splash.Close(); var passwordForm = new FrmPassword(passwordName, verify); return passwordForm.GetKey(); @@ -126,8 +128,7 @@ namespace mRemoteNG.Tools { var bmp = new Bitmap(sender.Width, sender.Height, PixelFormat.Format32bppRgb); Graphics g = Graphics.FromImage(bmp); - g.CopyFromScreen(sender.PointToScreen(Point.Empty), Point.Empty, bmp.Size, - CopyPixelOperation.SourceCopy); + g.CopyFromScreen(sender.PointToScreen(System.Drawing.Point.Empty), System.Drawing.Point.Empty, bmp.Size, CopyPixelOperation.SourceCopy); return bmp; } } diff --git a/mRemoteNG/UI/DPI_Per_Monitor.cs b/mRemoteNG/UI/DPI_Per_Monitor.cs new file mode 100644 index 00000000..e9a9c6b8 --- /dev/null +++ b/mRemoteNG/UI/DPI_Per_Monitor.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; + +/// <summary> +/// +/// DPI_Per_Monitor +/// +/// Use to make a simple Windows for app truely DPI-aware. +/// That is AVOID woolly apps! +/// +/// 1) Make sure your forms are designed with font size set in PIXELS, not POINTS (yes!!) +/// All controls possible should use inherited fonts +/// Each font explicitly given in PIXEL needs to be handled in the callback function +/// provided to Check_WM_DPICHANGED +/// The standard "8.25pt" matches "11.0px" (8.25 *96/72 = 11) +/// +/// 2) Leave the form in the default Autoscale=Font mode +/// +/// 3) Insert call to DPI_Per_Monitor.TryEnableDPIAware() , right after InitializeComponent(); +/// +/// 4) Add suitable call to DPI_Per_Monitor.Check_WM_DPICHANGED_WM_NCCREATE in DefWndProc +/// If a DefWndProc override is not already present add e.g. these lines +/// +/// protected override void DefWndProc(ref Message m) { +/// DPI_Per_Monitor.Check_WM_DPICHANGED_WM_NCCREATE(SetUserFonts,m, this.Handle); +/// base.DefWndProc(ref m); +/// } +/// +/// that has a call-back function you must provide, that set fonts as needed (in pixels or points), +/// if all are inherited, then just one set: +/// +/// void SetUserFonts(float scaleFactorX, float scaleFactorY) { +/// Font = new Font(Font.FontFamily, 11f * scaleFactorX, GraphicsUnit.Pixel); +/// } +/// +/// 5) And a really odd one, due to a Visual studio BUG. +/// This ONLY works, if your PRIMARY monitor is scalled at 100% at COMPILE time!!! +/// It is NOT just a matter of using a different reference than the 96 dpi below, and +/// it does not help to run it from a secondary monitor set to 100% !!! +/// And to make things worse, Visual Studio is one of the programs that doesn't handle +/// change of scale on primary monitor, without at the least a sign out.... +/// +/// NOTE that if you got (Checked)ListBoxes, repeated autosizing (e.g. move between monitors) +/// might fail as it rounds the height down to a multipla of the itemheight. So despite a +/// bottom-anchor it will 'creep' upwards... +/// So I recommend to place an empty and/or hidden bottom-anchored label just below the boxes, +/// to scale the spacing and set e.g. : yourList.Height=yourAnchor.Top-yourList.Top +/// +/// Also note that not everything gets scaled automatically. Only new updates of Win10 handles +/// the titlebar correctly. Also the squares of checkboxes are forgotten. +/// </summary> + +static class DPI_Per_Monitor +{ + [DllImport("SHCore.dll")] + private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness); + + private enum PROCESS_DPI_AWARENESS { + Process_DPI_Unaware = 0, + Process_System_DPI_Aware = 1, + Process_Per_Monitor_DPI_Aware = 2 + } + + [DllImport("user32.dll", SetLastError = true)] + static extern bool SetProcessDPIAware(); + + public static float MeanDPIprimary = 96f; + + [DllImport("user32.dll", EntryPoint = "SetWindowPos")] + public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); + [DllImport("user32.dll")] + internal static extern bool SetProcessDpiAwarenessContext(IntPtr XXXX); + [DllImport("user32.dll")] + internal static extern IntPtr GetWindowDpiAwarenessContext(IntPtr hWnd); + + public static IntPtr DPI_AWARENESS_CONTEXT = GetWindowDpiAwarenessContext(System.Diagnostics.Process.GetCurrentProcess().Handle); + + public enum DpiType + { + Effective = 0, + Angular = 1, + Raw = 2, + } + [DllImport("Shcore.dll")] + private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY); + [DllImport("User32.dll")] + private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags); + + static List<Tuple<Control, Form, float>> ManResCtrl = new List<Tuple<Control, Form, float>>(); + internal static void TryEnableDPIAware(Form form, VoidOfFloatFloatDelegate CallBackWithScale) + { + int handledLev = 0; + if (0==handledLev) + try { //"Creators update", new method, Only onw supported by newer VS: DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 + if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT - 4)) handledLev = 3; + } catch {} + if(0==handledLev) + try { //"Aniversary update", 'new' method, now depreceated + SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_Per_Monitor_DPI_Aware); + handledLev = 2; + } catch { } + if (0==handledLev) + try { // fallback, use (simpler) internal function - backwars compaibility that has been broken by newer Windows and Visual Studio... + SetProcessDPIAware(); + handledLev = 1; + } catch { } + try { + var mon = MonitorFromPoint(new System.Drawing.Point(1, 1), 2/*MONITOR_DEFAULTTONEAREST*/); //(0,0) always top left of primary + uint dpiX; + uint dpiY; + GetDpiForMonitor(mon, DpiType.Effective, out dpiX, out dpiY); + if (dpiX!=96 || dpiY!=96) { + CallBackWithScale(dpiX/96f, dpiY/96f); + } + } catch { /* Windows older than WinX */ } + } + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool EnableNonClientDpiScaling(IntPtr hWnd); + + private static SemaphoreSlim semaphoreScale = new SemaphoreSlim(1, 1); + internal delegate void VoidOfFloatFloatDelegate(float x, float y); + static Int32 Oldscales = -1; + static bool isCurrentlyScaling=false; + internal static void Check_WM_DPICHANGED_WM_NCCREATE(VoidOfFloatFloatDelegate CallBackWithScale, Message m, IntPtr hwnd) { + switch (m.Msg) { + case 0x02E0: //WM_DPICHANGED + try { + semaphoreScale.Wait(2000); //timeout?? + bool Local_isCurrentlyScaling = isCurrentlyScaling; + isCurrentlyScaling = true; + semaphoreScale.Release(); + if (Local_isCurrentlyScaling) break; //We will get it again if we are moving.... + + Int32 CurrentScales = m.WParam.ToInt32(); + //if (ScaleFactorsLastAndPendingQueue[0]!=ScaleFactorsLastAndPendingQueue[1]) //We MIGHT get the message more than once!!! + if (Oldscales!= CurrentScales) { //We MIGHT get the message more than once!!! + float scaleFactorX = (CurrentScales & 0xFFFF) / 96f; //###SEE NOTES!!### + float scaleFactorY = (CurrentScales >> 16) / 96f; //###SEE NOTES!!### + CallBackWithScale(scaleFactorX, scaleFactorY); + } + semaphoreScale.Wait(2000); //timeout?? + Oldscales = CurrentScales; + isCurrentlyScaling = false; + semaphoreScale.Release(); + } + catch {} + + break; + case 0x81: //WM_NCCREATE + try { EnableNonClientDpiScaling(hwnd); } catch { } //Scale header too if updates of Windows 10 between "Aniversary" and "Creators"... + break; + default: + break; + } + } +} diff --git a/mRemoteNG/UI/Font/HandelGotDBol.ttf b/mRemoteNG/UI/Font/HandelGotDBol.ttf Binary files differnew file mode 100644 index 00000000..b9bd98a4 --- /dev/null +++ b/mRemoteNG/UI/Font/HandelGotDBol.ttf diff --git a/mRemoteNG/UI/Forms/FrmSplashScreen.Designer.cs b/mRemoteNG/UI/Forms/FrmSplashScreen.Designer.cs deleted file mode 100644 index 80dfc41d..00000000 --- a/mRemoteNG/UI/Forms/FrmSplashScreen.Designer.cs +++ /dev/null @@ -1,76 +0,0 @@ -namespace mRemoteNG.UI.Forms -{ - partial class FrmSplashScreen - { - /// <summary> - /// Required designer variable. - /// </summary> - private System.ComponentModel.IContainer components = null; - - /// <summary> - /// Clean up any resources being used. - /// </summary> - /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// <summary> - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// </summary> - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.BackColor = System.Drawing.Color.Transparent; - this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.label1.ForeColor = System.Drawing.Color.White; - this.label1.Location = new System.Drawing.Point(390, 100); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(0, 17); - this.label1.TabIndex = 0; - // - // FrmSplashScreen - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackgroundImage = global::mRemoteNG.Properties.Resources.Header_dark; - this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.ClientSize = new System.Drawing.Size(450, 120); - this.ControlBox = false; - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Margin = new System.Windows.Forms.Padding(2); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(180, 60); - this.Name = "FrmSplashScreen"; - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "frmSplashScreen"; - this.TopMost = true; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - } -}
\ No newline at end of file diff --git a/mRemoteNG/UI/Forms/FrmSplashScreen.cs b/mRemoteNG/UI/Forms/FrmSplashScreen.cs deleted file mode 100644 index 472fad0d..00000000 --- a/mRemoteNG/UI/Forms/FrmSplashScreen.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Windows.Forms; -using mRemoteNG.App.Info; - -namespace mRemoteNG.UI.Forms -{ - public partial class FrmSplashScreen : Form - { - static FrmSplashScreen instance = null; - - private FrmSplashScreen() - { - InitializeComponent(); - label1.Text = $@"v. {GeneralAppInfo.ApplicationVersion}"; - Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20)); - } - - [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")] - private static extern IntPtr CreateRoundRectRgn - ( - int nLeftRect, // x-coordinate of upper-left corner - int nTopRect, // y-coordinate of upper-left corner - int nRightRect, // x-coordinate of lower-right corner - int nBottomRect, // y-coordinate of lower-right corner - int nWidthEllipse, // width of ellipse - int nHeightEllipse // height of ellipse - ); - - public static FrmSplashScreen getInstance() - { - if (instance == null) - instance = new FrmSplashScreen(); - return instance; - } - - protected override CreateParams CreateParams - { - get - { - CreateParams cp = base.CreateParams; - // turn on WS_EX_TOOLWINDOW style bit - cp.ExStyle |= 0x80; - return cp; - } - } - } -}
\ No newline at end of file diff --git a/mRemoteNG/UI/Forms/FrmSplashScreen.resx b/mRemoteNG/UI/Forms/FrmSplashScreen.resx deleted file mode 100644 index f298a7be..00000000 --- a/mRemoteNG/UI/Forms/FrmSplashScreen.resx +++ /dev/null @@ -1,60 +0,0 @@ -<root> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> -</root>
\ No newline at end of file diff --git a/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml b/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml new file mode 100644 index 00000000..ef7d21e8 --- /dev/null +++ b/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml @@ -0,0 +1,22 @@ +<Window x:Class="mRemoteNG.UI.Forms.FrmSplashScreenNew" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:mRemoteNG.UI.Forms" + mc:Ignorable="d" + WindowStartupLocation="Manual" + WindowStyle="None" + AllowsTransparency="True" + Background="Transparent" + Height="120" + Width="450"> + <Border CornerRadius="10" BorderBrush="#211E1B" BorderThickness="1" Background="#373C42"> + <Grid> + <Label Name="lblLogoPartA" Content="m" HorizontalAlignment="Left" VerticalAlignment="Top" Height="59" Margin="78,12,0,0" Width="40" FontFamily="HandelGotDBol" FontSize="40" Foreground="#5289F9"/> + <Label Name="lblLogoPartB" Content="RemoteNG" HorizontalAlignment="Left" VerticalAlignment="Top" Height="59" Margin="109,12,0,0" Width="210" FontFamily="HandelGotDBol" FontSize="40" Foreground="#E8EBEE"/> + <Label Name="lblLogoPartC" Content="Multi-Remote Next Generation Connection Manager" HorizontalAlignment="Center" VerticalAlignment="Top" Height="30" Margin="0,72,0,0" Width="410" FontFamily="Segoe" FontSize="16" Foreground="#E8EBEE" FontWeight="Bold"/> + <Label Name="lblLogoPartD" Content="v.?.??.?" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Margin="319,36,0,0" Width="75" FontFamily="Segoe" FontSize="16" Foreground="#E8EBEE"/> + </Grid> + </Border> +</Window> diff --git a/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml.cs b/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml.cs new file mode 100644 index 00000000..f95ba08a --- /dev/null +++ b/mRemoteNG/UI/Forms/FrmSplashScreenNew.xaml.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Forms; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.Drawing.Text; +using System.Drawing; +using mRemoteNG.App.Info; + +namespace mRemoteNG.UI.Forms +{ + /// <summary> + /// Interaction logic for FrmSplashScreenNew.xaml + /// </summary> + public partial class FrmSplashScreenNew + { + static FrmSplashScreenNew instance = null; + public FrmSplashScreenNew() + { + InitializeComponent(); + LoadFont(); + lblLogoPartD.Content = $@"v. {GeneralAppInfo.ApplicationVersion}"; + } + public static FrmSplashScreenNew GetInstance() + { + if (instance == null) + instance = new FrmSplashScreenNew(); + return instance; + } + void LoadFont() + { + lblLogoPartA.FontFamily = new System.Windows.Media.FontFamily(new Uri("pack://application:,,,/"), "./UI/Font/#HandelGotDBol"); + lblLogoPartB.FontFamily = new System.Windows.Media.FontFamily(new Uri("pack://application:,,,/"), "./UI/Font/#HandelGotDBol"); + } + } +} diff --git a/mRemoteNG/UI/Forms/frmMain.cs b/mRemoteNG/UI/Forms/frmMain.cs index 0cd3d725..43c10f16 100644 --- a/mRemoteNG/UI/Forms/frmMain.cs +++ b/mRemoteNG/UI/Forms/frmMain.cs @@ -30,9 +30,10 @@ using System.Windows.Forms; using mRemoteNG.UI.Panels; using WeifenLuo.WinFormsUI.Docking; using mRemoteNG.UI.Controls; -using mRemoteNG.Properties; + using mRemoteNG.Resources.Language; + // ReSharper disable MemberCanBePrivate.Global namespace mRemoteNG.UI.Forms @@ -63,6 +64,7 @@ namespace mRemoteNG.UI.Forms { _showFullPathInTitle = Properties.OptionsAppearancePage.Default.ShowCompleteConsPathInTitle; InitializeComponent(); + DPI_Per_Monitor.TryEnableDPIAware(this, SetUserFonts); Fullscreen = new FullscreenHandler(this); //Theming support @@ -72,7 +74,23 @@ namespace mRemoteNG.UI.Forms _advancedWindowMenu = new AdvancedWindowMenu(this); } - + void SetUserFonts(float scaleFactorX, float scaleFactorY) + { + //this.Width = (int)Math.Ceiling(this.Width *scaleFactorX); + //this.Height = (int)Math.Ceiling(this.Height*scaleFactorY); + var OldFont = Font; + Font = new Font(Font.FontFamily, 11f * scaleFactorX, Font.Style, GraphicsUnit.Pixel); + OldFont.Dispose(); + //splitContainer1.Size = this.ClientSize; // not strictly important, but stabalize things against rounding errors... + //checkedListBoxSaved.Height = labelAnchorSaved.Top - checkedListBoxSaved.Top; //See note on listboxes + //checkedListBoxCurrent.Height = labelAnchorChecked.Top - checkedListBoxCurrent.Top; //See note on listboxes + Refresh(); + } + //protected override void DefWndProc(ref System.Windows.Forms.Message m) + //{ + // DPI_Per_Monitor.Check_WM_DPICHANGED_WM_NCCREATE(SetUserFonts, m, this.Handle); + // base.WndProc(ref m); + //} #region Properties public FormWindowState PreviousWindowState { get; set; } @@ -194,7 +212,7 @@ namespace mRemoteNG.UI.Forms pnlDock.ShowDocumentIcon = true; - FrmSplashScreen.getInstance().Close(); + FrmSplashScreenNew.GetInstance().Close(); if (Properties.OptionsStartupExitPage.Default.StartMinimized) { diff --git a/mRemoteNG/mRemoteNG.csproj b/mRemoteNG/mRemoteNG.csproj index 7c845fa5..e44cec82 100644 --- a/mRemoteNG/mRemoteNG.csproj +++ b/mRemoteNG/mRemoteNG.csproj @@ -15,6 +15,8 @@ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <LangVersion>latest</LangVersion> <PackageIcon>Header_dark.png</PackageIcon> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <UseWPF>True</UseWPF> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <DefineConstants>DEBUG</DefineConstants> @@ -49,6 +51,7 @@ <ItemGroup> <None Remove="buildenv.tmp" /> + <None Remove="UI\Font\HandelGotDBol.ttf" /> </ItemGroup> <ItemGroup> @@ -422,6 +425,12 @@ </ItemGroup> <ItemGroup> + <Resource Include="UI\Font\HandelGotDBol.ttf"> + <CopyToOutputDirectory>Never</CopyToOutputDirectory> + </Resource> + </ItemGroup> + + <ItemGroup> <PackageReference Update="chromiumembeddedframework.runtime.win-x64" Version="92.0.25" /> </ItemGroup> |