浏览代码

优化部分代码,添加翻译功能

蓝点lilac 4 年之前
父节点
当前提交
c668b7b182

+ 6 - 2
ContextMenuManager/AppString.cs

@@ -1,4 +1,5 @@
 using BluePointLilac.Methods;
 using BluePointLilac.Methods;
+using System;
 using System.Text;
 using System.Text;
 
 
 namespace ContextMenuManager
 namespace ContextMenuManager
@@ -12,14 +13,13 @@ namespace ContextMenuManager
         {
         {
             string value = UserLanguage.GetValue(section, key);
             string value = UserLanguage.GetValue(section, key);
             if(string.IsNullOrEmpty(value)) value = DefaultLanguage.GetValue(section, key);
             if(string.IsNullOrEmpty(value)) value = DefaultLanguage.GetValue(section, key);
-            return value.Replace("\\n", "\n");
+            return value.Replace("\\n", Environment.NewLine);
         }
         }
 
 
         /// <summary>常规</summary>
         /// <summary>常规</summary>
         public static class General
         public static class General
         {
         {
             private static string GetValue(string key) => GetStringValue("General", key);
             private static string GetValue(string key) => GetStringValue("General", key);
-            public static string Language => GetValue("Language");
             public static string AppName => GetValue("AppName");
             public static string AppName => GetValue("AppName");
         }
         }
 
 
@@ -188,6 +188,10 @@ namespace ContextMenuManager
             public static string SelectNewItemType => GetValue("SelectNewItemType");
             public static string SelectNewItemType => GetValue("SelectNewItemType");
             public static string RegistryFile => GetValue("RegistryFile");
             public static string RegistryFile => GetValue("RegistryFile");
             public static string SelectGroup => GetValue("SelectGroup");
             public static string SelectGroup => GetValue("SelectGroup");
+            public static string TranslateTool => GetValue("TranslateTool");
+            public static string DefaultText => GetValue("DefaultText");
+            public static string OldTranslation => GetValue("OldTranslation");
+            public static string NewTranslation => GetValue("NewTranslation");
         }
         }
 
 
         /// <summary>消息框</summary>
         /// <summary>消息框</summary>

+ 0 - 35
ContextMenuManager/BluePointLilac.Controls/HitTestMessage.cs

@@ -1,35 +0,0 @@
-namespace BluePointLilac.Controls
-{
-    public static class HitTestMessage
-    {
-        /// <summary>光标移动或鼠标按下、释放时的消息</summary>
-        public const int WM_NCHITTEST = 0x84;
-        /// <summary>鼠标击中位置</summary>
-        public enum HitTest : int
-        {
-            Error = -2,
-            Transparent = -1,
-            Nowhere = 0,
-            Client = 1,
-            TitleBar = 2,
-            SysMenu = 3,
-            Size = 4,
-            GrowBox = 5,
-            Hscroll = 6,
-            Vscroll = 7,
-            MinButton = 8,
-            MaxButton = 9,
-            Left = 10,
-            Right = 11,
-            Top = 12,
-            TopLeft = 13,
-            TopRight = 14,
-            Bottom = 15,
-            BottomLeft = 16,
-            BottomRight = 17,
-            Border = 18,
-            Close = 20,
-            Help = 21
-        }
-    }
-}

+ 0 - 232
ContextMenuManager/BluePointLilac.Controls/MyBorderForm.cs

@@ -1,232 +0,0 @@
-using BluePointLilac.Methods;
-using System;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace BluePointLilac.Controls
-{
-    public class MyBorderForm : Form
-    {
-        public MyBorderForm()
-        {
-            this.HelpBox = false;
-            //无边框窗体最大化不覆盖任务栏
-            this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
-            this.FormBorderStyle = FormBorderStyle.None;
-            this.InitializeComponents();
-        }
-
-        public new Icon Icon
-        {
-            get => base.Icon;
-            set
-            {
-                base.Icon = value;
-                picIcon.Image = value.ToBitmap().ResizeImage(picIcon.Size);
-            }
-        }
-        public new string Text
-        {
-            get => base.Text;
-            set
-            {
-                lblTilte.Text = base.Text = value;
-                SetTitleLeft();
-            }
-        }
-        public new bool MaximizeBox
-        {
-            get => lblMax.Visible;
-            set => lblMax.Visible = value;
-        }
-        public new bool MinimizeBox
-        {
-            get => lblMin.Visible;
-            set => lblMin.Visible = value;
-        }
-        public bool CloseBox
-        {
-            get => lblClose.Visible;
-            set => lblClose.Visible = value;
-        }
-        public bool HelpBox
-        {
-            get => lblHelp.Visible;
-            set => lblHelp.Visible = value;
-        }
-        public new bool ShowIcon
-        {
-            get => picIcon.Visible;
-            set
-            {
-                picIcon.Visible = value;
-                SetTitleLeft();
-            }
-        }
-        public Color TitleBarBackColor
-        {
-            get => pnlTitleBar.BackColor;
-            set => pnlTitleBar.BackColor = value;
-        }
-        public Color TitleForeColor
-        {
-            get => lblTilte.ForeColor;
-            set => lblTilte.ForeColor = value;
-        }
-        private bool centerTitle;
-        public bool CenterTitle
-        {
-            get => centerTitle;
-            set
-            {
-                centerTitle = value;
-                SetTitleLeft();
-            }
-        }
-
-        readonly Panel pnlTitleBar = new Panel
-        {
-            BackColor = Color.White,
-            Dock = DockStyle.Top,
-            Height = 30.DpiZoom()
-        };
-        readonly FlowLayoutPanel flpControls = new FlowLayoutPanel
-        {
-            FlowDirection = FlowDirection.RightToLeft,
-            AutoSizeMode = AutoSizeMode.GrowAndShrink,
-            Font = new Font("Marlett", 11F),
-            Anchor = AnchorStyles.Right,
-            AutoSize = true,
-            Top = 0
-        };
-        readonly Label lblHelp = new Label { Text = "s" };
-        readonly Label lblMin = new Label { Text = "0" };
-        readonly Label lblMax = new Label { Text = "1" };
-        readonly Label lblClose = new Label { Text = "r" };
-        readonly Label[] lblBorders = new Label[]
-        {
-            new Label { Cursor = Cursors.SizeWE, Dock = DockStyle.Left },
-            new Label { Cursor = Cursors.SizeWE, Dock = DockStyle.Right },
-            new Label { Cursor = Cursors.SizeNS, Dock = DockStyle.Top },
-            new Label { Cursor = Cursors.SizeNS, Dock = DockStyle.Bottom }
-        };
-        readonly PictureBox picIcon = new PictureBox
-        {
-            Location = new Point(8, 8).DpiZoom(),
-            Size = new Size(16, 16).DpiZoom(),
-            Enabled = false
-        };
-        readonly Label lblTilte = new Label
-        {
-            Location = new Point(26, 8).DpiZoom(),
-            Font = new Font(SystemFonts.CaptionFont.FontFamily, 9F),
-            AutoSize = true
-        };
-
-        /// <summary>无边框窗体放缩窗体和移动窗体</summary>
-        protected override void WndProc(ref Message m)
-        {
-            base.WndProc(ref m);
-            if(m.Msg == HitTestMessage.WM_NCHITTEST && this.WindowState == FormWindowState.Normal)
-            {
-                Point point = PointToClient(Cursor.Position);
-                int x = point.X;
-                int y = point.Y;
-                HitTestMessage.HitTest res = 0;
-                if(x <= 5)
-                {
-                    if(y <= 5) res = HitTestMessage.HitTest.TopLeft;
-                    else if(y >= ClientSize.Height - 5) res = HitTestMessage.HitTest.BottomLeft;
-                    else res = HitTestMessage.HitTest.Left;
-                }
-                else if(x >= ClientSize.Width - 5)
-                {
-                    if(y <= 5) res = HitTestMessage.HitTest.TopRight;
-                    else if(y >= ClientSize.Height - 5) res = HitTestMessage.HitTest.BottomRight;
-                    else res = HitTestMessage.HitTest.Right;
-                }
-                else if(y <= 5) res = HitTestMessage.HitTest.Top;
-                else if(y >= ClientSize.Height - 5) res = HitTestMessage.HitTest.Bottom;
-                m.Result = (IntPtr)res;
-            }
-        }
-
-        /// <summary>最小化后点击任务栏图标还原窗口</summary>
-        protected override CreateParams CreateParams
-        {
-            get
-            {
-                CreateParams p = base.CreateParams;
-                p.Style |= 0x20000;//WS_MINIMIZEBOX
-                return p;
-            }
-        }
-
-        protected override void OnResize(EventArgs e)
-        {
-            base.OnResize(e);
-            lblMax.Text = this.WindowState == FormWindowState.Normal ? "1" : "2";
-            SetTitleLeft();
-        }
-
-        protected override void OnLoad(EventArgs e)
-        {
-            base.OnLoad(e);
-            SetTitleLeft();
-        }
-
-        private void SetMaxOrNormal()
-        {
-            if(this.WindowState == FormWindowState.Normal)
-            {
-                this.WindowState = FormWindowState.Maximized;
-            }
-            else
-            {
-                this.WindowState = FormWindowState.Normal;
-            }
-        }
-
-        private void SetTitleLeft()
-        {
-            if(CenterTitle) lblTilte.Left = (pnlTitleBar.Width - lblTilte.Width) / 2;
-            else if(ShowIcon) lblTilte.Left = 26.DpiZoom();
-            else lblTilte.Left = 4.DpiZoom();
-        }
-
-        private void InitializeComponents()
-        {
-            this.Controls.Add(pnlTitleBar);
-            this.ControlAdded += (sender, e) => pnlTitleBar.SendToBack();
-            foreach(Label label in lblBorders)
-            {
-                label.Parent = this;
-                label.Enabled = false;
-                label.Size = new Size(1, 1);
-                label.BackColor = Color.FromArgb(85, 145, 215);
-                this.ControlAdded += (sender, e) => label.SendToBack();
-            }
-            lblTilte.SetEnabled(false);
-            pnlTitleBar.CanMoveForm();
-            pnlTitleBar.Controls.AddRange(new Control[] { flpControls, picIcon, lblTilte });
-            flpControls.Left = pnlTitleBar.Width;
-            flpControls.SizeChanged += (sender, e) => this.MinimumSize = new Size(flpControls.Width + 2, pnlTitleBar.Height + 2);
-            foreach(Label label in new[] { lblClose, lblMax, lblMin, lblHelp })
-            {
-                label.Parent = flpControls;
-                label.Margin = new Padding(0);
-                label.Size = new Size(32, 30).DpiZoom();
-                label.TextAlign = ContentAlignment.MiddleCenter;
-                label.MouseLeave += (sender, e) => label.BackColor = pnlTitleBar.BackColor;
-                label.MouseEnter += (sender, e) => label.BackColor = Color.FromArgb(213, 225, 242);
-                label.MouseDown += (sender, e) => label.BackColor = Color.FromArgb(163, 189, 227);
-            }
-            lblClose.MouseClick += (sender, e) => { if(e.Button == MouseButtons.Left) this.Close(); };
-            lblMin.MouseClick += (sender, e) => { if(e.Button == MouseButtons.Left) this.WindowState = FormWindowState.Minimized; };
-            lblMax.MouseClick += (sender, e) => { if(e.Button == MouseButtons.Left) this.SetMaxOrNormal(); };
-            pnlTitleBar.MouseDoubleClick += (sender, e) => { if(e.Button == MouseButtons.Left) this.SetMaxOrNormal(); };
-            lblHelp.Click += (sender, e) => this.OnHelpButtonClicked(null);
-
-        }
-    }
-}

+ 3 - 3
ContextMenuManager/BluePointLilac.Controls/MyMainForm.cs

@@ -5,12 +5,12 @@ using System.Windows.Forms;
 
 
 namespace BluePointLilac.Controls
 namespace BluePointLilac.Controls
 {
 {
-    public class MyMainForm : MyBorderForm
+    public class MyMainForm : Form
     {
     {
         public MyMainForm()
         public MyMainForm()
         {
         {
             this.Text = Application.ProductName;
             this.Text = Application.ProductName;
-            this.MinimumSize = this.Size = new Size(866, 642).DpiZoom();
+            this.MinimumSize = this.Size = new Size(866, 649).DpiZoom();
             this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
             this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
             this.Controls.AddRange(new Control[] { MainBody, SideBar, StatusBar, ToolBar });
             this.Controls.AddRange(new Control[] { MainBody, SideBar, StatusBar, ToolBar });
             SideBar.Resize += (sender, e) => this.OnResize(null);
             SideBar.Resize += (sender, e) => this.OnResize(null);
@@ -30,7 +30,7 @@ namespace BluePointLilac.Controls
         protected override void OnResize(EventArgs e)
         protected override void OnResize(EventArgs e)
         {
         {
             base.OnResize(e);
             base.OnResize(e);
-            MainBody.Width = ClientSize.Width - SideBar.Width - 2;
+            MainBody.Width = ClientSize.Width - SideBar.Width;
         }
         }
     }
     }
 }
 }

+ 0 - 1
ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs

@@ -13,7 +13,6 @@ namespace BluePointLilac.Controls
             this.ShortcutsEnabled = false;
             this.ShortcutsEnabled = false;
             this.BackColor = Color.White;
             this.BackColor = Color.White;
             this.ForeColor = Color.FromArgb(80, 80, 80);
             this.ForeColor = Color.FromArgb(80, 80, 80);
-            this.ScrollBars = ScrollBars.Vertical;
             this.Font = new Font(SystemFonts.MenuFont.FontFamily, 10F);
             this.Font = new Font(SystemFonts.MenuFont.FontFamily, 10F);
         }
         }
 
 

+ 40 - 11
ContextMenuManager/BluePointLilac.Controls/ResizbleForm.cs

@@ -15,28 +15,57 @@ namespace BluePointLilac.Controls
         protected override void WndProc(ref Message m)
         protected override void WndProc(ref Message m)
         {
         {
             base.WndProc(ref m);
             base.WndProc(ref m);
-            if(m.Msg == HitTestMessage.WM_NCHITTEST && this.WindowState == FormWindowState.Normal)
+            if(m.Msg == WM_NCHITTEST && this.WindowState == FormWindowState.Normal)
             {
             {
-                IntPtr hNowhere = new IntPtr((int)HitTestMessage.HitTest.Nowhere);
-                HitTestMessage.HitTest value = (HitTestMessage.HitTest)m.Result;
+                IntPtr hNowhere = new IntPtr((int)HitTest.Nowhere);
+                HitTest value = (HitTest)m.Result;
                 switch(value)
                 switch(value)
                 {
                 {
-                    case HitTestMessage.HitTest.Top:
-                    case HitTestMessage.HitTest.Bottom:
+                    case HitTest.Top:
+                    case HitTest.Bottom:
                         if(!VerticalResizable) m.Result = hNowhere;
                         if(!VerticalResizable) m.Result = hNowhere;
                         break;
                         break;
-                    case HitTestMessage.HitTest.Left:
-                    case HitTestMessage.HitTest.Right:
+                    case HitTest.Left:
+                    case HitTest.Right:
                         if(!HorizontalResizable) m.Result = hNowhere;
                         if(!HorizontalResizable) m.Result = hNowhere;
                         break;
                         break;
-                    case HitTestMessage.HitTest.TopLeft:
-                    case HitTestMessage.HitTest.TopRight:
-                    case HitTestMessage.HitTest.BottomLeft:
-                    case HitTestMessage.HitTest.BottomRight:
+                    case HitTest.TopLeft:
+                    case HitTest.TopRight:
+                    case HitTest.BottomLeft:
+                    case HitTest.BottomRight:
                         if(!VerticalResizable || !HorizontalResizable) m.Result = hNowhere;
                         if(!VerticalResizable || !HorizontalResizable) m.Result = hNowhere;
                         break;
                         break;
                 }
                 }
             }
             }
         }
         }
+
+        const int WM_NCHITTEST = 0x84;//光标移动或鼠标按下、释放时的消息
+        /// <summary>鼠标击中位置</summary>
+        public enum HitTest : int
+        {
+            Error = -2,
+            Transparent = -1,
+            Nowhere = 0,
+            Client = 1,
+            TitleBar = 2,
+            SysMenu = 3,
+            Size = 4,
+            GrowBox = 5,
+            Hscroll = 6,
+            Vscroll = 7,
+            MinButton = 8,
+            MaxButton = 9,
+            Left = 10,
+            Right = 11,
+            Top = 12,
+            TopLeft = 13,
+            TopRight = 14,
+            Bottom = 15,
+            BottomLeft = 16,
+            BottomRight = 17,
+            Border = 18,
+            Close = 20,
+            Help = 21
+        }
     }
     }
 }
 }

+ 1 - 0
ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs

@@ -26,6 +26,7 @@ namespace BluePointLilac.Methods
             {
             {
                 foreach(DateTime time in new[] { downTime, upTime })
                 foreach(DateTime time in new[] { downTime, upTime })
                 {
                 {
+                    //避免ReleaseCapture影响控件的其他鼠标事件
                     if((DateTime.Now - time).TotalMilliseconds < 20) return;
                     if((DateTime.Now - time).TotalMilliseconds < 20) return;
                 }
                 }
                 if(e.Button == MouseButtons.Left)
                 if(e.Button == MouseButtons.Left)

+ 5 - 4
ContextMenuManager/BluePointLilac.Methods/IniWriter.cs

@@ -12,18 +12,17 @@ namespace BluePointLilac.Methods
         public IniWriter(string filePath)
         public IniWriter(string filePath)
         {
         {
             this.FilePath = filePath;
             this.FilePath = filePath;
-            if(File.Exists(FilePath)) this.Encoding = EncodingType.GetType(FilePath);
         }
         }
 
 
         public string FilePath { get; set; }
         public string FilePath { get; set; }
-        public Encoding Encoding { get; set; } = Encoding.Unicode;
+
         public bool DeleteFileWhenEmpty { get; set; }
         public bool DeleteFileWhenEmpty { get; set; }
 
 
         private List<string> GetLines()
         private List<string> GetLines()
         {
         {
             List<string> lines = new List<string>();
             List<string> lines = new List<string>();
             if(!File.Exists(FilePath)) return lines;
             if(!File.Exists(FilePath)) return lines;
-            using(StreamReader reader = new StreamReader(FilePath, Encoding))
+            using(StreamReader reader = new StreamReader(FilePath, EncodingType.GetType(FilePath)))
             {
             {
                 while(!reader.EndOfStream)
                 while(!reader.EndOfStream)
                 {
                 {
@@ -142,12 +141,14 @@ namespace BluePointLilac.Methods
             {
             {
                 Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
                 Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
                 FileAttributes attributes = FileAttributes.Normal;
                 FileAttributes attributes = FileAttributes.Normal;
+                Encoding encoding = Encoding.Unicode;
                 if(File.Exists(FilePath))
                 if(File.Exists(FilePath))
                 {
                 {
+                    encoding = EncodingType.GetType(FilePath);
                     attributes = File.GetAttributes(FilePath);
                     attributes = File.GetAttributes(FilePath);
                     File.SetAttributes(FilePath, FileAttributes.Normal);
                     File.SetAttributes(FilePath, FileAttributes.Normal);
                 }
                 }
-                File.WriteAllLines(FilePath, lines.ToArray(), Encoding);
+                File.WriteAllLines(FilePath, lines.ToArray(), encoding);
                 File.SetAttributes(FilePath, attributes);
                 File.SetAttributes(FilePath, attributes);
             }
             }
         }
         }

+ 18 - 27
ContextMenuManager/BluePointLilac.Methods/RichTextBoxExtension.cs

@@ -1,6 +1,5 @@
 using System;
 using System;
 using System.Drawing;
 using System.Drawing;
-using System.Text;
 using System.Windows.Forms;
 using System.Windows.Forms;
 using System.Xml.Linq;
 using System.Xml.Linq;
 
 
@@ -14,18 +13,17 @@ namespace BluePointLilac.Methods
         /// <param name="xmlStr">要显示的xml文本</param>
         /// <param name="xmlStr">要显示的xml文本</param>
         public static void LoadXml(this RichTextBox box, string xmlStr)
         public static void LoadXml(this RichTextBox box, string xmlStr)
         {
         {
-            try
-            {
-                xmlStr = XDocument.Parse(xmlStr).ToString().Trim();
-                if(string.IsNullOrEmpty(xmlStr)) return;
-            }
-            catch(Exception e) { throw e; }
-
             XmlStateMachine machine = new XmlStateMachine();
             XmlStateMachine machine = new XmlStateMachine();
             if(xmlStr.StartsWith("<?"))
             if(xmlStr.StartsWith("<?"))
             {
             {
                 string declaration = machine.GetXmlDeclaration(xmlStr);
                 string declaration = machine.GetXmlDeclaration(xmlStr);
-                if(declaration != string.Empty) xmlStr = declaration + Environment.NewLine + xmlStr;
+                try
+                {
+                    xmlStr = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace).ToString().Trim();
+                    if(string.IsNullOrEmpty(xmlStr) && declaration == string.Empty) return;
+                }
+                catch(Exception e) { throw e; }
+                xmlStr = declaration + Environment.NewLine + xmlStr;
             }
             }
 
 
             int location = 0;
             int location = 0;
@@ -33,7 +31,7 @@ namespace BluePointLilac.Methods
             int tokenTryCount = 0;
             int tokenTryCount = 0;
             while(location < xmlStr.Length)
             while(location < xmlStr.Length)
             {
             {
-                string token = machine.GetNextToken(xmlStr, location, out XmlTokenType ttype);
+                string token = machine.GetNextToken(xmlStr.Substring(location), out XmlTokenType ttype);
                 Color color = machine.GetTokenColor(ttype);
                 Color color = machine.GetTokenColor(ttype);
                 bool isBold = ttype == XmlTokenType.DocTypeName || ttype == XmlTokenType.NodeName;
                 bool isBold = ttype == XmlTokenType.DocTypeName || ttype == XmlTokenType.NodeName;
                 box.AppendText(token, color, isBold);
                 box.AppendText(token, color, isBold);
@@ -45,7 +43,7 @@ namespace BluePointLilac.Methods
                 if(failCount > 10 || tokenTryCount > xmlStr.Length)
                 if(failCount > 10 || tokenTryCount > xmlStr.Length)
                 {
                 {
                     string theRestOfIt = xmlStr.Substring(location, xmlStr.Length - location);
                     string theRestOfIt = xmlStr.Substring(location, xmlStr.Length - location);
-                    //this.AppendText(Environment.NewLine + Environment.NewLine + theRestOfIt); // DEBUG
+                    //box.AppendText(Environment.NewLine + Environment.NewLine + theRestOfIt); // DEBUG
                     box.AppendText(theRestOfIt);
                     box.AppendText(theRestOfIt);
                     break;
                     break;
                 }
                 }
@@ -100,13 +98,12 @@ namespace BluePointLilac.Methods
             private string subString = string.Empty;
             private string subString = string.Empty;
             private string token = string.Empty;
             private string token = string.Empty;
 
 
-            public string GetNextToken(string s, int location, out XmlTokenType ttype)
+            public string GetNextToken(string s, out XmlTokenType ttype)
             {
             {
                 ttype = XmlTokenType.Unknown;
                 ttype = XmlTokenType.Unknown;
                 // skip past any whitespace (token added to it at the end of method)
                 // skip past any whitespace (token added to it at the end of method)
-                string whitespace = GetWhitespace(s, location);
-                if(!string.IsNullOrEmpty(whitespace)) location += whitespace.Length;
-                subString = s.Substring(location, s.Length - location);
+                string whitespace = GetWhitespace(s);
+                subString = s.TrimStart();
                 token = string.Empty;
                 token = string.Empty;
                 if(CurrentState == XmlTokenType.CDataStart)
                 if(CurrentState == XmlTokenType.CDataStart)
                 {
                 {
@@ -459,22 +456,16 @@ namespace BluePointLilac.Methods
                 return commentValue;
                 return commentValue;
             }
             }
 
 
-            private string GetWhitespace(string s, int location)
+            private string GetWhitespace(string s)
             {
             {
-                bool foundWhitespace = false;
-                StringBuilder sb = new StringBuilder();
-                for(int i = 0; (location + i) < s.Length; i++)
+                string whitespace = "";
+                for(int i = 0; i < s.Length; i++)
                 {
                 {
-                    char c = s[location + i];
-                    if(char.IsWhiteSpace(c))
-                    {
-                        foundWhitespace = true;
-                        sb.Append(c);
-                    }
+                    char c = s[i];
+                    if(char.IsWhiteSpace(c)) whitespace += c;
                     else break;
                     else break;
                 }
                 }
-                if(foundWhitespace) return sb.ToString();
-                return string.Empty;
+                return whitespace;
             }
             }
         }
         }
 
 

+ 44 - 0
ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs

@@ -17,5 +17,49 @@ namespace BluePointLilac.Methods
                 box.Font = new Font(box.Font.FontFamily, size + (e.Delta > 0 ? 1 : -1));
                 box.Font = new Font(box.Font.FontFamily, size + (e.Delta > 0 ? 1 : -1));
             };
             };
         }
         }
+
+        /// <summary>TextBox在文字未超出边界时隐藏滚动条,超出时显示</summary>
+        public static void SetAutoShowScroll(this TextBox box, ScrollBars scrollBars)
+        {
+
+            void SetScrollVisible()
+            {
+                Size szBox = box.ClientSize;
+                Size szText = TextRenderer.MeasureText(box.Text, box.Font);
+                if((scrollBars | ScrollBars.Vertical) == ScrollBars.Vertical)
+                {
+                    if(szText.Height > szBox.Height)
+                    {
+                        box.ScrollBars = scrollBars | ScrollBars.Vertical;
+                    }
+                    else
+                    {
+                        box.ScrollBars = scrollBars & ~ScrollBars.Vertical;
+                    }
+                }
+                if((scrollBars | ScrollBars.Horizontal) == ScrollBars.Horizontal)
+                {
+                    if(szText.Width > szBox.Width)
+                    {
+                        box.ScrollBars = scrollBars | ScrollBars.Horizontal;
+                    }
+                    else
+                    {
+                        box.ScrollBars = scrollBars & ~ScrollBars.Horizontal;
+                    }
+                }
+            };
+            box.TextChanged += (sender, e) => SetScrollVisible();
+            box.FontChanged += (sender, e) => SetScrollVisible();
+            box.ClientSizeChanged += (sender, e) => SetScrollVisible();
+        }
+
+        public static void CanSelectAllWhenReadOnly(this TextBox box)
+        {
+            box.KeyDown += (sender, e) =>
+            {
+                if(box.ReadOnly && e.Control && e.KeyCode == Keys.A) box.SelectAll();
+            };
+        }
     }
     }
 }
 }

+ 0 - 4
ContextMenuManager/ContextMenuManager.csproj

@@ -114,10 +114,6 @@
   <ItemGroup>
   <ItemGroup>
     <Compile Include="AppConfig.cs" />
     <Compile Include="AppConfig.cs" />
     <Compile Include="AppDic.cs" />
     <Compile Include="AppDic.cs" />
-    <Compile Include="BluePointLilac.Controls\HitTestMessage.cs" />
-    <Compile Include="BluePointLilac.Controls\MyBorderForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
     <Compile Include="BluePointLilac.Controls\MyToolTip.cs" />
     <Compile Include="BluePointLilac.Controls\MyToolTip.cs" />
     <Compile Include="BluePointLilac.Controls\ReadOnlyTextBox.cs">
     <Compile Include="BluePointLilac.Controls\ReadOnlyTextBox.cs">
       <SubType>Component</SubType>
       <SubType>Component</SubType>

+ 6 - 2
ContextMenuManager/Controls/AboutApp.cs

@@ -165,13 +165,15 @@ namespace ContextMenuManager.Controls
         {
         {
             this.Dock = DockStyle.Fill;
             this.Dock = DockStyle.Fill;
             this.Font = new Font(SystemFonts.MenuFont.FontFamily, 10F);
             this.Font = new Font(SystemFonts.MenuFont.FontFamily, 10F);
-            this.Controls.AddRange(new Control[] { cmbLanguages, btnOpenDir, btnDownLoad, txtTranslators });
+            this.Controls.AddRange(new Control[] { cmbLanguages, btnOpenDir, btnDownLoad, btnTranslate, txtTranslators });
             cmbLanguages.SelectionChangeCommitted += (sender, e) => ChangeLanguage();
             cmbLanguages.SelectionChangeCommitted += (sender, e) => ChangeLanguage();
             btnDownLoad.MouseDown += (sender, e) => ExternalProgram.OpenUrl(OtherLanguagesUrl);
             btnDownLoad.MouseDown += (sender, e) => ExternalProgram.OpenUrl(OtherLanguagesUrl);
             btnOpenDir.MouseDown += (sender, e) => ExternalProgram.JumpExplorer(AppConfig.LangsDir);
             btnOpenDir.MouseDown += (sender, e) => ExternalProgram.JumpExplorer(AppConfig.LangsDir);
             btnTranslate.MouseDown += (sender, e) => new TranslateDialog().ShowDialog();
             btnTranslate.MouseDown += (sender, e) => new TranslateDialog().ShowDialog();
             MyToolTip.SetToolTip(btnOpenDir, AppString.Tip.OpenLanguagesDir);
             MyToolTip.SetToolTip(btnOpenDir, AppString.Tip.OpenLanguagesDir);
             MyToolTip.SetToolTip(btnDownLoad, AppString.Tip.OtherLanguages);
             MyToolTip.SetToolTip(btnDownLoad, AppString.Tip.OtherLanguages);
+            MyToolTip.SetToolTip(btnTranslate, AppString.Dialog.TranslateTool);
+            txtTranslators.SetAutoShowScroll(ScrollBars.Vertical);
             this.OnResize(null);
             this.OnResize(null);
         }
         }
 
 
@@ -207,12 +209,14 @@ namespace ContextMenuManager.Controls
                 languages.Clear();
                 languages.Clear();
                 foreach(string fileName in Directory.GetFiles(AppConfig.LangsDir, "*.ini"))
                 foreach(string fileName in Directory.GetFiles(AppConfig.LangsDir, "*.ini"))
                 {
                 {
-                    languages.Add(Path.GetFileNameWithoutExtension(fileName));
+                    string langName = Path.GetFileNameWithoutExtension(fileName);
                     IniReader reader = new IniReader(fileName);
                     IniReader reader = new IniReader(fileName);
                     string language = reader.GetValue("General", "Language");
                     string language = reader.GetValue("General", "Language");
+                    if(language.IsNullOrWhiteSpace()) language = langName;
                     string translator = reader.GetValue("General", "Translator");
                     string translator = reader.GetValue("General", "Translator");
                     str += Environment.NewLine + language + new string('\t', 5) + translator;
                     str += Environment.NewLine + language + new string('\t', 5) + translator;
                     cmbLanguages.Items.Add(language);
                     cmbLanguages.Items.Add(language);
+                    languages.Add(langName);
                 }
                 }
             }
             }
             txtTranslators.Text = str;
             txtTranslators.Text = str;

+ 3 - 3
ContextMenuManager/Controls/EnhanceMenusList.cs

@@ -143,7 +143,7 @@ namespace ContextMenuManager.Controls
                 {
                 {
                     if(!tip.IsNullOrWhiteSpace()) tip += "\n";
                     if(!tip.IsNullOrWhiteSpace()) tip += "\n";
                     tip += AppString.Tip.CommandFiles;
                     tip += AppString.Tip.CommandFiles;
-                    if(System.Diagnostics.Debugger.IsAttached) item.ChkVisible.Checked = item.ItemVisible = true;
+                    if(System.Diagnostics.Debugger.IsAttached) item.ChkVisible.Checked = item.ItemVisible = true;//调试状态
                 }
                 }
                 MyToolTip.SetToolTip(item.ChkVisible, tip);
                 MyToolTip.SetToolTip(item.ChkVisible, tip);
                 this.AddItem(item);
                 this.AddItem(item);
@@ -175,7 +175,7 @@ namespace ContextMenuManager.Controls
 
 
         public static bool JudgeOSVersion(XmlElement itemXE)
         public static bool JudgeOSVersion(XmlElement itemXE)
         {
         {
-            if(System.Diagnostics.Debugger.IsAttached) return true;//调试状态
+            //if(System.Diagnostics.Debugger.IsAttached) return true;//调试状态
             bool JudgeOne(XmlElement osXE)
             bool JudgeOne(XmlElement osXE)
             {
             {
                 Version ver = new Version(osXE.InnerText);
                 Version ver = new Version(osXE.InnerText);
@@ -208,7 +208,7 @@ namespace ContextMenuManager.Controls
 
 
         private static bool FileExists(XmlElement itemXE)
         private static bool FileExists(XmlElement itemXE)
         {
         {
-            if(System.Diagnostics.Debugger.IsAttached) return true;//调试状态
+            //if(System.Diagnostics.Debugger.IsAttached) return true;//调试状态
             foreach(XmlElement feXE in itemXE.SelectNodes("FileExists"))
             foreach(XmlElement feXE in itemXE.SelectNodes("FileExists"))
             {
             {
                 string path = Environment.ExpandEnvironmentVariables(feXE.InnerText);
                 string path = Environment.ExpandEnvironmentVariables(feXE.InnerText);

+ 6 - 2
ContextMenuManager/Controls/GuidBlockedItem.cs

@@ -6,7 +6,7 @@ using System.Windows.Forms;
 
 
 namespace ContextMenuManager.Controls
 namespace ContextMenuManager.Controls
 {
 {
-    class GuidBlockedItem : MyListItem, IBtnDeleteItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiGuidItem
+    class GuidBlockedItem : MyListItem, IBtnDeleteItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiGuidItem, ITsiRegPathItem
     {
     {
         public GuidBlockedItem(string value)
         public GuidBlockedItem(string value)
         {
         {
@@ -28,6 +28,8 @@ namespace ContextMenuManager.Controls
 
 
         public string Value { get; set; }
         public string Value { get; set; }
         public Guid Guid { get; set; }
         public Guid Guid { get; set; }
+        public string ValueName => Value;
+        public string RegPath => GuidBlockedList.HKLMBLOCKED;
 
 
         public string ItemText
         public string ItemText
         {
         {
@@ -56,6 +58,7 @@ namespace ContextMenuManager.Controls
         public FileLocationMenuItem TsiFileLocation { get; set; }
         public FileLocationMenuItem TsiFileLocation { get; set; }
         public FilePropertiesMenuItem TsiFileProperties { get; set; }
         public FilePropertiesMenuItem TsiFileProperties { get; set; }
         public HandleGuidMenuItem TsiHandleGuid { get; set; }
         public HandleGuidMenuItem TsiHandleGuid { get; set; }
+        public RegLocationMenuItem TsiRegLocation { get; set; }
 
 
         readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);
         readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);
 
 
@@ -66,12 +69,13 @@ namespace ContextMenuManager.Controls
             TsiSearch = new WebSearchMenuItem(this);
             TsiSearch = new WebSearchMenuItem(this);
             TsiFileProperties = new FilePropertiesMenuItem(this);
             TsiFileProperties = new FilePropertiesMenuItem(this);
             TsiFileLocation = new FileLocationMenuItem(this);
             TsiFileLocation = new FileLocationMenuItem(this);
+            TsiRegLocation = new RegLocationMenuItem(this);
             TsiHandleGuid = new HandleGuidMenuItem(this, false);
             TsiHandleGuid = new HandleGuidMenuItem(this, false);
 
 
             ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiHandleGuid,
             ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiHandleGuid,
                 new ToolStripSeparator(), TsiDetails });
                 new ToolStripSeparator(), TsiDetails });
             TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,
             TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,
-                new ToolStripSeparator(), TsiFileProperties, TsiFileLocation});
+                new ToolStripSeparator(), TsiFileProperties, TsiFileLocation, TsiRegLocation});
 
 
             MyToolTip.SetToolTip(BtnDelete, AppString.Menu.Delete);
             MyToolTip.SetToolTip(BtnDelete, AppString.Menu.Delete);
         }
         }

+ 11 - 6
ContextMenuManager/Controls/GuidBlockedList.cs

@@ -23,14 +23,19 @@ namespace ContextMenuManager.Controls
         private void LoadBlockedItems()
         private void LoadBlockedItems()
         {
         {
             List<string> values = new List<string>();
             List<string> values = new List<string>();
-            Array.ForEach(BlockedPaths, path =>
+            foreach(string path in BlockedPaths)
             {
             {
                 using(RegistryKey key = RegistryEx.GetRegistryKey(path))
                 using(RegistryKey key = RegistryEx.GetRegistryKey(path))
-                    if(key != null) values.AddRange(key.GetValueNames());
-            });
-            Array.ForEach(values.Distinct(StringComparer.OrdinalIgnoreCase).ToArray(), value =>
-                this.AddItem(new GuidBlockedItem(value))
-            );
+                {
+                    if(key == null) continue;
+                    foreach(string value in key.GetValueNames())
+                    {
+                        if(values.Contains(value, StringComparer.OrdinalIgnoreCase)) continue;
+                        this.AddItem(new GuidBlockedItem(value));
+                        values.Add(value);
+                    }
+                }
+            }
         }
         }
 
 
         private void AddNewItem()
         private void AddNewItem()

+ 11 - 5
ContextMenuManager/Controls/NewShellDialog.cs

@@ -73,11 +73,15 @@ namespace ContextMenuManager.Controls
 
 
                 rdoMulti.CheckedChanged += (sender, e) =>
                 rdoMulti.CheckedChanged += (sender, e) =>
                 {
                 {
-                    if(WindowsOsVersion.IsEqualVista && rdoMulti.Checked)
+                    if(rdoMulti.Checked)
                     {
                     {
-                        MessageBoxEx.Show(AppString.MessageBox.VistaUnsupportedMulti);
-                        rdoSingle.Checked = true;
-                        return;
+                        chkSE.Checked = false;
+                        if(WindowsOsVersion.IsEqualVista)
+                        {
+                            MessageBoxEx.Show(AppString.MessageBox.VistaUnsupportedMulti);
+                            rdoSingle.Checked = true;
+                            return;
+                        }
                     }
                     }
                     lblCommand.Enabled = txtFilePath.Enabled = lblArguments.Enabled
                     lblCommand.Enabled = txtFilePath.Enabled = lblArguments.Enabled
                     = txtArguments.Enabled = btnBrowse.Enabled = chkSE.Enabled = !rdoMulti.Checked;
                     = txtArguments.Enabled = btnBrowse.Enabled = chkSE.Enabled = !rdoMulti.Checked;
@@ -126,9 +130,11 @@ namespace ContextMenuManager.Controls
                     if(Array.FindIndex(DirScenePaths, path
                     if(Array.FindIndex(DirScenePaths, path
                        => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)
                        => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)
                     {
                     {
-                        if(!Arguments.IsNullOrWhiteSpace()) Arguments += " ";
                         if(ScenePath != ShellList.MENUPATH_BACKGROUND)
                         if(ScenePath != ShellList.MENUPATH_BACKGROUND)
+                        {
+                            if(!Arguments.IsNullOrWhiteSpace()) Arguments += " ";
                             Arguments += "\"%V\"";//自动加目录后缀
                             Arguments += "\"%V\"";//自动加目录后缀
+                        }
                     }
                     }
                     else if(Array.FindIndex(FileObjectsScenePaths, path
                     else if(Array.FindIndex(FileObjectsScenePaths, path
                        => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)
                        => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)

+ 192 - 17
ContextMenuManager/Controls/TranslateDialog.cs

@@ -1,7 +1,10 @@
 using BluePointLilac.Methods;
 using BluePointLilac.Methods;
 using System;
 using System;
+using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing;
+using System.IO;
 using System.Linq;
 using System.Linq;
+using System.Text;
 using System.Windows.Forms;
 using System.Windows.Forms;
 
 
 namespace ContextMenuManager.Controls
 namespace ContextMenuManager.Controls
@@ -14,8 +17,7 @@ namespace ContextMenuManager.Controls
         {
         {
             using(TranslateForm frm = new TranslateForm())
             using(TranslateForm frm = new TranslateForm())
             {
             {
-                bool flag = frm.ShowDialog() == DialogResult.OK;
-                return flag;
+                return frm.ShowDialog() == DialogResult.OK;
             }
             }
         }
         }
 
 
@@ -23,26 +25,53 @@ namespace ContextMenuManager.Controls
         {
         {
             public TranslateForm()
             public TranslateForm()
             {
             {
-                this.ShowIcon = this.ShowInTaskbar = false;
-                this.MaximizeBox = this.MinimizeBox = false;
                 this.SizeGripStyle = SizeGripStyle.Hide;
                 this.SizeGripStyle = SizeGripStyle.Hide;
+                this.Text = AppString.Dialog.TranslateTool;
                 this.StartPosition = FormStartPosition.CenterParent;
                 this.StartPosition = FormStartPosition.CenterParent;
+                this.ShowIcon = this.ShowInTaskbar = this.MinimizeBox = false;
                 this.Font = new Font(SystemFonts.MessageBoxFont.FontFamily, 10F);
                 this.Font = new Font(SystemFonts.MessageBoxFont.FontFamily, 10F);
-                cmbSections.Width = cmbKeys.Width = 200.DpiZoom();
-                cmbSections.Left = cmbSections.Top = cmbKeys.Top = 20.DpiZoom();
-                cmbKeys.Left = cmbSections.Right + 20.DpiZoom();
-                this.Width = cmbKeys.Right + 20.DpiZoom();
-                this.Controls.AddRange(new Control[] { cmbSections, cmbKeys });
-                cmbSections.Items.AddRange(AppString.DefaultLanguage.RootDic.Keys.ToArray());
-                cmbSections.SelectedIndexChanged += (sender, e) =>
-                {
-                    cmbKeys.Items.Clear();
-                    cmbKeys.Items.AddRange(AppString.DefaultLanguage.RootDic[cmbSections.Text].Keys.ToArray());
-                    cmbKeys.SelectedIndex = 0;
-                };
-                cmbSections.SelectedIndex = 0;
+                this.InitializeComponents();
             }
             }
 
 
+            readonly Label lblSections = new Label
+            {
+                AutoSize = true,
+                Text = "Section"
+            };
+            readonly Label lblKeys = new Label
+            {
+                AutoSize = true,
+                Text = "Key"
+            };
+            readonly Label lblDefault = new Label
+            {
+                Text = AppString.Dialog.DefaultText,
+                AutoSize = true
+            };
+            readonly Label lblOld = new Label
+            {
+                Text = AppString.Dialog.OldTranslation,
+                AutoSize = true
+            };
+            readonly Label lblNew = new Label
+            {
+                Text = AppString.Dialog.NewTranslation,
+                AutoSize = true
+            };
+            readonly TextBox txtDefault = new TextBox
+            {
+                Multiline = true,
+                ReadOnly = true
+            };
+            readonly TextBox txtOld = new TextBox
+            {
+                Multiline = true,
+                ReadOnly = true
+            };
+            readonly TextBox txtNew = new TextBox
+            {
+                Multiline = true
+            };
             readonly ComboBox cmbSections = new ComboBox
             readonly ComboBox cmbSections = new ComboBox
             {
             {
                 DropDownStyle = ComboBoxStyle.DropDownList
                 DropDownStyle = ComboBoxStyle.DropDownList
@@ -51,6 +80,152 @@ namespace ContextMenuManager.Controls
             {
             {
                 DropDownStyle = ComboBoxStyle.DropDownList
                 DropDownStyle = ComboBoxStyle.DropDownList
             };
             };
+            readonly Button btnBrowse = new Button
+            {
+                Text = AppString.Dialog.Browse,
+                AutoSize = true
+            };
+            readonly Button btnSave = new Button
+            {
+                Text = AppString.Menu.Save,
+                AutoSize = true
+            };
+            readonly Button btnCancel = new Button
+            {
+                DialogResult = DialogResult.Cancel,
+                Text = AppString.Dialog.Cancel,
+                AutoSize = true
+            };
+
+            static TranslateForm()
+            {
+                foreach(string section in DefaultDic.Keys)
+                {
+                    var dic = new Dictionary<string, string>();
+                    foreach(string key in DefaultDic[section].Keys)
+                    {
+                        dic.Add(key, string.Empty);
+                    }
+                    EditingDic.Add(section, dic);
+                }
+            }
+
+            static readonly Dictionary<string, Dictionary<string, string>> EditingDic
+                = new Dictionary<string, Dictionary<string, string>>();
+            static readonly Dictionary<string, Dictionary<string, string>> DefaultDic
+                = AppString.DefaultLanguage.RootDic;
+
+            static readonly IniWriter ReferentialWirter = new IniWriter();
+
+            private string Section => cmbSections.Text;
+            private string Key => cmbKeys.Text;
+
+            private void InitializeComponents()
+            {
+                this.Controls.AddRange(new Control[] { lblSections, cmbSections, lblKeys,
+                    cmbKeys, lblDefault, txtDefault, lblOld, txtOld, lblNew,
+                    txtNew, btnBrowse, btnSave, btnCancel });
+
+                txtDefault.SetAutoShowScroll(ScrollBars.Vertical);
+                txtOld.SetAutoShowScroll(ScrollBars.Vertical);
+                txtNew.SetAutoShowScroll(ScrollBars.Vertical);
+                txtDefault.CanSelectAllWhenReadOnly();
+                txtOld.CanSelectAllWhenReadOnly();
+
+                int a = 20.DpiZoom();
+
+                lblSections.Top = lblSections.Left = cmbSections.Top = lblKeys.Left
+                    = lblDefault.Left = lblOld.Left = lblNew.Left = btnBrowse.Left = a;
+
+                lblKeys.Top = cmbKeys.Top = cmbSections.Bottom + a;
+                lblDefault.Top = txtDefault.Top = cmbKeys.Bottom + a;
+                txtDefault.Height = txtOld.Height = txtNew.Height = 4 * a;
+                cmbSections.Width = cmbKeys.Width = txtDefault.Width = txtOld.Width = txtNew.Width = 20 * a;
+
+                int h = cmbSections.Height + cmbKeys.Height + btnBrowse.Height;
+                int[] ws = { lblSections.Width, lblKeys.Width, lblDefault.Width, lblOld.Width, lblNew.Width };
+                int w = ws.Max();
+
+                cmbSections.Left = cmbKeys.Left = txtDefault.Left = txtOld.Left = txtNew.Left = w + 2 * a;
+
+                this.Resize += (sender, e) =>
+                {
+                    txtDefault.Height = txtOld.Height = txtNew.Height
+                        = (this.ClientSize.Height - h - 7 * a) / 3;
+
+                    lblOld.Top = txtOld.Top = txtDefault.Bottom + a;
+                    lblNew.Top = txtNew.Top = txtOld.Bottom + a;
+                    btnBrowse.Top = btnSave.Top = btnCancel.Top = txtNew.Bottom + a;
+
+                    cmbSections.Width = cmbKeys.Width = txtDefault.Width = txtOld.Width = txtNew.Width
+                        = this.ClientSize.Width - (w + 3 * a);
+
+                    btnCancel.Left = this.ClientSize.Width - btnCancel.Width - a;
+                    btnSave.Left = btnCancel.Left - btnSave.Width - 2 * a;
+                    btnBrowse.Left = btnSave.Left - btnBrowse.Width - 2 * a;
+                };
+                this.ClientSize = new Size(w + 23 * a, h + 3 * 4 * a + 7 * a);
+                this.MinimumSize = this.Size;
+
+                cmbSections.Items.AddRange(DefaultDic.Keys.ToArray());
+                cmbSections.SelectedIndexChanged += (sender, e) =>
+                {
+                    cmbKeys.Items.Clear();
+                    cmbKeys.Items.AddRange(DefaultDic[Section].Keys.ToArray());
+                    cmbKeys.SelectedIndex = 0;
+                };
+                cmbKeys.SelectedIndexChanged += (sender, e) =>
+                {
+                    txtNew.Text = EditingDic[Section][Key].Replace("\\n", Environment.NewLine);
+                    txtDefault.Text = DefaultDic[Section][Key].Replace("\\n", Environment.NewLine);
+                    txtOld.Text = ReferentialWirter.GetValue(Section, Key).Replace("\\n", Environment.NewLine);
+                };
+                cmbSections.SelectedIndex = 0;
+
+                txtOld.TextChanged += (sender, e) => { if(txtNew.Text == string.Empty) txtNew.Text = txtOld.Text; };
+                txtNew.TextChanged += (sender, e) => EditingDic[Section][Key] = txtNew.Text.Replace(Environment.NewLine, "\\n");
+                btnBrowse.Click += (sender, e) => SelectFile();
+                btnSave.Click += (sender, e) => Save();
+            }
+
+            private void SelectFile()
+            {
+                using(OpenFileDialog dlg = new OpenFileDialog())
+                {
+                    dlg.InitialDirectory = AppConfig.LangsDir;
+                    dlg.Filter = $"{AppString.SideBar.AppLanguage}|*.ini";
+                    if(dlg.ShowDialog() != DialogResult.OK) return;
+                    ReferentialWirter.FilePath = dlg.FileName;
+                    txtOld.Text = ReferentialWirter.GetValue(Section, Key).Replace("\\n", "\n");
+                }
+            }
+
+            private void Save()
+            {
+                using(SaveFileDialog dlg = new SaveFileDialog())
+                {
+                    string language = EditingDic["General"]["Language"];
+                    int index = language.IndexOf(' ');
+                    if(index > 0) language = language.Substring(0, index);
+                    dlg.FileName = $"{language}.ini";
+                    dlg.InitialDirectory = AppConfig.LangsDir;
+                    dlg.Filter = $"{AppString.SideBar.AppLanguage}|*.ini";
+                    if(dlg.ShowDialog() != DialogResult.OK) return;
+
+                    string contents = string.Empty;
+                    foreach(string section in EditingDic.Keys)
+                    {
+                        contents += $"[{section}]" + Environment.NewLine;
+                        foreach(string key in EditingDic[section].Keys)
+                        {
+                            string value = EditingDic[section][key];
+                            contents += $"{key} = {value}" + Environment.NewLine;
+                        }
+                        contents += Environment.NewLine;
+                    }
+                    File.WriteAllText(dlg.FileName, contents, Encoding.Unicode);
+                }
+            }
         }
         }
     }
     }
 }
 }

+ 4 - 0
ContextMenuManager/Properties/Resources/Texts/AppLanguageDic.ini

@@ -159,6 +159,10 @@ SelectDirectoryType = 请选择一个目录感知类型
 SelectGroup = 请选择保存分组
 SelectGroup = 请选择保存分组
 SelectNewItemType = 请选择新建菜单类型
 SelectNewItemType = 请选择新建菜单类型
 SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\n①该多级菜单的所有子菜单项目私有(推荐),\n②该多级菜单可与其他多级菜单引用相同子项,\n请做出你的选择......
 SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\n①该多级菜单的所有子菜单项目私有(推荐),\n②该多级菜单可与其他多级菜单引用相同子项,\n请做出你的选择......
+TranslateTool = 翻译器
+DefaultText = 默认文本
+OldTranslation = 旧译文
+NewTranslation = 新译文
 
 
 [MessageBox]
 [MessageBox]
 TextCannotBeEmpty = 菜单文本不能为空!
 TextCannotBeEmpty = 菜单文本不能为空!

+ 3 - 3
ContextMenuManager/Updater.cs

@@ -54,8 +54,8 @@ namespace ContextMenuManager
             Version version2 = new Version(Application.ProductVersion);
             Version version2 = new Version(Application.ProductVersion);
             if(version1.CompareTo(version2) > 0)
             if(version1.CompareTo(version2) > 0)
             {
             {
-                string info = reader.GetValue("Update", "Info").Replace("\\n", "\n");
-                if(MessageBoxEx.Show($"{AppString.MessageBox.UpdateApp}{version1}\n{info}",
+                string info = reader.GetValue("Update", "Info").Replace("\\n", Environment.NewLine);
+                if(MessageBoxEx.Show($"{AppString.MessageBox.UpdateApp}{version1}{Environment.NewLine}{info}",
                     MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                     MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                 {
                 {
                     string url = reader.GetValue("Update", "Url");
                     string url = reader.GetValue("Update", "Url");
@@ -70,7 +70,7 @@ namespace ContextMenuManager
         {
         {
             string contents = GetWebString(url);
             string contents = GetWebString(url);
             if(!contents.IsNullOrWhiteSpace())
             if(!contents.IsNullOrWhiteSpace())
-                File.WriteAllText(filePath, contents.Replace("\n", "\r\n"), Encoding.Unicode);
+                File.WriteAllText(filePath, contents.Replace("\n", Environment.NewLine), Encoding.Unicode);
         }
         }
 
 
         private static string GetWebString(string url)
         private static string GetWebString(string url)

+ 5 - 3
Donate.md

@@ -8,9 +8,9 @@
 
 
 ## 捐赠名单
 ## 捐赠名单
 
 
-> 此名单不定期更新(上次更新:**2021-03-13**)
+> 此名单不定期更新(上次更新:**2021-03-16**)
 
 
-> 累计金额:**358.54** 元,累计人次:**59** 人次
+> 累计金额:**366.64** 元,累计人次:**62** 人次
 
 
 |日期|用户ID|平台|金额|备注
 |日期|用户ID|平台|金额|备注
 |:--:|:--:|:--:|:--:|:--:
 |:--:|:--:|:--:|:--:|:--:
@@ -73,4 +73,6 @@
 |2020-03-12|*禹|支付宝|5|
 |2020-03-12|*禹|支付宝|5|
 |2020-03-12|*游|微信|50|谢谢您的软件
 |2020-03-12|*游|微信|50|谢谢您的软件
 |2020-03-13|k*h|微信|6.66|右键管理强迫症福音
 |2020-03-13|k*h|微信|6.66|右键管理强迫症福音
-|2020-03-13|*🍊|微信|10|软件好用,十分感谢!
+|2020-03-13|*🍊|微信|10|软件好用,十分感谢!
+|2020-03-16|**骏|支付宝|0.1|
+|2020-03-16|**华|支付宝|5|

+ 1 - 1
languages/en-US.ini

@@ -18,7 +18,7 @@ About = About
 [SideBar]
 [SideBar]
 File = File
 File = File
 Folder = Folder
 Folder = Folder
-Directory = File directory
+Directory = Directory
 Background = Background
 Background = Background
 Desktop = Desktop
 Desktop = Desktop
 Drive = Disk
 Drive = Disk

+ 5 - 1
languages/zh-CN.ini

@@ -1,4 +1,4 @@
-;此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典
+;此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典
 ;翻译:可帮助作者为此程序提供翻译并提交到Github,以下内容中等号右侧内容替换为翻译文本,
 ;翻译:可帮助作者为此程序提供翻译并提交到Github,以下内容中等号右侧内容替换为翻译文本,
 ;General-Translator为翻译贡献者,General-Language为语言名称,如en-US 美国英语
 ;General-Translator为翻译贡献者,General-Language为语言名称,如en-US 美国英语
 ;翻译文件保存在Config\languages目录中,文件名保存为en-US.ini
 ;翻译文件保存在Config\languages目录中,文件名保存为en-US.ini
@@ -159,6 +159,10 @@ SelectDirectoryType = 请选择一个目录感知类型
 SelectGroup = 请选择保存分组
 SelectGroup = 请选择保存分组
 SelectNewItemType = 请选择新建菜单类型
 SelectNewItemType = 请选择新建菜单类型
 SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\n①该多级菜单的所有子菜单项目私有(推荐),\n②该多级菜单可与其他多级菜单引用相同子项,\n请做出你的选择......
 SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\n①该多级菜单的所有子菜单项目私有(推荐),\n②该多级菜单可与其他多级菜单引用相同子项,\n请做出你的选择......
+TranslateTool = 翻译器
+DefaultText = 默认文本
+OldTranslation = 旧译文
+NewTranslation = 新译文
 
 
 [MessageBox]
 [MessageBox]
 TextCannotBeEmpty = 菜单文本不能为空!
 TextCannotBeEmpty = 菜单文本不能为空!