diff --git a/src/Application/Application.csproj b/src/Application/Application.csproj
index bcdd3a58..559b62d9 100644
--- a/src/Application/Application.csproj
+++ b/src/Application/Application.csproj
@@ -174,6 +174,7 @@
+
FormGotoLine.cs
diff --git a/src/Application/FormMain.cs b/src/Application/FormMain.cs
index fe86c4a9..e742a374 100644
--- a/src/Application/FormMain.cs
+++ b/src/Application/FormMain.cs
@@ -1753,6 +1753,9 @@ protected virtual void OnSettingsChanged(object sender, string name)
this._analytics.SetEnabled(this._settings.GetBoolean("AllowAnalytics", false));
}
break;
+ case "Theme":
+ OnThemeChanged();
+ break;
}
this._delayedActions.StartDelayedAction("DelaySaveSettings",
@@ -1760,6 +1763,27 @@ protected virtual void OnSettingsChanged(object sender, string name)
TimeSpan.FromSeconds(1));
}
+ private void OnThemeChanged()
+ {
+ if ((ColorTheme)this._settings["Theme"] == ColorTheme.Light)
+ {
+ ThemeAllControls(this, false);
+ }
+ else
+ {
+ ThemeAllControls(this, true);
+ }
+ }
+
+ private void ThemeAllControls(Control parent, bool darkMode)
+ {
+ Win32Helpers.UseImmersiveDarkMode(this.Handle, darkMode);
+ foreach (Control control in parent.Controls)
+ {
+ ThemeAllControls(control, darkMode);
+ }
+ }
+
public void SaveErrors(string filename)
{
this._taskList.Save(filename);
diff --git a/src/Application/Win32Helpers.cs b/src/Application/Win32Helpers.cs
new file mode 100644
index 00000000..2c7248d1
--- /dev/null
+++ b/src/Application/Win32Helpers.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace XmlNotepad
+{
+ internal enum DWMWINDOWATTRIBUTE : uint
+ {
+ DWMWA_NCRENDERING_ENABLED,
+ DWMWA_NCRENDERING_POLICY,
+ DWMWA_TRANSITIONS_FORCEDISABLED,
+ DWMWA_ALLOW_NCPAINT,
+ DWMWA_CAPTION_BUTTON_BOUNDS,
+ DWMWA_NONCLIENT_RTL_LAYOUT,
+ DWMWA_FORCE_ICONIC_REPRESENTATION,
+ DWMWA_FLIP3D_POLICY,
+ DWMWA_EXTENDED_FRAME_BOUNDS,
+ DWMWA_HAS_ICONIC_BITMAP,
+ DWMWA_DISALLOW_PEEK,
+ DWMWA_EXCLUDED_FROM_PEEK,
+ DWMWA_CLOAK,
+ DWMWA_CLOAKED,
+ DWMWA_FREEZE_REPRESENTATION,
+ DWMWA_PASSIVE_UPDATE_MODE,
+ DWMWA_USE_HOSTBACKDROPBRUSH,
+ DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
+ DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
+ DWMWA_WINDOW_CORNER_PREFERENCE = 33,
+ DWMWA_BORDER_COLOR,
+ DWMWA_CAPTION_COLOR,
+ DWMWA_TEXT_COLOR,
+ DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
+ DWMWA_SYSTEMBACKDROP_TYPE,
+ DWMWA_LAST
+ };
+
+
+ internal static class Win32Helpers
+ {
+ [DllImport("Dwmapi")]
+ static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE dwAttribute, ref int attrValue, uint cbAttribute);
+
+ internal static bool UseImmersiveDarkMode(IntPtr handle, bool enabled)
+ {
+ if (IsWindows10OrGreater(17763))
+ {
+ var attribute = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
+ if (IsWindows10OrGreater(18985))
+ {
+ attribute = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
+ }
+
+ int useImmersiveDarkMode = enabled ? 1 : 0;
+ return DwmSetWindowAttribute(handle, attribute,
+ ref useImmersiveDarkMode, sizeof(int)) == 0;
+ }
+
+ return false;
+ }
+
+ private static bool IsWindows10OrGreater(int build = -1)
+ {
+ return Environment.OSVersion.Version.Major >= 10 &&
+ Environment.OSVersion.Version.Build >= build;
+ }
+
+ }
+}
diff --git a/src/Model/XmlCache.cs b/src/Model/XmlCache.cs
index 7bbbf426..a269bb6b 100644
--- a/src/Model/XmlCache.cs
+++ b/src/Model/XmlCache.cs
@@ -393,7 +393,7 @@ public void SaveCopy(string filename)
Settings settings = (Settings)this._site.GetService(typeof(Settings));
if (settings != null)
{
- noBom = (bool)settings["NoByteOrderMark"];
+ noBom = settings.GetBoolean("NoByteOrderMark", false);
if (noBom)
{
// then we must have an XML declaration with an encoding attribute.
@@ -414,10 +414,11 @@ public void SaveCopy(string filename)
EncodingHelpers.InitializeWriterSettings(w, this._site);
_doc.Save(w);
}
- ms.Seek(0, SeekOrigin.Begin);
-
- EncodingHelpers.WriteFileWithoutBOM(ms, filename);
+ using (var stm = new MemoryStream(ms.ToArray()))
+ {
+ EncodingHelpers.WriteFileWithoutBOM(stm, filename);
+ }
}
else
{
diff --git a/src/UnitTests/UnitTest1.cs b/src/UnitTests/UnitTest1.cs
index c558bbee..738ede2c 100644
--- a/src/UnitTests/UnitTest1.cs
+++ b/src/UnitTests/UnitTest1.cs
@@ -3099,9 +3099,48 @@ public void TestChangeTo()
this.SaveAndCompare("out.xml", "test8.xml");
}
+ [TestMethod]
+ [Timeout(TestMethodTimeout)]
+ public void TestNoByteOrderMark()
+ {
+ SetNoByteOrderMark(true);
+ Trace.WriteLine("TestNoByteOrderMark==========================================================");
+ string testFile = _testDir + "UnitTests\\test8.xml";
+ var w = this.LaunchNotepad(testFile);
+ Sleep(1000);
+ string outFile = Save("out.xml");
+ AssertUtf8Bom(testFile, true);
+ AssertUtf8Bom(outFile, false);
+
+ // test we can load it
+ XmlDocument doc = new XmlDocument();
+ doc.Load(outFile);
+ }
//==================================================================================
+
+ void SetNoByteOrderMark(bool value)
+ {
+ this.testSettings["NoByteOrderMark"] = value;
+ this.testSettings.Save(this.testSettings.FileName);
+ }
+
+ private void AssertUtf8Bom(string filename, bool expected)
+ {
+ var data = File.ReadAllBytes(filename);
+ bool isUtf8 = data.Length > 3 && data[0] == 0xef && data[1] == 0xBB && data[2] == 0xBF;
+ if (isUtf8 && !expected)
+ {
+ throw new ApplicationException("Byte order mark is present in {filename} but should not be");
+ }
+ else if (!isUtf8 && expected)
+ {
+ throw new ApplicationException("Byte order mark is not present in {filename} but should be");
+ }
+ }
+
+
private void SaveAndCompare(string outname, string compareWith)
{
string outFile = Save(outname);
diff --git a/src/Updates/Updates.xml b/src/Updates/Updates.xml
index eef0e37d..eb40b39d 100644
--- a/src/Updates/Updates.xml
+++ b/src/Updates/Updates.xml
@@ -9,6 +9,10 @@
https://github.com/microsoft/XmlNotepad/blob/master/src/Updates/Updates.xml
1.00:00:00
+
+ Fix issue #425: "No byte order mark on save" option throws stream closed exception add unit test.
+ Apply dark mode to window titlebar.
+
Fix issue #418: check setttings-file for "read-only".
Fix issue #398: XmlNotepad detects xml-errors at empty nillable xsd:date Elements, but xml is correct
diff --git a/src/Version/Version.cs b/src/Version/Version.cs
index 70fb28e9..628ba1b6 100644
--- a/src/Version/Version.cs
+++ b/src/Version/Version.cs
@@ -15,5 +15,7 @@
// Build Number
// Revision
//
+// This is the Master version number from which UpdateVersions will propagate to
+// Package.appxmanifest, Product.wxs, Bundle.wxs and Application.csproj.
[assembly: AssemblyVersion("2.9.0.14")]
[assembly: AssemblyFileVersion("2.9.0.14")]