Browse Source

收藏栏

CaptB 4 months ago
parent
commit
772336b9ff
8 changed files with 551 additions and 23 deletions
  1. 6 0
      App.config
  2. 25 0
      EdgeVoyager.csproj
  3. 18 18
      Form1.Designer.cs
  4. 143 5
      Form1.cs
  5. 72 0
      favoritesMenuItem.Designer.cs
  6. 123 0
      favoritesMenuItem.resx
  7. 63 0
      favoritesMenuItemIcon.Designer.cs
  8. 101 0
      favoritesMenuItemIcon.resx

+ 6 - 0
App.config

@@ -2,10 +2,16 @@
 <configuration>
 <configuration>
     <configSections>
     <configSections>
         <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
         <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="EdgeVoyager.favoritesMenuItem" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
             <section name="EdgeVoyager.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
             <section name="EdgeVoyager.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
         </sectionGroup>
         </sectionGroup>
     </configSections>
     </configSections>
     <userSettings>
     <userSettings>
+        <EdgeVoyager.favoritesMenuItem>
+            <setting name="设置" serializeAs="String">
+                <value>1</value>
+            </setting>
+        </EdgeVoyager.favoritesMenuItem>
         <EdgeVoyager.Settings1>
         <EdgeVoyager.Settings1>
             <setting name="firstwindow" serializeAs="String">
             <setting name="firstwindow" serializeAs="String">
                 <value>True</value>
                 <value>True</value>

+ 25 - 0
EdgeVoyager.csproj

@@ -16,11 +16,26 @@
 访问https://dev.lykns.com.cn/EdgeVoyager_Project/EdgeVoyager获取更多信息。</Description>
 访问https://dev.lykns.com.cn/EdgeVoyager_Project/EdgeVoyager获取更多信息。</Description>
   </PropertyGroup>
   </PropertyGroup>
 
 
+  <ItemGroup>
+    <EmbeddedResource Remove="favoritesMenuItem.resx" />
+    <EmbeddedResource Remove="favoritesMenuItemIcon.resx" />
+  </ItemGroup>
+
   <ItemGroup>
   <ItemGroup>
     <None Remove="index.html" />
     <None Remove="index.html" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>
+    <Content Include="favoritesMenuItem.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>favoritesMenuItem.Designer.cs</LastGenOutput>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="favoritesMenuItemIcon.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>favoritesMenuItemIcon.Designer.cs</LastGenOutput>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
     <Content Include="Resources\icons8_connection_status_on.ico" />
     <Content Include="Resources\icons8_connection_status_on.ico" />
   </ItemGroup>
   </ItemGroup>
 
 
@@ -29,6 +44,16 @@
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>
+    <Compile Update="favoritesMenuItem.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>favoritesMenuItem.resx</DependentUpon>
+    </Compile>
+    <Compile Update="favoritesMenuItemIcon.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>favoritesMenuItemIcon.resx</DependentUpon>
+    </Compile>
     <Compile Update="Properties\Resources.Designer.cs">
     <Compile Update="Properties\Resources.Designer.cs">
       <DesignTime>True</DesignTime>
       <DesignTime>True</DesignTime>
       <AutoGen>True</AutoGen>
       <AutoGen>True</AutoGen>

+ 18 - 18
Form1.Designer.cs

@@ -404,7 +404,6 @@
             // 
             // 
             // 全选AToolStripMenuItem
             // 全选AToolStripMenuItem
             // 
             // 
-            全选AToolStripMenuItem.Enabled = false;
             全选AToolStripMenuItem.Image = Properties.Resources.select_all_files_16px;
             全选AToolStripMenuItem.Image = Properties.Resources.select_all_files_16px;
             全选AToolStripMenuItem.Name = "全选AToolStripMenuItem";
             全选AToolStripMenuItem.Name = "全选AToolStripMenuItem";
             全选AToolStripMenuItem.Size = new Size(180, 22);
             全选AToolStripMenuItem.Size = new Size(180, 22);
@@ -423,6 +422,7 @@
             查找FToolStripMenuItem.Name = "查找FToolStripMenuItem";
             查找FToolStripMenuItem.Name = "查找FToolStripMenuItem";
             查找FToolStripMenuItem.Size = new Size(180, 22);
             查找FToolStripMenuItem.Size = new Size(180, 22);
             查找FToolStripMenuItem.Text = "查找(&F)";
             查找FToolStripMenuItem.Text = "查找(&F)";
+            查找FToolStripMenuItem.Click += 查找FToolStripMenuItem_Click;
             // 
             // 
             // 查看VToolStripMenuItem
             // 查看VToolStripMenuItem
             // 
             // 
@@ -437,40 +437,40 @@
             工具栏ToolStripMenuItem.CheckOnClick = true;
             工具栏ToolStripMenuItem.CheckOnClick = true;
             工具栏ToolStripMenuItem.CheckState = CheckState.Checked;
             工具栏ToolStripMenuItem.CheckState = CheckState.Checked;
             工具栏ToolStripMenuItem.Name = "工具栏ToolStripMenuItem";
             工具栏ToolStripMenuItem.Name = "工具栏ToolStripMenuItem";
-            工具栏ToolStripMenuItem.Size = new Size(120, 22);
+            工具栏ToolStripMenuItem.Size = new Size(180, 22);
             工具栏ToolStripMenuItem.Text = "工具栏";
             工具栏ToolStripMenuItem.Text = "工具栏";
             工具栏ToolStripMenuItem.CheckStateChanged += 工具栏ToolStripMenuItem_CheckStateChanged;
             工具栏ToolStripMenuItem.CheckStateChanged += 工具栏ToolStripMenuItem_CheckStateChanged;
             // 
             // 
             // toolStripSeparator8
             // toolStripSeparator8
             // 
             // 
             toolStripSeparator8.Name = "toolStripSeparator8";
             toolStripSeparator8.Name = "toolStripSeparator8";
-            toolStripSeparator8.Size = new Size(117, 6);
+            toolStripSeparator8.Size = new Size(177, 6);
             // 
             // 
             // 刷新RToolStripMenuItem
             // 刷新RToolStripMenuItem
             // 
             // 
             刷新RToolStripMenuItem.Name = "刷新RToolStripMenuItem";
             刷新RToolStripMenuItem.Name = "刷新RToolStripMenuItem";
-            刷新RToolStripMenuItem.Size = new Size(120, 22);
+            刷新RToolStripMenuItem.Size = new Size(180, 22);
             刷新RToolStripMenuItem.Text = "刷新(&R)";
             刷新RToolStripMenuItem.Text = "刷新(&R)";
             刷新RToolStripMenuItem.Click += 刷新RToolStripMenuItem_Click;
             刷新RToolStripMenuItem.Click += 刷新RToolStripMenuItem_Click;
             // 
             // 
             // 停止TToolStripMenuItem
             // 停止TToolStripMenuItem
             // 
             // 
             停止TToolStripMenuItem.Name = "停止TToolStripMenuItem";
             停止TToolStripMenuItem.Name = "停止TToolStripMenuItem";
-            停止TToolStripMenuItem.Size = new Size(120, 22);
+            停止TToolStripMenuItem.Size = new Size(180, 22);
             停止TToolStripMenuItem.Text = "停止(&O)";
             停止TToolStripMenuItem.Text = "停止(&O)";
             停止TToolStripMenuItem.Click += 停止TToolStripMenuItem_Click;
             停止TToolStripMenuItem.Click += 停止TToolStripMenuItem_Click;
             // 
             // 
             // 前进QToolStripMenuItem
             // 前进QToolStripMenuItem
             // 
             // 
             前进QToolStripMenuItem.Name = "前进QToolStripMenuItem";
             前进QToolStripMenuItem.Name = "前进QToolStripMenuItem";
-            前进QToolStripMenuItem.Size = new Size(120, 22);
+            前进QToolStripMenuItem.Size = new Size(180, 22);
             前进QToolStripMenuItem.Text = "前进(&Q)";
             前进QToolStripMenuItem.Text = "前进(&Q)";
             前进QToolStripMenuItem.Click += 前进QToolStripMenuItem_Click;
             前进QToolStripMenuItem.Click += 前进QToolStripMenuItem_Click;
             // 
             // 
             // 后退WToolStripMenuItem
             // 后退WToolStripMenuItem
             // 
             // 
             后退WToolStripMenuItem.Name = "后退WToolStripMenuItem";
             后退WToolStripMenuItem.Name = "后退WToolStripMenuItem";
-            后退WToolStripMenuItem.Size = new Size(120, 22);
+            后退WToolStripMenuItem.Size = new Size(180, 22);
             后退WToolStripMenuItem.Text = "后退(&W)";
             后退WToolStripMenuItem.Text = "后退(&W)";
             后退WToolStripMenuItem.Click += 后退WToolStripMenuItem_Click;
             后退WToolStripMenuItem.Click += 后退WToolStripMenuItem_Click;
             // 
             // 
@@ -483,22 +483,22 @@
             // 
             // 
             // 添加到收藏夹ToolStripMenuItem
             // 添加到收藏夹ToolStripMenuItem
             // 
             // 
-            添加到收藏夹ToolStripMenuItem.Enabled = false;
             添加到收藏夹ToolStripMenuItem.Name = "添加到收藏夹ToolStripMenuItem";
             添加到收藏夹ToolStripMenuItem.Name = "添加到收藏夹ToolStripMenuItem";
-            添加到收藏夹ToolStripMenuItem.Size = new Size(148, 22);
+            添加到收藏夹ToolStripMenuItem.Size = new Size(180, 22);
             添加到收藏夹ToolStripMenuItem.Text = "添加到收藏夹";
             添加到收藏夹ToolStripMenuItem.Text = "添加到收藏夹";
+            添加到收藏夹ToolStripMenuItem.Click += 添加到收藏夹ToolStripMenuItem_Click;
             // 
             // 
             // 整理收藏夹ToolStripMenuItem
             // 整理收藏夹ToolStripMenuItem
             // 
             // 
             整理收藏夹ToolStripMenuItem.Enabled = false;
             整理收藏夹ToolStripMenuItem.Enabled = false;
             整理收藏夹ToolStripMenuItem.Name = "整理收藏夹ToolStripMenuItem";
             整理收藏夹ToolStripMenuItem.Name = "整理收藏夹ToolStripMenuItem";
-            整理收藏夹ToolStripMenuItem.Size = new Size(148, 22);
+            整理收藏夹ToolStripMenuItem.Size = new Size(180, 22);
             整理收藏夹ToolStripMenuItem.Text = "整理收藏夹";
             整理收藏夹ToolStripMenuItem.Text = "整理收藏夹";
             // 
             // 
             // toolStripSeparator10
             // toolStripSeparator10
             // 
             // 
             toolStripSeparator10.Name = "toolStripSeparator10";
             toolStripSeparator10.Name = "toolStripSeparator10";
-            toolStripSeparator10.Size = new Size(145, 6);
+            toolStripSeparator10.Size = new Size(177, 6);
             // 
             // 
             // 工具TToolStripMenuItem
             // 工具TToolStripMenuItem
             // 
             // 
@@ -511,49 +511,49 @@
             // 
             // 
             internet选项ToolStripMenuItem.Enabled = false;
             internet选项ToolStripMenuItem.Enabled = false;
             internet选项ToolStripMenuItem.Name = "internet选项ToolStripMenuItem";
             internet选项ToolStripMenuItem.Name = "internet选项ToolStripMenuItem";
-            internet选项ToolStripMenuItem.Size = new Size(145, 22);
+            internet选项ToolStripMenuItem.Size = new Size(180, 22);
             internet选项ToolStripMenuItem.Text = "Internet选项";
             internet选项ToolStripMenuItem.Text = "Internet选项";
             // 
             // 
             // 安全ToolStripMenuItem
             // 安全ToolStripMenuItem
             // 
             // 
             安全ToolStripMenuItem.Enabled = false;
             安全ToolStripMenuItem.Enabled = false;
             安全ToolStripMenuItem.Name = "安全ToolStripMenuItem";
             安全ToolStripMenuItem.Name = "安全ToolStripMenuItem";
-            安全ToolStripMenuItem.Size = new Size(145, 22);
+            安全ToolStripMenuItem.Size = new Size(180, 22);
             安全ToolStripMenuItem.Text = "安全";
             安全ToolStripMenuItem.Text = "安全";
             // 
             // 
             // 隐私ToolStripMenuItem
             // 隐私ToolStripMenuItem
             // 
             // 
             隐私ToolStripMenuItem.Enabled = false;
             隐私ToolStripMenuItem.Enabled = false;
             隐私ToolStripMenuItem.Name = "隐私ToolStripMenuItem";
             隐私ToolStripMenuItem.Name = "隐私ToolStripMenuItem";
-            隐私ToolStripMenuItem.Size = new Size(145, 22);
+            隐私ToolStripMenuItem.Size = new Size(180, 22);
             隐私ToolStripMenuItem.Text = "隐私";
             隐私ToolStripMenuItem.Text = "隐私";
             // 
             // 
             // 内容ToolStripMenuItem
             // 内容ToolStripMenuItem
             // 
             // 
             内容ToolStripMenuItem.Enabled = false;
             内容ToolStripMenuItem.Enabled = false;
             内容ToolStripMenuItem.Name = "内容ToolStripMenuItem";
             内容ToolStripMenuItem.Name = "内容ToolStripMenuItem";
-            内容ToolStripMenuItem.Size = new Size(145, 22);
+            内容ToolStripMenuItem.Size = new Size(180, 22);
             内容ToolStripMenuItem.Text = "内容";
             内容ToolStripMenuItem.Text = "内容";
             // 
             // 
             // 连接ToolStripMenuItem
             // 连接ToolStripMenuItem
             // 
             // 
             连接ToolStripMenuItem.Enabled = false;
             连接ToolStripMenuItem.Enabled = false;
             连接ToolStripMenuItem.Name = "连接ToolStripMenuItem";
             连接ToolStripMenuItem.Name = "连接ToolStripMenuItem";
-            连接ToolStripMenuItem.Size = new Size(145, 22);
+            连接ToolStripMenuItem.Size = new Size(180, 22);
             连接ToolStripMenuItem.Text = "连接";
             连接ToolStripMenuItem.Text = "连接";
             // 
             // 
             // 程序ToolStripMenuItem
             // 程序ToolStripMenuItem
             // 
             // 
             程序ToolStripMenuItem.Enabled = false;
             程序ToolStripMenuItem.Enabled = false;
             程序ToolStripMenuItem.Name = "程序ToolStripMenuItem";
             程序ToolStripMenuItem.Name = "程序ToolStripMenuItem";
-            程序ToolStripMenuItem.Size = new Size(145, 22);
+            程序ToolStripMenuItem.Size = new Size(180, 22);
             程序ToolStripMenuItem.Text = "程序";
             程序ToolStripMenuItem.Text = "程序";
             // 
             // 
             // 高级ToolStripMenuItem
             // 高级ToolStripMenuItem
             // 
             // 
             高级ToolStripMenuItem.Enabled = false;
             高级ToolStripMenuItem.Enabled = false;
             高级ToolStripMenuItem.Name = "高级ToolStripMenuItem";
             高级ToolStripMenuItem.Name = "高级ToolStripMenuItem";
-            高级ToolStripMenuItem.Size = new Size(145, 22);
+            高级ToolStripMenuItem.Size = new Size(180, 22);
             高级ToolStripMenuItem.Text = "高级";
             高级ToolStripMenuItem.Text = "高级";
             // 
             // 
             // 帮助HToolStripMenuItem
             // 帮助HToolStripMenuItem

+ 143 - 5
Form1.cs

@@ -1,4 +1,6 @@
+using System.Collections;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Resources;
 using System.Text;
 using System.Text;
 using Microsoft.Web.WebView2.Core;
 using Microsoft.Web.WebView2.Core;
 
 
@@ -659,7 +661,6 @@ background-position: right top;
                 {
                 {
                     Clipboard.SetText(textBox1.SelectedText);
                     Clipboard.SetText(textBox1.SelectedText);
                     textBox1.Text = textBox1.Text.Remove(textBox1.SelectionStart, textBox1.SelectionLength);
                     textBox1.Text = textBox1.Text.Remove(textBox1.SelectionStart, textBox1.SelectionLength);
-                    textBox1.Focus();
                 }
                 }
             }
             }
         }
         }
@@ -713,16 +714,153 @@ background-position: right top;
             {
             {
                 textBox1.Paste();
                 textBox1.Paste();
             }
             }
-            else if (isWebView2Focused)
+
+        }
+
+        private async void 全选AToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (comboBox1.Focused)
+            {
+                comboBox1.SelectAll();
+            }
+            else if (textBox1.Focused)
             {
             {
-                string script = "document.execCommand('paste', false, null);";
+                textBox1.SelectAll();
+            }
+            else
+            {
+                string script = "document.execCommand('selectAll', false, null);";
                 await webView21.CoreWebView2.ExecuteScriptAsync(script);
                 await webView21.CoreWebView2.ExecuteScriptAsync(script);
             }
             }
         }
         }
 
 
-        private async void 全选AToolStripMenuItem_Click(object sender, EventArgs e)
+        private void 查找FToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+        }
+
+        private async void 添加到收藏夹ToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            string resxFilePath = "favoritesMenuItem.resx";
+            string title = await webView21.CoreWebView2.ExecuteScriptAsync("document.title;");
+            string pageTitle = title.Trim('"');
+            string pageUrl = webView21.CoreWebView2.Source.ToString();
+            string faviconUrl = await webView21.CoreWebView2.ExecuteScriptAsync("var link = document.querySelector('link[rel~=\"icon\"]') || document.querySelector('link[rel~=\"shortcut icon\"]');link ? link.href : '';");
+            byte[] iconData = await DownloadFaviconAsync(faviconUrl);
+            bool titleExists = false;
+            using (ResXResourceReader reader = new ResXResourceReader(resxFilePath))
+            {
+                foreach (DictionaryEntry entry in reader)
+                {
+                    if (entry.Key.ToString() == pageTitle)
+                    {
+                        titleExists = true;
+                        break;
+                    }
+                }
+            }
+            if (!titleExists)
+            {
+                using (ResXResourceWriter writer = new ResXResourceWriter(resxFilePath))
+                {
+                    writer.AddResource(pageTitle, pageUrl);
+                    writer.Generate();
+                }
+            }
+            using (ResXResourceReader reader = new ResXResourceReader(resxFilePath))
+            {
+                foreach (DictionaryEntry entry in reader)
+                {
+                    if (entry.Key.ToString() == pageTitle)
+                    {
+                        titleExists = true;
+                        break;
+                    }
+                }
+            }
+            if (!titleExists)
+            {
+                using (ResXResourceWriter writer = new ResXResourceWriter(resxFilePath))
+                {
+                    writer.AddResource(pageTitle, iconData);
+                    writer.Generate();
+                }
+            }
+
+            // 1. 清空“收藏夹AToolStripMenuItem”下的菜单中分割线下方的所有按钮
+            ToolStripItem[] itemsToRemove = 收藏夹AToolStripMenuItem.DropDownItems.Cast<ToolStripItem>()
+                .SkipWhile(item => item != 收藏夹AToolStripMenuItem.DropDownItems["toolStripSeparator1"])
+                .ToArray();
+
+            foreach (var item in itemsToRemove)
+            {
+                收藏夹AToolStripMenuItem.DropDownItems.Remove(item);
+            }
+
+            // 2. 从 favoritesMenuItem.resx 文件中读取所有字符串资源
+            using (ResXResourceReader reader = new ResXResourceReader(resxFilePath))
+            {
+                foreach (DictionaryEntry entry in reader)
+                {
+                    string resourceName = entry.Key.ToString();
+                    string resourceValue = entry.Value.ToString();
+
+                    // 3. 为每个字符串资源创建一个新的 ToolStripMenuItem
+                    ToolStripMenuItem menuItem = new ToolStripMenuItem
+                    {
+                        Text = resourceName,
+                        Tag = resourceValue  // 你可以将资源值存储在 Tag 属性中,方便后续使用
+                    };
+
+                    // 4. 为每个按钮添加点击事件处理程序
+                    menuItem.Click += MenuItem_Click;
+
+                    // 5. 从 favoritesMenuItemIcon.resx 文件中读取对应的图标
+                    string iconResxFilePath = "favoritesMenuItemIcon.resx";
+                    using (ResXResourceReader iconReader = new ResXResourceReader(iconResxFilePath))
+                    {
+                        foreach (DictionaryEntry iconEntry in iconReader)
+                        {
+                            if (iconEntry.Key.ToString() == resourceName)
+                            {
+                                using (MemoryStream ms = new MemoryStream(iconData))
+                                {
+                                    Image iconImage = Image.FromStream(ms);
+                                    menuItem.Image = iconImage;
+                                }
+                                break;
+                            }
+                        }
+                    }
+
+                    // 6. 将新的 ToolStripMenuItem 添加到“收藏夹AToolStripMenuItem”下
+                    收藏夹AToolStripMenuItem.DropDownItems.Add(menuItem);
+                }
+            }
+        }
+        private async Task<byte[]> DownloadFaviconAsync(string faviconUrl)
+        {
+            using (HttpClient client = new HttpClient())
+            {
+                try
+                {
+                    return await client.GetByteArrayAsync(faviconUrl);
+                }
+                catch (Exception ex)
+                {
+                    return null; // 返回 null 或默认图标数据
+                }
+            }
+        }
+        private void MenuItem_Click(object sender, EventArgs e)
         {
         {
-            //await webView21.CoreWebView2.ExecuteScriptAsync("document.execCommand('selectAll', false, null);");
+            // 获取点击的按钮
+            ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
+
+            // 获取按钮的 Tag 属性,即资源值(URL)
+            string url = (string)menuItem.Tag;
+
+            // 令 WebView2 导航至该地址
+            webView21.CoreWebView2.Navigate(url);
         }
         }
     }
     }
 }
 }

+ 72 - 0
favoritesMenuItem.Designer.cs

@@ -0,0 +1,72 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EdgeVoyager {
+    using System;
+    
+    
+    /// <summary>
+    ///   一个强类型的资源类,用于查找本地化的字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class favoritesMenuItem {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal favoritesMenuItem() {
+        }
+        
+        /// <summary>
+        ///   返回此类使用的缓存的 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EdgeVoyager.favoritesMenuItem", typeof(favoritesMenuItem).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   重写当前线程的 CurrentUICulture 属性,对
+        ///   使用此强类型资源类的所有资源查找执行重写。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似  的本地化字符串。
+        /// </summary>
+        internal static string String1 {
+            get {
+                return ResourceManager.GetString("String1", resourceCulture);
+            }
+        }
+    }
+}

+ 123 - 0
favoritesMenuItem.resx

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <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>
+  <data name="String1" xml:space="preserve">
+    <value />
+  </data>
+</root>

+ 63 - 0
favoritesMenuItemIcon.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EdgeVoyager {
+    using System;
+    
+    
+    /// <summary>
+    ///   一个强类型的资源类,用于查找本地化的字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class favoritesMenuItemIcon {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal favoritesMenuItemIcon() {
+        }
+        
+        /// <summary>
+        ///   返回此类使用的缓存的 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EdgeVoyager.favoritesMenuItemIcon", typeof(favoritesMenuItemIcon).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   重写当前线程的 CurrentUICulture 属性,对
+        ///   使用此强类型资源类的所有资源查找执行重写。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 101 - 0
favoritesMenuItemIcon.resx

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+	<!-- 
+		Microsoft ResX Schema
+
+		Version 1.3
+
+		The primary goals of this format is to allow a simple XML format 
+		that is mostly human readable. The generation and parsing of the 
+		various data types are done through the TypeConverter classes 
+		associated with the data types.
+
+		Example:
+
+		... ado.net/XML headers & schema ...
+		<resheader name="resmimetype">text/microsoft-resx</resheader>
+		<resheader name="version">1.3</resheader>
+		<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+		<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+		<data name="Name1">this is my long string</data>
+		<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+		<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+			[base64 mime encoded serialized .NET Framework object]
+		</data>
+		<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+			[base64 mime encoded string representing a byte array form of the .NET Framework object]
+		</data>
+
+		There are any number of "resheader" rows that contain simple 
+		name/value pairs.
+
+		Each data row contains a name, and value. The row also contains a 
+		type or mimetype. Type corresponds to a .NET class that support 
+		text/value conversion through the TypeConverter architecture. 
+		Classes that don't support this are serialized and stored with the 
+		mimetype set.
+
+		The mimetype is used for serialized objects, and tells the 
+		ResXResourceReader how to depersist the object. This is currently not 
+		extensible. For a given mimetype the value must be set accordingly:
+
+		Note - application/x-microsoft.net.object.binary.base64 is the format 
+		that the ResXResourceWriter will generate, however the reader can 
+		read any of the formats listed below.
+
+		mimetype: application/x-microsoft.net.object.binary.base64
+		value   : The object must be serialized with 
+			: System.Serialization.Formatters.Binary.BinaryFormatter
+			: and then encoded with base64 encoding.
+
+		mimetype: application/x-microsoft.net.object.soap.base64
+		value   : The object must be serialized with 
+			: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+			: and then encoded with base64 encoding.
+
+		mimetype: application/x-microsoft.net.object.bytearray.base64
+		value   : The object must be serialized into a byte array 
+			: using a System.ComponentModel.TypeConverter
+			: and then encoded with base64 encoding.
+	-->
+	
+	<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+		<xsd:element name="root" msdata:IsDataSet="true">
+			<xsd:complexType>
+				<xsd:choice maxOccurs="unbounded">
+					<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" msdata:Ordinal="1" />
+							<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+							<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+						</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>1.3</value>
+	</resheader>
+	<resheader name="reader">
+		<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+	<resheader name="writer">
+		<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+	</resheader>
+</root>