├── .gitattributes
├── .gitignore
├── ContextMenuManager.sln
├── ContextMenuManager
├── App.config
├── BluePointLilac.Controls
│ ├── BackupDialog.cs
│ ├── DownloadDialog.cs
│ ├── IconDialog.cs
│ ├── InputDialog.cs
│ ├── MyCheckBox.cs
│ ├── MyListBox.cs
│ ├── MyMainForm.cs
│ ├── MySideBar.cs
│ ├── MyStatusBar.cs
│ ├── MyToolBar.cs
│ ├── PictureButton.cs
│ ├── ReadOnlyTextBox.cs
│ ├── ResizeLimitedForm.cs
│ ├── SelectDialog.cs
│ └── UAWebClient.cs
├── BluePointLilac.Methods
│ ├── ComboBoxExtension.cs
│ ├── ControlExtension.cs
│ ├── DirectoryEx.cs
│ ├── ElevatedFileDroper.cs
│ ├── EncodingType.cs
│ ├── ExternalProgram.cs
│ ├── FileExtension.cs
│ ├── FormExtension.cs
│ ├── GuidEx.cs
│ ├── HighDpi.cs
│ ├── ImageExtension.cs
│ ├── IniReader.cs
│ ├── IniWriter.cs
│ ├── MessageBoxEx.cs
│ ├── RegTrustedInstaller.cs
│ ├── RegistryEx.cs
│ ├── ResourceIcon.cs
│ ├── ResourceString.cs
│ ├── RichTextBoxExtension.cs
│ ├── ShellLink.cs
│ ├── SingleInstance.cs
│ ├── StringExtension.cs
│ ├── TextBoxExtension.cs
│ ├── ToolTipBox.cs
│ └── WinOsVersion.cs
├── ContextMenuManager.csproj
├── Controls
│ ├── AppSettingBox.cs
│ ├── BackupListBox.cs
│ ├── DetailedEditDialog.cs
│ ├── DetailedEditList.cs
│ ├── DictionariesBox.cs
│ ├── DonateBox.cs
│ ├── EnhanceMenuList.cs
│ ├── EnhanceMenusDialog.cs
│ ├── EnhanceMenusItem.cs
│ ├── ExplorerRestarter.cs
│ ├── FileExtensionDialog.cs
│ ├── FoldSubItem.cs
│ ├── GuidBlockedItem.cs
│ ├── GuidBlockedList.cs
│ ├── IEItem.cs
│ ├── IEList.cs
│ ├── Interfaces
│ │ ├── IBtnDeleteItem.cs
│ │ ├── IBtnMoveUpDownItem.cs
│ │ ├── IBtnShowMenuItem.cs
│ │ ├── IChkVisibleItem.cs
│ │ ├── IProtectOpenItem.cs
│ │ ├── ITsiAdministratorItem.cs
│ │ ├── ITsiCommandItem.cs
│ │ ├── ITsiDeleteItem.cs
│ │ ├── ITsiFilePathItem.cs
│ │ ├── ITsiGuidItem.cs
│ │ ├── ITsiIconItem.cs
│ │ ├── ITsiRegExportItem.cs
│ │ ├── ITsiRegPathItem.cs
│ │ ├── ITsiRestoreItem.cs
│ │ ├── ITsiShortcutCommandItem.cs
│ │ ├── ITsiTextItem.cs
│ │ └── ITsiWebSearchItem.cs
│ ├── LanguagesBox.cs
│ ├── NewIEDialog.cs
│ ├── NewItem.cs
│ ├── NewItemForm.cs
│ ├── NewLnkFileDialog.cs
│ ├── NewOpenWithDialog.cs
│ ├── NewShellDialog.cs
│ ├── OpenWithItem.cs
│ ├── OpenWithList.cs
│ ├── RComboBox.cs
│ ├── RForm.cs
│ ├── RToolStripMenuItem.cs
│ ├── RestoreItem.cs
│ ├── RestoreListDialog.cs
│ ├── RuleItem.cs
│ ├── SendToItem.cs
│ ├── SendToList.cs
│ ├── ShellExItem.cs
│ ├── ShellExecuteDialog.cs
│ ├── ShellItem.cs
│ ├── ShellList.cs
│ ├── ShellNewItem.cs
│ ├── ShellNewList.cs
│ ├── ShellStoreDialog.cs
│ ├── ShellSubMenuDialog.cs
│ ├── SubItemsForm.cs
│ ├── SwitchDicList.cs
│ ├── UwpModeItem.cs
│ ├── WinXGroupItem.cs
│ ├── WinXItem.cs
│ └── WinXList.cs
├── MainForm.cs
├── Methods
│ ├── AppConfig.cs
│ ├── AppImage.cs
│ ├── AppMessageBox.cs
│ ├── AppString.cs
│ ├── BackupHelper.cs
│ ├── DesktopIni.cs
│ ├── GuidInfo.cs
│ ├── ObjectPath.cs
│ ├── Updater.cs
│ ├── UwpHelper.cs
│ ├── WinXHasher.cs
│ └── XmlDicHelper.cs
├── Program.cs
└── Properties
│ ├── App.manifest
│ ├── AppIcon.ico
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Resources
│ ├── Images
│ │ ├── About.png
│ │ ├── Add.png
│ │ ├── AddExisting.png
│ │ ├── AddSeparator.png
│ │ ├── BackupItem.png
│ │ ├── CheckUpdate.png
│ │ ├── ContextMenuStyle.png
│ │ ├── Custom.png
│ │ ├── Delete.png
│ │ ├── Donate.png
│ │ ├── DownLoad.png
│ │ ├── Enhance.png
│ │ ├── Home.png
│ │ ├── Jump.png
│ │ ├── MicrosoftStore.png
│ │ ├── NewFolder.png
│ │ ├── NewItem.png
│ │ ├── Open.png
│ │ ├── Refresh.png
│ │ ├── Select.png
│ │ ├── Setting.png
│ │ ├── Sort.png
│ │ ├── Star.png
│ │ ├── SubItems.png
│ │ ├── Translate.png
│ │ ├── Type.png
│ │ ├── Up.png
│ │ ├── User.png
│ │ └── Web.png
│ ├── ShellNew
│ │ ├── 0.c
│ │ ├── 0.html
│ │ ├── 0.rar
│ │ ├── 0.reg
│ │ ├── 0.rtf
│ │ ├── 0.xlsx
│ │ ├── 0.xml
│ │ └── 0.zip
│ └── Texts
│ │ ├── AppLanguageDic.ini
│ │ ├── DetailedEditDic.xml
│ │ ├── EnhanceMenusDic.xml
│ │ ├── GuidInfosDic.ini
│ │ └── UwpModeItemsDic.xml
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Donate.md
├── LICENSE
├── Logo
└── Logo.png
├── README-en.md
├── README.md
├── Screenshot
├── AppImage-dark.png
├── AppImage.png
├── Screenshot-dark.png
├── Screenshot-en-dark.png
├── Screenshot-en.png
└── Screenshot.png
└── languages
├── ar-DZ عربية
├── de-DE.ini
├── en-US.ini
├── ja-JP.ini
├── ko-KR.ini
├── pt-BR.ini
├── ru-RU.ini
├── zh-CN.ini
└── zh-TW.ini
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/ContextMenuManager.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.12.35527.113 d17.12
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContextMenuManager", "ContextMenuManager\ContextMenuManager.csproj", "{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE0AD55A-5ABF-40A7-931E-FC04B0FFC6FA}"
9 | ProjectSection(SolutionItems) = preProject
10 | .gitattributes = .gitattributes
11 | .gitignore = .gitignore
12 | Screenshot\AppImage.png = Screenshot\AppImage.png
13 | Donate.md = Donate.md
14 | LICENSE = LICENSE
15 | Logo\Logo.png = Logo\Logo.png
16 | Logo\Logo2.png = Logo\Logo2.png
17 | README-en.md = README-en.md
18 | README.md = README.md
19 | Screenshot\Screenshot-en.png = Screenshot\Screenshot-en.png
20 | Screenshot\Screenshot.png = Screenshot\Screenshot.png
21 | EndProjectSection
22 | EndProject
23 | Global
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 | Debug|Any CPU = Debug|Any CPU
26 | Release|Any CPU = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
29 | {EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Release|Any CPU.Build.0 = Release|Any CPU
33 | EndGlobalSection
34 | GlobalSection(SolutionProperties) = preSolution
35 | HideSolutionNode = FALSE
36 | EndGlobalSection
37 | GlobalSection(ExtensibilityGlobals) = postSolution
38 | SolutionGuid = {A0E97C81-86B8-4360-8251-DF6FD4494EDA}
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/ContextMenuManager/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.IO;
6 | using System.Windows.Forms;
7 |
8 | namespace BluePointLilac.Controls
9 | {
10 | sealed class DownloadDialog : CommonDialog
11 | {
12 | public string Text { get; set; }
13 | public string Url { get; set; }
14 | public string FilePath { get; set; }
15 | public override void Reset() { }
16 |
17 | protected override bool RunDialog(IntPtr hwndOwner)
18 | {
19 | using(Process process = Process.GetCurrentProcess())
20 | using(DownloadForm frm = new DownloadForm())
21 | {
22 | frm.Url = Url;
23 | frm.Text = Text;
24 | frm.FilePath = FilePath;
25 | return frm.ShowDialog() == DialogResult.OK;
26 | }
27 | }
28 |
29 | sealed class DownloadForm : RForm
30 | {
31 | public DownloadForm()
32 | {
33 | SuspendLayout();
34 | Font = SystemFonts.MessageBoxFont;
35 | FormBorderStyle = FormBorderStyle.FixedSingle;
36 | MinimizeBox = MaximizeBox = ShowInTaskbar = false;
37 | Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
38 | Controls.AddRange(new Control[] { pgbDownload, btnCancel });
39 | Load += (sender, e) => DownloadFile(Url, FilePath);
40 | InitializeComponents();
41 | ResumeLayout();
42 | InitTheme();
43 | }
44 |
45 | readonly ProgressBar pgbDownload = new ProgressBar
46 | {
47 | Width = 200.DpiZoom(),
48 | Maximum = 100
49 | };
50 | readonly Button btnCancel = new Button
51 | {
52 | DialogResult = DialogResult.Cancel,
53 | Text = ResourceString.Cancel,
54 | AutoSize = true
55 | };
56 |
57 | public string Url { get; set; }
58 | public string FilePath { get; set; }
59 |
60 | private void InitializeComponents()
61 | {
62 | int a = 20.DpiZoom();
63 | pgbDownload.Left = pgbDownload.Top = btnCancel.Top = a;
64 | pgbDownload.Height = btnCancel.Height;
65 | btnCancel.Left = pgbDownload.Right + a;
66 | ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);
67 | }
68 |
69 | private void DownloadFile(string url, string filePath)
70 | {
71 | try
72 | {
73 | using(UAWebClient client = new UAWebClient())
74 | {
75 | client.DownloadProgressChanged += (sender, e) =>
76 | {
77 | int value = e.ProgressPercentage;
78 | Text = $"Downloading: {value}%";
79 | pgbDownload.Value = value;
80 | if(DialogResult == DialogResult.Cancel)
81 | {
82 | client.CancelAsync();
83 | File.Delete(FilePath);
84 | }
85 | };
86 | client.DownloadFileCompleted += (sender, e) =>
87 | {
88 | DialogResult = DialogResult.OK;
89 | };
90 | client.DownloadFileAsync(new Uri(url), filePath);
91 | }
92 | }
93 | catch(Exception e)
94 | {
95 | MessageBox.Show(e.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
96 | DialogResult = DialogResult.Cancel;
97 | }
98 | }
99 |
100 | protected override void OnLoad(EventArgs e)
101 | {
102 | if(Owner == null && Form.ActiveForm != this) Owner = Form.ActiveForm;
103 | if(Owner == null) StartPosition = FormStartPosition.CenterScreen;
104 | else
105 | {
106 | TopMost = Owner.TopMost;
107 | StartPosition = FormStartPosition.CenterParent;
108 | }
109 | base.OnLoad(e);
110 | }
111 | }
112 | }
113 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/IconDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 | using System.Windows.Forms;
5 |
6 | namespace BluePointLilac.Controls
7 | {
8 | public sealed class IconDialog : CommonDialog
9 | {
10 | [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#62", SetLastError = true)]
11 | private static extern bool PickIconDlg(IntPtr hWnd, StringBuilder pszFileName, int cchFileNameMax, ref int pnIconIndex);
12 |
13 | private const int MAXLENGTH = 260;
14 | private int iconIndex;
15 | public int IconIndex { get => iconIndex; set => iconIndex = value; }
16 | public string IconPath { get; set; }
17 |
18 | public override void Reset() { }
19 |
20 | protected override bool RunDialog(IntPtr hwndOwner)
21 | {
22 | StringBuilder sb = new StringBuilder(IconPath, MAXLENGTH);
23 | bool flag = PickIconDlg(hwndOwner, sb, MAXLENGTH, ref iconIndex);
24 | IconPath = flag ? sb.ToString() : null;
25 | return flag;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/InputDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace BluePointLilac.Controls
7 | {
8 | public sealed class InputDialog : CommonDialog
9 | {
10 | /// 输入对话框标题
11 | public string Title { get; set; } = Application.ProductName;
12 | /// 输入对话框文本框文本
13 | public string Text { get; set; }
14 | public Size Size { get; set; }
15 |
16 | public override void Reset() { }
17 |
18 | protected override bool RunDialog(IntPtr hwndOwner)
19 | {
20 | using(InputBox frm = new InputBox())
21 | {
22 | frm.Text = Title;
23 | frm.InputedText = Text;
24 | frm.Size = Size;
25 | if (Control.FromHandle(hwndOwner) is Form owner) frm.TopMost = owner.TopMost;
26 | bool flag = frm.ShowDialog() == DialogResult.OK;
27 | Text = flag ? frm.InputedText : null;
28 | return flag;
29 | }
30 | }
31 |
32 | sealed class InputBox : RForm
33 | {
34 | public InputBox()
35 | {
36 | AcceptButton = btnOK;
37 | CancelButton = btnCancel;
38 | Font = SystemFonts.MessageBoxFont;
39 | SizeGripStyle = SizeGripStyle.Hide;
40 | StartPosition = FormStartPosition.CenterParent;
41 | MaximizeBox = MinimizeBox = ShowIcon = ShowInTaskbar = false;
42 | Controls.AddRange(new Control[] { txtInput, btnOK, btnCancel });
43 | txtInput.Font = new Font(txtInput.Font.FontFamily, txtInput.Font.Size + 2F);
44 | txtInput.CanResizeFont();
45 | InitializeComponents();
46 | InitTheme();
47 | }
48 |
49 | public string InputedText
50 | {
51 | get => txtInput.Text;
52 | set => txtInput.Text = value;
53 | }
54 |
55 | readonly TextBox txtInput = new TextBox
56 | {
57 | Font = SystemFonts.MenuFont,
58 | ScrollBars = ScrollBars.Vertical,
59 | Multiline = true
60 | };
61 | readonly Button btnOK = new Button
62 | {
63 | Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
64 | DialogResult = DialogResult.OK,
65 | Text = ResourceString.OK,
66 | AutoSize = true
67 | };
68 | readonly Button btnCancel = new Button
69 | {
70 | Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
71 | DialogResult = DialogResult.Cancel,
72 | Text = ResourceString.Cancel,
73 | AutoSize = true
74 | };
75 |
76 | private void InitializeComponents()
77 | {
78 | SuspendLayout();
79 | int a = 20.DpiZoom();
80 | txtInput.Location = new Point(a, a);
81 | txtInput.Size = new Size(340, 24).DpiZoom();
82 | ClientSize = new Size(txtInput.Width + a * 2, txtInput.Height + btnOK.Height + a * 3);
83 | btnCancel.Top = btnOK.Top = txtInput.Bottom + a;
84 | btnCancel.Left = txtInput.Right - btnCancel.Width;
85 | btnOK.Left = btnCancel.Left - btnOK.Width - a;
86 | ResumeLayout();
87 | MinimumSize = Size;
88 | Resize += (sender, e) =>
89 | {
90 | txtInput.Width = ClientSize.Width - 2 * a;
91 | txtInput.Height = btnCancel.Top - 2 * a;
92 | };
93 | }
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/MyCheckBox.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Drawing.Drawing2D;
6 | using System.Windows.Forms;
7 |
8 | namespace BluePointLilac.Controls
9 | {
10 | [DefaultProperty("Checked")]
11 | public class MyCheckBox : PictureBox
12 | {
13 | public MyCheckBox()
14 | {
15 | Image = TurnOff;
16 | Cursor = Cursors.Hand;
17 | SizeMode = PictureBoxSizeMode.AutoSize;
18 | }
19 |
20 | private bool? _Checked = null;
21 | public bool Checked
22 | {
23 | get => _Checked == true;
24 | set
25 | {
26 | if (_Checked == value) return;
27 | Image = SwitchImage(value);
28 | if (_Checked == null)
29 | {
30 | _Checked = value;
31 | return;
32 | }
33 | if (PreCheckChanging != null && !PreCheckChanging.Invoke())
34 | {
35 | Image = SwitchImage(!value);
36 | return;
37 | }
38 | CheckChanging?.Invoke();
39 | if (PreCheckChanged != null && !PreCheckChanged.Invoke())
40 | {
41 | Image = SwitchImage(!value);
42 | return;
43 | }
44 | _Checked = value;
45 | CheckChanged?.Invoke();
46 | }
47 | }
48 |
49 | public Func PreCheckChanging;
50 | public Func PreCheckChanged;
51 | public Action CheckChanging;
52 | public Action CheckChanged;
53 |
54 | public Image TurnOnImage { get; set; } = TurnOn;
55 | public Image TurnOffImage { get; set; } = TurnOff;
56 |
57 | private Image SwitchImage(bool value) => value ? TurnOnImage : TurnOffImage;
58 |
59 | protected override void OnMouseDown(MouseEventArgs e)
60 | {
61 | base.OnMouseDown(e);
62 | if (e.Button == MouseButtons.Left) Checked = !Checked;
63 | }
64 |
65 | private static readonly Image TurnOn = DrawImage(true);
66 | private static readonly Image TurnOff = DrawImage(false);
67 |
68 | private static Image DrawImage(bool value)
69 | {
70 | int w = 80.DpiZoom(), h = 40.DpiZoom();
71 | int r = h / 2, padding = 4.DpiZoom();
72 | var bitmap = new Bitmap(w, h);
73 |
74 | using (Graphics g = Graphics.FromImage(bitmap))
75 | {
76 | g.InterpolationMode = InterpolationMode.HighQualityBicubic;
77 | g.CompositingQuality = CompositingQuality.HighQuality;
78 | g.PixelOffsetMode = PixelOffsetMode.HighQuality;
79 | g.SmoothingMode = SmoothingMode.AntiAlias;
80 |
81 | // 背景渐变
82 | using (var bgPath = CreateRoundedRect(0, 0, w, h, r))
83 | {
84 | Color startColor = value ? MyMainForm.MainColor : Color.FromArgb(200, 200, 200);
85 | Color endColor = value ? Color.FromArgb(160, MyMainForm.MainColor.R, MyMainForm.MainColor.G, MyMainForm.MainColor.B) :
86 | Color.FromArgb(160, 160, 160);
87 | using (var bgBrush = new LinearGradientBrush(new Rectangle(0, 0, w, h), startColor, endColor, 90f))
88 | {
89 | g.FillPath(bgBrush, bgPath);
90 | }
91 | }
92 |
93 | // 按钮位置计算
94 | int buttonX = value ? w - h + padding : padding;
95 | int buttonY = padding;
96 |
97 | // 按钮绘制(带阴影)
98 | using (var shadowPath = CreateRoundedRect(buttonX - 2, buttonY - 2, h - padding * 2 + 4, h - padding * 2 + 4, (h - padding * 2) / 2))
99 | using (var shadowBrush = new SolidBrush(Color.FromArgb(50, 0, 0, 0)))
100 | {
101 | g.FillPath(shadowBrush, shadowPath);
102 | }
103 |
104 | using (var buttonPath = CreateRoundedRect(buttonX, buttonY, h - padding * 2, h - padding * 2, (h - padding * 2) / 2))
105 | {
106 | using (var buttonBrush = new SolidBrush(Color.White))
107 | {
108 | g.FillPath(buttonBrush, buttonPath);
109 | }
110 | }
111 |
112 | // 高光效果
113 | using (var highlightPath = CreateRoundedRect(buttonX + 2, buttonY + 2, (h - padding * 2) / 2, (h - padding * 2) / 2, (h - padding * 2) / 4))
114 | using (var highlightBrush = new SolidBrush(Color.FromArgb(100, 255, 255, 255)))
115 | {
116 | g.FillPath(highlightBrush, highlightPath);
117 | }
118 | }
119 | return bitmap;
120 | }
121 |
122 | private static GraphicsPath CreateRoundedRect(float x, float y, float width, float height, float radius)
123 | {
124 | var path = new GraphicsPath();
125 | path.AddArc(x, y, radius * 2, radius * 2, 180, 90); // 左上角
126 | path.AddArc(x + width - radius * 2, y, radius * 2, radius * 2, 270, 90); // 右上角
127 | path.AddArc(x + width - radius * 2, y + height - radius * 2, radius * 2, radius * 2, 0, 90); // 右下角
128 | path.AddArc(x, y + height - radius * 2, radius * 2, radius * 2, 90, 90); // 左下角
129 | path.CloseFigure();
130 | return path;
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/MyStatusBar.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace BluePointLilac.Controls
8 | {
9 | public sealed class MyStatusBar : Panel
10 | {
11 | public static readonly string DefaultText = $"Ver: {Application.ProductVersion} {Application.CompanyName}";
12 |
13 | public MyStatusBar()
14 | {
15 | Text = DefaultText;
16 | Height = 30.DpiZoom();
17 | Dock = DockStyle.Bottom;
18 | Font = SystemFonts.StatusFont;
19 | BackColor = MyMainForm.ButtonMain;
20 | ForeColor = MyMainForm.FormFore;
21 | }
22 |
23 | [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
24 | public override string Text { get => base.Text; set => base.Text = value; }
25 |
26 | protected override void OnPaint(PaintEventArgs e)
27 | {
28 | base.OnPaint(e);
29 | string txt = Text;
30 | int left = Height / 3;
31 | for(int i = Text.Length - 1; i >= 0; i--)
32 | {
33 | Size size = TextRenderer.MeasureText(txt, Font);
34 | if(size.Width < ClientSize.Width - 2 * left)
35 | {
36 | using(Brush brush = new SolidBrush(ForeColor))
37 | {
38 | int top = (Height - size.Height) / 2;
39 | e.Graphics.Clear(BackColor);
40 | e.Graphics.DrawString(txt, Font, brush, left, top);
41 | break;
42 | }
43 | }
44 | txt = Text.Substring(0, i) + "...";
45 | }
46 | }
47 |
48 | protected override void OnResize(EventArgs e)
49 | {
50 | base.OnResize(e); Refresh();
51 | }
52 | protected override void OnTextChanged(EventArgs e)
53 | {
54 | base.OnTextChanged(e); Refresh();
55 | }
56 | protected override void OnFontChanged(EventArgs e)
57 | {
58 | base.OnFontChanged(e); Refresh();
59 | }
60 | protected override void OnForeColorChanged(EventArgs e)
61 | {
62 | base.OnForeColorChanged(e); Refresh();
63 | }
64 | protected override void OnBackColorChanged(EventArgs e)
65 | {
66 | base.OnBackColorChanged(e); Refresh();
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/PictureButton.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace BluePointLilac.Controls
6 | {
7 | public class PictureButton : PictureBox
8 | {
9 | public PictureButton(Image image)
10 | {
11 | BaseImage = image;
12 | SizeMode = PictureBoxSizeMode.AutoSize;
13 | Cursor = Cursors.Hand;
14 | }
15 |
16 | private Image baseImage;
17 | public Image BaseImage
18 | {
19 | get => baseImage;
20 | set
21 | {
22 | baseImage = value;
23 | Image = ToolStripRenderer.CreateDisabledImage(value);
24 | }
25 | }
26 |
27 | protected override void OnMouseEnter(EventArgs e)
28 | {
29 | base.OnMouseEnter(e); Image = BaseImage;
30 | }
31 |
32 | protected override void OnMouseLeave(EventArgs e)
33 | {
34 | base.OnMouseLeave(e);
35 | Image = ToolStripRenderer.CreateDisabledImage(BaseImage);
36 | }
37 |
38 | protected override void OnMouseDown(MouseEventArgs e)
39 | {
40 | if(e.Button == MouseButtons.Left) base.OnMouseDown(e);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace BluePointLilac.Controls
7 | {
8 | public sealed class ReadOnlyTextBox : TextBox
9 | {
10 | public ReadOnlyTextBox()
11 | {
12 | ReadOnly = true;
13 | Multiline = true;
14 | ShortcutsEnabled = false;
15 | ForeColor = MyMainForm.FormFore;
16 | BackColor = MyMainForm.FormBack;
17 | Font = SystemFonts.MenuFont;
18 | Font = new Font(Font.FontFamily, Font.Size + 1F);
19 | }
20 |
21 | const int WM_SETFOCUS = 0x0007;
22 | const int WM_KILLFOCUS = 0x0008;
23 | protected override void WndProc(ref Message m)
24 | {
25 | switch(m.Msg)
26 | {
27 | case WM_SETFOCUS:
28 | m.Msg = WM_KILLFOCUS; break;
29 | }
30 | base.WndProc(ref m);
31 | }
32 |
33 | private bool firstEnter = true;
34 |
35 | protected override void OnMouseEnter(EventArgs e)
36 | {
37 | base.OnMouseEnter(e);
38 | if(firstEnter) Focus();
39 | firstEnter = false;
40 | }
41 | }
42 |
43 | public sealed class ReadOnlyRichTextBox : RichTextBox
44 | {
45 | public ReadOnlyRichTextBox()
46 | {
47 | ReadOnly = true;
48 | Dock = DockStyle.Fill;
49 | BorderStyle = BorderStyle.None;
50 | ForeColor = MyMainForm.FormFore;
51 | BackColor = MyMainForm.FormBack;
52 | Font = SystemFonts.MenuFont;
53 | Font = new Font(Font.FontFamily, Font.Size + 1F);
54 | }
55 |
56 | const int WM_SETFOCUS = 0x0007;
57 | const int WM_KILLFOCUS = 0x0008;
58 |
59 | protected override void WndProc(ref Message m)
60 | {
61 | switch(m.Msg)
62 | {
63 | case WM_SETFOCUS:
64 | m.Msg = WM_KILLFOCUS; break;
65 | }
66 | base.WndProc(ref m);
67 | }
68 |
69 | private bool firstEnter = true;
70 |
71 | protected override void OnMouseEnter(EventArgs e)
72 | {
73 | base.OnMouseEnter(e);
74 | if(firstEnter) Focus();
75 | firstEnter = false;
76 | }
77 |
78 | protected override void OnLinkClicked(LinkClickedEventArgs e)
79 | {
80 | base.OnLinkClicked(e);
81 | ExternalProgram.OpenWebUrl(e.LinkText);
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/ResizeLimitedForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace BluePointLilac.Controls
5 | {
6 | /// 限制水平、竖直方向调整大小的窗体
7 | public class ResizeLimitedForm : RForm
8 | {
9 | /// 水平方向可调整大小
10 | public bool HorizontalResizable { get; set; } = true;
11 |
12 | /// 竖直方向可调整大小
13 | public bool VerticalResizable { get; set; } = true;
14 |
15 | public ResizeLimitedForm()
16 | {
17 | InitTheme();
18 | }
19 |
20 | protected override void WndProc(ref Message m)
21 | {
22 | base.WndProc(ref m);
23 | if(m.Msg == WM_NCHITTEST && WindowState == FormWindowState.Normal)
24 | {
25 | IntPtr hNowhere = new IntPtr((int)HitTest.Nowhere);
26 | switch((HitTest)m.Result)
27 | {
28 | case HitTest.Top:
29 | case HitTest.Bottom:
30 | if(!VerticalResizable) m.Result = hNowhere;
31 | break;
32 | case HitTest.Left:
33 | case HitTest.Right:
34 | if(!HorizontalResizable) m.Result = hNowhere;
35 | break;
36 | case HitTest.TopLeft:
37 | case HitTest.TopRight:
38 | case HitTest.BottomLeft:
39 | case HitTest.BottomRight:
40 | if(!VerticalResizable || !HorizontalResizable) m.Result = hNowhere;
41 | break;
42 | }
43 | }
44 | }
45 |
46 | const int WM_NCHITTEST = 0x84;//光标移动或鼠标按下、释放时的消息
47 | /// 鼠标击中位置
48 | enum HitTest : int
49 | {
50 | Error = -2,
51 | Transparent = -1,
52 | Nowhere = 0,
53 | Client = 1,
54 | TitleBar = 2,
55 | SysMenu = 3,
56 | Size = 4,
57 | GrowBox = 5,
58 | Hscroll = 6,
59 | Vscroll = 7,
60 | MinButton = 8,
61 | MaxButton = 9,
62 | Left = 10,
63 | Right = 11,
64 | Top = 12,
65 | TopLeft = 13,
66 | TopRight = 14,
67 | Bottom = 15,
68 | BottomLeft = 16,
69 | BottomRight = 17,
70 | Border = 18,
71 | Close = 20,
72 | Help = 21
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/SelectDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace BluePointLilac.Controls
7 | {
8 | public class SelectDialog : CommonDialog
9 | {
10 | public string Title { get; set; }
11 | public string Selected { get; set; }
12 | public int SelectedIndex { get; set; }
13 | public string[] Items { get; set; }
14 | public bool CanEdit { get; set; }
15 |
16 | public override void Reset() { }
17 |
18 | protected override bool RunDialog(IntPtr hwndOwner)
19 | {
20 | using(SelectForm frm = new SelectForm())
21 | {
22 | frm.Text = Title;
23 | frm.Items = Items;
24 | if(Selected != null) frm.Selected = Selected;
25 | else frm.SelectedIndex = SelectedIndex;
26 | frm.CanEdit = CanEdit;
27 | if (Control.FromHandle(hwndOwner) is Form owner) frm.TopMost = owner.TopMost;
28 | bool flag = frm.ShowDialog() == DialogResult.OK;
29 | if(flag)
30 | {
31 | Selected = frm.Selected;
32 | SelectedIndex = frm.SelectedIndex;
33 | }
34 | return flag;
35 | }
36 | }
37 |
38 | sealed class SelectForm : RForm
39 | {
40 | public SelectForm()
41 | {
42 | SuspendLayout();
43 | AcceptButton = btnOK;
44 | CancelButton = btnCancel;
45 | Font = SystemFonts.MenuFont;
46 | ShowIcon = ShowInTaskbar = false;
47 | MaximizeBox = MinimizeBox = false;
48 | FormBorderStyle = FormBorderStyle.FixedSingle;
49 | StartPosition = FormStartPosition.CenterParent;
50 | InitializeComponents();
51 | ResumeLayout();
52 | InitTheme();
53 | }
54 |
55 | public string Selected
56 | {
57 | get => cmbItems.Text;
58 | set => cmbItems.Text = value;
59 | }
60 |
61 | public string[] Items
62 | {
63 | get
64 | {
65 | string[] value = new string[cmbItems.Items.Count];
66 | cmbItems.Items.CopyTo(value, 0);
67 | return value;
68 | }
69 | set
70 | {
71 | cmbItems.Items.Clear();
72 | cmbItems.Items.AddRange(value);
73 | }
74 | }
75 |
76 | public bool CanEdit
77 | {
78 | get => cmbItems.DropDownStyle == ComboBoxStyle.DropDown;
79 | set => cmbItems.DropDownStyle = value ? ComboBoxStyle.DropDown : ComboBoxStyle.DropDownList;
80 | }
81 |
82 | public int SelectedIndex
83 | {
84 | get => cmbItems.SelectedIndex;
85 | set => cmbItems.SelectedIndex = value;
86 | }
87 |
88 | readonly Button btnOK = new Button
89 | {
90 | DialogResult = DialogResult.OK,
91 | Text = ResourceString.OK,
92 | AutoSize = true
93 | };
94 | readonly Button btnCancel = new Button
95 | {
96 | DialogResult = DialogResult.Cancel,
97 | Text = ResourceString.Cancel,
98 | AutoSize = true
99 | };
100 | readonly RComboBox cmbItems = new RComboBox
101 | {
102 | AutoCompleteMode = AutoCompleteMode.SuggestAppend,
103 | AutoCompleteSource = AutoCompleteSource.ListItems,
104 | DropDownHeight = 294.DpiZoom(),
105 | ImeMode = ImeMode.Disable
106 | };
107 |
108 | private void InitializeComponents()
109 | {
110 | Controls.AddRange(new Control[] { cmbItems, btnOK, btnCancel });
111 | int a = 20.DpiZoom();
112 | cmbItems.Left = a;
113 | cmbItems.Width = 85.DpiZoom();
114 | cmbItems.Top = btnOK.Top = btnCancel.Top = a;
115 | btnOK.Left = cmbItems.Right + a;
116 | btnCancel.Left = btnOK.Right + a;
117 | ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);
118 | cmbItems.AutosizeDropDownWidth();
119 | }
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Controls/UAWebClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Net;
4 | using System.Runtime.Serialization.Json;
5 | using System.Text;
6 | using System.Xml;
7 |
8 | namespace BluePointLilac.Controls
9 | {
10 | public sealed class UAWebClient : WebClient
11 | {
12 | public UAWebClient()
13 | {
14 | //此类主要为了解决访问Github的一些问题
15 | //请求被中止: 未能创建 SSL/TLS 安全通道; 基础连接已经关闭: 发送时发生错误,一般添加TLS12即可
16 | //TLS12------0xc00,TLS11------0x300,TLS------0xc0,SSL------0x30;
17 | ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc00 | 0x300 | 0xc0 | 0x30);
18 | //网络传输默认文本编码 UTF-8
19 | Encoding = Encoding.UTF8;
20 | //远程服务器返回错误: (403) 已禁止
21 | //浏览器 F12 console 输入 console.log(navigator.userAgent); 获取 User Agent
22 | Headers.Add("User-Agent",
23 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
24 | "Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66");
25 | }
26 |
27 | protected override WebRequest GetWebRequest(Uri address)
28 | {
29 | WebRequest request = base.GetWebRequest(address);
30 | request.Timeout = 6 * 1000;
31 | return request;
32 | }
33 |
34 | /// 获取网页文本
35 | public string GetWebString(string url)
36 | {
37 | try
38 | {
39 | string str = DownloadString(url);
40 | str = str?.Replace("\n", Environment.NewLine);//换行符转换
41 | return str;
42 | }
43 | catch { return null; }
44 | }
45 |
46 | /// 将网络文本写入本地文件
47 | /// 本地文件路径
48 | /// 网络文件Raw路径
49 | public bool WebStringToFile(string filePath, string fileUrl)
50 | {
51 | string contents = GetWebString(fileUrl);
52 | bool flag = contents != null;
53 | if(flag) File.WriteAllText(filePath, contents, Encoding.Unicode);
54 | return flag;
55 | }
56 |
57 | /// 获取网页Json文本并加工为Xml
58 | public XmlDocument GetWebJsonToXml(string url)
59 | {
60 | try
61 | {
62 | byte[] bytes = DownloadData(url);
63 | using(XmlReader xReader = JsonReaderWriterFactory.CreateJsonReader(bytes, XmlDictionaryReaderQuotas.Max))
64 | {
65 | XmlDocument doc = new XmlDocument();
66 | doc.Load(xReader);
67 | return doc;
68 | }
69 | }
70 | catch { return null; }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using System;
3 | using System.Windows.Forms;
4 |
5 | namespace BluePointLilac.Methods
6 | {
7 | public static class ComboBoxExtension
8 | {
9 | public static void AutosizeDropDownWidth(this RComboBox box)
10 | {
11 | box.DropDown += (sender, e) =>
12 | {
13 | int maxWidth = 0;
14 | foreach(var item in box.Items)
15 | {
16 | maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(item.ToString(), box.Font).Width);
17 | }
18 | maxWidth = Math.Max(maxWidth, box.Width);
19 | box.DropDownWidth = maxWidth;
20 | };
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows.Forms;
4 |
5 | namespace BluePointLilac.Methods
6 | {
7 | public static class ControlExtension
8 | {
9 | [DllImport("user32.dll")]
10 | private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
11 |
12 | [DllImport("user32.dll")]
13 | private static extern bool ReleaseCapture();
14 |
15 | /// 使控件能够移动所属窗体
16 | /// 目标控件
17 | public static void CanMoveForm(this Control ctr)
18 | {
19 | const int WM_NCLBUTTONDOWN = 0xA1;
20 | const int HT_CAPTION = 0x2;
21 | ctr.MouseMove += (sender, e) =>
22 | {
23 | if(e.Button != MouseButtons.Left) return;
24 | ReleaseCapture();
25 | PostMessage(ctr.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
26 | };
27 | }
28 |
29 | [DllImport("user32.dll")]
30 | private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc);
31 |
32 | [DllImport("user32.dll")]
33 | private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
34 |
35 | /// 通过Win32API禁用/启用目标控件
36 | /// 控件被禁用时仍可更改字体颜色,不需要同时设置ctr.Enabled=false
37 | /// 目标控件
38 | /// 启用为true,禁用为false
39 | public static void SetEnabled(this Control ctr, bool enabled)
40 | {
41 | const int GWL_STYLE = -16;
42 | const int WS_DISABLED = 0x8000000;
43 | int value = GetWindowLong(ctr.Handle, GWL_STYLE);
44 | if(enabled) value &= ~WS_DISABLED;
45 | else value |= WS_DISABLED;
46 | SetWindowLong(ctr.Handle, GWL_STYLE, value);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/DirectoryEx.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace BluePointLilac.Methods
4 | {
5 | public static class DirectoryEx
6 | {
7 | public static void CopyTo(string srcDirPath, string dstDirPath)
8 | {
9 | DirectoryInfo srcDi = new DirectoryInfo(srcDirPath);
10 | DirectoryInfo dstDi = new DirectoryInfo(dstDirPath);
11 | dstDi.Create();
12 | foreach(FileInfo srcFi in srcDi.GetFiles())
13 | {
14 | string dstFilePath = $@"{dstDirPath}\{srcFi.Name}";
15 | srcFi.CopyTo(dstFilePath, true);
16 | }
17 | foreach(DirectoryInfo srcSubDi in srcDi.GetDirectories())
18 | {
19 | DirectoryInfo dstSubDi = dstDi.CreateSubdirectory(srcSubDi.Name);
20 | CopyTo(srcSubDi.FullName, dstSubDi.FullName);
21 | }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Windows.Forms;
7 |
8 | namespace BluePointLilac.Methods
9 | {
10 | /// 代码用途:管理员UAC进程窗口拖放文件
11 | /// 代码来源1:https://zhuanlan.zhihu.com/p/48735364
12 | /// 代码来源2:https://github.com/volschin/sdimager/blob/master/ElevatedDragDropManager.cs
13 | /// 代码作者:雨少主(知乎)、volschin(Github)、蓝点lilac(转载、修改)
14 | /// 调用方法:var droper = new ElevatedFileDroper(control);
15 | /// droper.DragDrop += (sender, e) => MessageBox.Show(droper.DropFilePaths[0]);
16 | /// 备注:此类只能生效一个实例,不能将control.AllowDrop设为true,droper.DragDrop与control.DragDrop不共存
17 |
18 | public sealed class ElevatedFileDroper : IMessageFilter
19 | {
20 | [DllImport("user32.dll", SetLastError = true)]
21 | [return: MarshalAs(UnmanagedType.Bool)]
22 | private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint message, ChangeFilterAction action, in ChangeFilterStruct pChangeFilterStruct);
23 |
24 | [DllImport("user32.dll", SetLastError = true)]
25 | [return: MarshalAs(UnmanagedType.Bool)]
26 | private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);
27 |
28 | [DllImport("shell32.dll", SetLastError = false)]
29 | private static extern void DragAcceptFiles(IntPtr hWnd, bool fAccept);
30 |
31 | [DllImport("shell32.dll", SetLastError = false, CharSet = CharSet.Unicode)]
32 | private static extern uint DragQueryFile(IntPtr hWnd, uint iFile, StringBuilder lpszFile, int cch);
33 |
34 | [DllImport("shell32.dll", SetLastError = false)]
35 | private static extern bool DragQueryPoint(IntPtr hDrop, out Point lppt);
36 |
37 | [DllImport("shell32.dll", SetLastError = false)]
38 | private static extern void DragFinish(IntPtr hDrop);
39 |
40 | [StructLayout(LayoutKind.Sequential)]
41 | struct ChangeFilterStruct
42 | {
43 | public uint CbSize;
44 | public ChangeFilterStatu ExtStatus;
45 | }
46 |
47 | enum ChangeWindowMessageFilterFlags : uint
48 | {
49 | MSGFLT_ADD = 1,
50 | MSGFLT_REMOVE = 2
51 | }
52 |
53 | enum ChangeFilterAction : uint
54 | {
55 | MSGFLT_RESET,
56 | MSGFLT_ALLOW,
57 | MSGFLT_DISALLOW
58 | }
59 |
60 | enum ChangeFilterStatu : uint
61 | {
62 | MSGFLTINFO_NONE,
63 | MSGFLTINFO_ALREADYALLOWED_FORWND,
64 | MSGFLTINFO_ALREADYDISALLOWED_FORWND,
65 | MSGFLTINFO_ALLOWED_HIGHER
66 | }
67 |
68 | const uint WM_COPYGLOBALDATA = 0x0049;
69 | const uint WM_COPYDATA = 0x004A;
70 | const uint WM_DROPFILES = 0x0233;
71 |
72 | public event EventHandler DragDrop;
73 | public string[] DropFilePaths { get; private set; }
74 | public Point DropPoint { get; private set; }
75 |
76 | public ElevatedFileDroper(Control ctr)
77 | {
78 | ctr.AllowDrop = false;
79 | DragAcceptFiles(ctr.Handle, true);
80 | Application.AddMessageFilter(this);
81 | ctr.Disposed += (sender, e) => Application.RemoveMessageFilter(this);
82 |
83 | if(ctr is Form frm)
84 | {
85 | double opacity = frm.Opacity;
86 | frm.Paint += (sender, e) =>
87 | {
88 | if(frm.Opacity != opacity)
89 | {
90 | //窗体透明度变化时需要重新注册接受文件拖拽标识符
91 | DragAcceptFiles(ctr.Handle, true);
92 | opacity = frm.Opacity;
93 | }
94 | };
95 | }
96 |
97 | Version ver = Environment.OSVersion.Version;
98 | bool isVistaOrHigher = ver >= new Version(6, 0);
99 | bool isWin7OrHigher = ver >= new Version(6, 1);
100 | var status = new ChangeFilterStruct { CbSize = 8 };
101 | if(isVistaOrHigher)
102 | {
103 | foreach(uint msg in new[] { WM_DROPFILES, WM_COPYGLOBALDATA, WM_COPYDATA })
104 | {
105 | bool error = false;
106 | if(isWin7OrHigher)
107 | {
108 | error = !ChangeWindowMessageFilterEx(ctr.Handle, msg, ChangeFilterAction.MSGFLT_ALLOW, in status);
109 | }
110 | else
111 | {
112 | error = !ChangeWindowMessageFilter(msg, ChangeWindowMessageFilterFlags.MSGFLT_ADD);
113 | }
114 | if(error) throw new Win32Exception(Marshal.GetLastWin32Error());
115 | }
116 | }
117 | }
118 |
119 | public bool PreFilterMessage(ref Message m)
120 | {
121 | if(m.Msg != WM_DROPFILES) return false;
122 | IntPtr handle = m.WParam;
123 | uint fileCount = DragQueryFile(handle, uint.MaxValue, null, 0);
124 | string[] filePaths = new string[fileCount];
125 | for(uint i = 0; i < fileCount; i++)
126 | {
127 | StringBuilder sb = new StringBuilder(260);
128 | uint result = DragQueryFile(handle, i, sb, sb.Capacity);
129 | if(result > 0) filePaths[i] = sb.ToString();
130 | }
131 | DragQueryPoint(handle, out Point point);
132 | DragFinish(handle);
133 | DropPoint = point;
134 | DropFilePaths = filePaths;
135 | DragDrop?.Invoke(this, null);
136 | return true;
137 | }
138 | }
139 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/EncodingType.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace BluePointLilac.Methods
7 | {
8 | /* 获取文本文件编码类型
9 | * 代码参考:https://www.cnblogs.com/guyun/p/4262587.html (Napoléon)*/
10 | public static class EncodingType
11 | {
12 | /// 各种带BOM的编码BOM值
13 | private static readonly Dictionary EncodingBomBytes = new Dictionary
14 | {
15 | { new byte[] { 0xEF, 0xBB, 0xBF }, Encoding.UTF8 }, //UTF-8 EF BB BF
16 | { new byte[] { 0xFF, 0xFE, 0x00, 0x00 }, Encoding.UTF32 }, //UTF-32LE FF FE 00 00
17 | { new byte[] { 0xFF, 0xFE }, Encoding.Unicode }, //UTF-16LE FF FE
18 | { new byte[] { 0xFE, 0xFF }, Encoding.BigEndianUnicode }, //UTF-16BE FE FF
19 | { new byte[] { 0x2B, 0x2F, 0x76 }, Encoding.UTF7 }, //UTF-7 2B 2F 76
20 | { new byte[] { 0x00, 0x00, 0xFE, 0xFF }, new UTF32Encoding(true, true) }, //UTF-32BE 00 00 FE FF
21 | };
22 |
23 | /// 获取给定的文件的编码类型
24 | /// 文件路径
25 | /// 文件的编码类型
26 | public static Encoding GetType(string filePath)
27 | {
28 | byte[] fs = File.ReadAllBytes(filePath);
29 | foreach(var kv in EncodingBomBytes)
30 | {
31 | if(fs.Length < kv.Key.Length) continue;
32 | int i = -1;
33 | bool flag = kv.Key.All(s => { i++; return s == fs[i]; });
34 | if(flag) return kv.Value;
35 | }
36 | if(IsUTF8Bytes(fs)) return Encoding.UTF8; //不带BOM的UTF-8
37 | return Encoding.Default;
38 | }
39 |
40 | /// 判断是否是不带 BOM 的 UTF8 格式
41 | ///
42 | private static bool IsUTF8Bytes(byte[] bytes)
43 | {
44 | int count = 1; //计算当前正分析的字符应还有的字节数
45 | for(int i = 0; i < bytes.Length; i++)
46 | {
47 | byte curByte = bytes[i];//当前分析的字节.
48 | if(count == 1)
49 | {
50 | if(curByte >= 0x80)
51 | {
52 | //计算当前字符所占的字节数
53 | //修复了EncodingType内造成en语言下debug错误的问题(算术溢出)
54 | int byteCount = 7;
55 | if (curByte < 0xC0)
56 | {
57 | byteCount = 0;
58 | }
59 | else if (curByte < 0xE0)
60 | {
61 | byteCount = 1;
62 | }
63 | else if (curByte < 0xF0)
64 | {
65 | byteCount = 2;
66 | }
67 | else if (curByte < 0xF8)
68 | {
69 | byteCount = 3;
70 | }
71 | else if (curByte < 0xFC)
72 | {
73 | byteCount = 4;
74 | }
75 | else if (curByte < 0xFE)
76 | {
77 | byteCount = 5;
78 | }
79 | else if (curByte < 0xFF)
80 | {
81 | byteCount = 6;
82 | }
83 | count += byteCount;
84 | /*while (((curByte <<= 1) & 0x80) != 0)
85 | {
86 | count++;
87 | }*/
88 | //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
89 | if (count == 1 || count > 6) return false;
90 | }
91 | }
92 | else
93 | {
94 | //若是UTF-8 此时第一位必须为1
95 | if((curByte & 0xC0) != 0x80) return false;
96 | else count--;
97 | }
98 | }
99 | //if(count > 1) throw new Exception("非预期的byte格式");
100 | return true;
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/FileExtension.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using System;
3 | using System.Runtime.InteropServices;
4 | using System.Text;
5 |
6 | namespace BluePointLilac.Methods
7 | {
8 | public static class FileExtension
9 | {
10 | [Flags]
11 | enum AssocF
12 | {
13 | Init_NoRemapCLSID = 0x1,
14 | Init_ByExeName = 0x2,
15 | Open_ByExeName = 0x2,
16 | Init_DefaultToStar = 0x4,
17 | Init_DefaultToFolder = 0x8,
18 | NoUserSettings = 0x10,
19 | NoTruncate = 0x20,
20 | Verify = 0x40,
21 | RemapRunDll = 0x80,
22 | NoFixUps = 0x100,
23 | IgnoreBaseClass = 0x200
24 | }
25 |
26 | public enum AssocStr
27 | {
28 | Command = 1,
29 | Executable,
30 | FriendlyDocName,
31 | FriendlyAppName,
32 | NoOpen,
33 | ShellNewValue,
34 | DDECommand,
35 | DDEIfExec,
36 | DDEApplication,
37 | DDETopic
38 | }
39 |
40 | [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
41 | private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut);
42 |
43 | public const string FILEEXTSPATH = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts";
44 | private const string HKCRCLASSES = @"HKEY_CURRENT_USER\SOFTWARE\Classes";
45 | private const string HKLMCLASSES = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes";
46 |
47 | public static string GetExtentionInfo(AssocStr assocStr, string extension)
48 | {
49 | uint pcchOut = 0;
50 | AssocQueryString(AssocF.Verify, assocStr, extension, null, null, ref pcchOut);
51 | StringBuilder pszOut = new StringBuilder((int)pcchOut);
52 | AssocQueryString(AssocF.Verify, assocStr, extension, null, pszOut, ref pcchOut);
53 | return pszOut.ToString();
54 | }
55 |
56 | public static string GetOpenMode(string extension)
57 | {
58 | if(string.IsNullOrEmpty(extension)) return null;
59 | string mode;
60 | bool CheckMode()
61 | {
62 | if(mode.IsNullOrWhiteSpace()) return false;
63 | if(mode.Length > 255) return false;
64 | if(mode.ToLower().StartsWith(@"applications\")) return false;
65 | using(RegistryKey root = Registry.ClassesRoot)
66 | using(RegistryKey key = root.OpenSubKey(mode))
67 | {
68 | return key != null;
69 | }
70 | }
71 | mode = Registry.GetValue($@"{FILEEXTSPATH}\{extension}\UserChoice", "ProgId", null)?.ToString();
72 | if(CheckMode()) return mode;
73 | mode = Registry.GetValue($@"{HKLMCLASSES}\{extension}", "", null)?.ToString();
74 | if(CheckMode()) return mode;
75 | mode = Registry.GetValue($@"{HKCRCLASSES}\{extension}", "", null)?.ToString();
76 | if(CheckMode()) return mode;
77 | return null;
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/FormExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows.Forms;
3 |
4 | namespace BluePointLilac.Methods
5 | {
6 | public static class FormExtension
7 | {
8 | /// 移动窗体时同时移动另一个窗体
9 | /// 主动移动的窗体
10 | /// 同时被移动的窗体
11 | public static void MoveAsMove(this Form frm1, Form frm2)
12 | {
13 | if(frm2 == null) return;
14 | Point pLast = Point.Empty;
15 | frm1.Load += (sender, e) => pLast = frm1.Location;
16 | frm1.LocationChanged += (sender, e) =>
17 | {
18 | if(pLast == Point.Empty) return;
19 | frm2.Left += frm1.Left - pLast.X;
20 | frm2.Top += frm1.Top - pLast.Y;
21 | pLast = frm1.Location;
22 | };
23 | }
24 |
25 | /// 给窗体添加ESC键关闭功能
26 | /// 指定窗口
27 | /// 关闭窗口时的对话框返回值
28 | /// 也可以重写Form的ProcessDialogKey事件,
29 | /// 这个方法更简单,但遍历窗体控件时切记多了一个不可见的关闭按钮
30 | public static void AddEscapeButton(this Form frm, DialogResult dr = DialogResult.Cancel)
31 | {
32 | Button btn = new Button
33 | {
34 | Parent = frm,
35 | Size = Size.Empty,
36 | DialogResult = dr
37 | };
38 | frm.CancelButton = btn;
39 | frm.Disposed += (sender, e) => btn.Dispose();
40 | frm.FormClosing += (sender, e) => btn.PerformClick();
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/GuidEx.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace BluePointLilac.Methods
5 | {
6 | //为兼容.Net Framework 3.5,无法引用Microsoft.CSharp.dll(中的Guid.TryParse)写了这个扩展方法
7 | public static class GuidEx
8 | {
9 | public static bool TryParse(string str, out Guid guid)
10 | {
11 | if(IsGuid(str))
12 | {
13 | guid = new Guid(str);
14 | return true;
15 | }
16 | else
17 | {
18 | guid = Guid.Empty;
19 | return false;
20 | }
21 | }
22 |
23 | private static readonly Regex GuidRegex = new Regex(@"[A-F0-9]{8}(\-[A-F0-9]{4}){3}\-[A-F0-9]{12}", RegexOptions.IgnoreCase);
24 |
25 | public static bool IsGuid(string str)
26 | {
27 | if(string.IsNullOrEmpty(str)) return false;
28 | if(str.Length == 38 && str.StartsWith("{") && str.EndsWith("}") && GuidRegex.IsMatch(str)) return true;
29 | if(str.Length == 36 && GuidRegex.IsMatch(str)) return true;
30 | return false;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/HighDpi.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows;
3 | using System.Windows.Forms;
4 |
5 | namespace BluePointLilac.Methods
6 | {
7 | /// 处理不同DPI缩放比下的像素绘制和字体显示问题
8 | /// 使用此类需要添加引用 PresentationFramework
9 | /// 还应在配置清单App.manifest中启用DPI感知自动缩放
10 | /// Font为矢量类型,Point、Size、Rectangle、Padding等为像素类型。
11 | /// 在不同DPI缩放下,矢量类型等比缩放,像素类型保持不变,故会出现排版显示问题。
12 | /// 解决方案一:项目中所有用到的像素类型实例值都取与缩放比之积,矢量类型不变。
13 | /// 解决方案二:项目中所有用到的矢量类型实例都取与缩放比之商,像素类型不变
14 | public static class HighDpi
15 | {
16 | /// DPI缩放比
17 | public static readonly double DpiScale = Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
18 |
19 | public static Point DpiZoom(this Point point) => new Point(DpiZoom(point.X), DpiZoom(point.Y));
20 |
21 | public static PointF DpiZoom(this PointF point) => new PointF(DpiZoom(point.X), DpiZoom(point.Y));
22 |
23 | public static Size DpiZoom(this Size size) => new Size(DpiZoom(size.Width), DpiZoom(size.Height));
24 |
25 | public static SizeF DpiZoom(this SizeF size) => new SizeF(DpiZoom(size.Width), DpiZoom(size.Height));
26 |
27 | public static Rectangle DpiZoom(this Rectangle r) => new Rectangle(DpiZoom(r.Location), DpiZoom(r.Size));
28 |
29 | public static RectangleF DpiZoom(this RectangleF r) => new RectangleF(DpiZoom(r.Location), DpiZoom(r.Size));
30 |
31 | public static Padding DpiZoom(this Padding p) => new Padding(DpiZoom(p.Left), DpiZoom(p.Top), DpiZoom(p.Right), DpiZoom(p.Bottom));
32 |
33 | public static Font DpiZoom(this Font font) => new Font(font.FontFamily, font.Size / DpiZoom(1F), font.Style);
34 |
35 | public static int DpiZoom(this int num) => (int)(num * DpiScale);
36 |
37 | public static float DpiZoom(this float num) => (float)(num * DpiScale);
38 |
39 | public static double DpiZoom(this double num) => num * DpiScale;
40 | }
41 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ImageExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Drawing.Drawing2D;
3 | using System.Drawing.Imaging;
4 |
5 | namespace BluePointLilac.Methods
6 | {
7 | public static class ImageExtension
8 | {
9 | public static Image ToTransparent(this Image image, float opacity = 0.5F)
10 | {
11 | Bitmap bitmap = new Bitmap(image.Width, image.Height);
12 | using(Graphics g = Graphics.FromImage(bitmap))
13 | using(ImageAttributes attributes = new ImageAttributes())
14 | {
15 | ColorMatrix matrix = new ColorMatrix { Matrix33 = opacity };
16 | attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
17 | g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height),
18 | 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
19 | }
20 | return bitmap;
21 | }
22 |
23 | public static Image ResizeImage(this Image image, int width, int height)
24 | {
25 | //return image.GetThumbnailImage(width, height, null, System.IntPtr.Zero);//质量稍微低一点
26 | if(image.Width == width && image.Height == height) return image;
27 | Bitmap destImage = new Bitmap(width, height);
28 | destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
29 | using(Graphics g = Graphics.FromImage(destImage))
30 | {
31 | g.CompositingMode = CompositingMode.SourceCopy;
32 | g.InterpolationMode = InterpolationMode.HighQualityBicubic;
33 | g.CompositingQuality = CompositingQuality.HighQuality;
34 | g.PixelOffsetMode = PixelOffsetMode.HighQuality;
35 | g.SmoothingMode = SmoothingMode.HighQuality;
36 |
37 | using(ImageAttributes attributes = new ImageAttributes())
38 | {
39 | attributes.SetWrapMode(WrapMode.TileFlipXY);
40 | g.DrawImage(image, new Rectangle(0, 0, width, height),
41 | 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
42 | }
43 | }
44 | return destImage;
45 | }
46 |
47 | public static Image ResizeImage(this Image image, double scale)
48 | {
49 | if(scale == 1) return image;
50 | int width = (int)(image.Width * scale);
51 | int height = (int)(image.Height * scale);
52 | return image.ResizeImage(width, height);
53 | }
54 |
55 | public static Image ResizeImage(this Image image, Size newSize)
56 | {
57 | if(newSize == image.Size) return image;
58 | return image.ResizeImage(newSize.Width, newSize.Height);
59 | }
60 |
61 | public static Image RotateImage(this Image image, RotateFlipType rotateType)
62 | {
63 | Bitmap bitmap = new Bitmap(image);
64 | bitmap.RotateFlip(rotateType);
65 | return bitmap;
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ResourceString.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 |
5 | namespace BluePointLilac.Methods
6 | {
7 | public static class ResourceString
8 | {
9 | //MSDN文档: https://docs.microsoft.com/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring
10 | //提取.pri文件资源: https://docs.microsoft.com/windows/uwp/app-resources/makepri-exe-command-options
11 | //.pri转储.xml资源列表: MakePri.exe dump /if [priPath] /of [xmlPath]
12 |
13 | [DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode,
14 | ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
15 | private static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved);
16 |
17 | /// 获取格式为"@[filename],-[strID]"或"@{[packageName]?ms-resource://[resPath]}"的直接字符串
18 | /// 要转换的字符串
19 | /// resStr为Null时返回值为string.Empty; resStr首字符为@但解析失败时返回string.Empty
20 | /// [fileName]:文件路径; [strID]:字符串资源索引; [packageName]:UWP带版本号包名; [resPath]:pri资源路径
21 | public static string GetDirectString(string resStr)
22 | {
23 | StringBuilder outBuff = new StringBuilder(1024);
24 | SHLoadIndirectString(resStr, outBuff, 1024, IntPtr.Zero);
25 | return outBuff.ToString();
26 | }
27 |
28 | public static readonly string OK = GetDirectString("@shell32.dll,-9752");
29 | public static readonly string Cancel = GetDirectString("@shell32.dll,-9751");
30 | }
31 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Windows.Forms;
8 |
9 | namespace BluePointLilac.Methods
10 | {
11 | public static class SingleInstance
12 | {
13 | [DllImport("user32.dll")]
14 | private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
15 |
16 | [DllImport("user32.dll")]
17 | private static extern bool SetForegroundWindow(IntPtr hWnd);
18 |
19 | /// 判断单实例程序是否正在运行
20 | /// 若正在运行激活窗口
21 | public static bool IsRunning()
22 | {
23 | using(Process current = Process.GetCurrentProcess())
24 | {
25 | foreach(Process process in Process.GetProcessesByName(current.ProcessName))
26 | {
27 | using(process)
28 | {
29 | if(process.Id == current.Id) continue;
30 | if(process.MainModule.FileName == current.MainModule.FileName)
31 | {
32 | const int SW_RESTORE = 9;
33 | ShowWindowAsync(process.MainWindowHandle, SW_RESTORE);
34 | SetForegroundWindow(process.MainWindowHandle);
35 | return true;
36 | }
37 | }
38 | }
39 | return false;
40 | }
41 | }
42 |
43 | /// 重启单实例程序
44 | /// 重启程序时传入参数
45 | /// 用于更新程序的新版本文件路径,为null则为普通重启
46 | public static void Restart(string[] args = null, string updatePath = null)
47 | {
48 | string appPath = Application.ExecutablePath;
49 | string command = appPath;
50 | if(args != null && args.Length > 0) command += "," + string.Join(" ", args);
51 | List contents = new List();
52 | //vbs命令逐行执行不等待,故加些代码确定上一条命令执行是否完成
53 | contents.AddRange(new[]
54 | {
55 | "On Error Resume Next",
56 | "WScript.Sleep 1000",//等待程序结束
57 | "Dim wsh, fso",
58 | "Set wsh = CreateObject(\"WScript.Shell\")",
59 | "Set fso = CreateObject(\"Scripting.FileSystemObject\")",
60 | });
61 |
62 | if(File.Exists(updatePath))
63 | {
64 | contents.AddRange(new[]
65 | {
66 | $"fso.DeleteFile \"{appPath}\"",
67 | $"Do While fso.FileExists(\"{appPath}\")",
68 | "WScript.Sleep 100",
69 | "Loop",//确定文件删除完成
70 | $"fso.MoveFile \"{updatePath}\",\"{appPath}\"",//更新文件
71 | $"Do While fso.FileExists(\"{updatePath}\")",//确定文件已被移动
72 | "WScript.Sleep 100",
73 | $"Loop",
74 | });
75 | }
76 | contents.AddRange(new[]
77 | {
78 | $"wsh.Run \"{command}\"",
79 | "fso.DeleteFile(WScript.ScriptFullName)",//vbs自删命令
80 | "Set wsh = Nothing",
81 | "Set fso = Nothing",
82 | });
83 |
84 | string vbsPath = Path.GetTempPath() + Guid.NewGuid() + ".vbs";
85 | File.WriteAllLines(vbsPath, contents.ToArray(), Encoding.Unicode);
86 | Application.Exit();
87 | using(Process process = new Process())
88 | {
89 | process.StartInfo.FileName = "wscript.exe";
90 | process.StartInfo.Arguments = vbsPath;
91 | process.Start();
92 | }
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/StringExtension.cs:
--------------------------------------------------------------------------------
1 | namespace BluePointLilac.Methods
2 | {
3 | //为兼容.Net Framework 3.5,无法引用Microsoft.CSharp.dll(中的string.IsNullOrWhiteSpace)写了这个扩展方法
4 | public static class StringExtension
5 | {
6 | public static bool IsNullOrWhiteSpace(this string str)
7 | {
8 | if(string.IsNullOrEmpty(str)) return true;
9 | return str.Trim().Length == 0;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows.Forms;
3 |
4 | namespace BluePointLilac.Methods
5 | {
6 | public static class TextBoxExtension
7 | {
8 | /// TextBox仿RichTextBox按住Ctrl加鼠标滚轮放缩字体
9 | public static void CanResizeFont(this TextBox box)
10 | {
11 | box.MouseWheel += (sender, e) =>
12 | {
13 | if(Control.ModifierKeys != Keys.Control) return;
14 | float size = box.Font.Size;
15 | if(size < 8F && e.Delta < 0) return;
16 | if(size > 40F && e.Delta > 0) return;
17 | box.Font = new Font(box.Font.FontFamily, size + (e.Delta > 0 ? 1F : -1F));
18 | };
19 | }
20 |
21 | /// TextBox在文字未超出边界时隐藏滚动条,超出时显示
22 | public static void SetAutoShowScroll(this TextBox box, ScrollBars scrollBars)
23 | {
24 |
25 | void SetScrollVisible()
26 | {
27 | Size szBox = box.ClientSize;
28 | Size szText = TextRenderer.MeasureText(box.Text, box.Font);
29 | if((scrollBars | ScrollBars.Vertical) == ScrollBars.Vertical)
30 | {
31 | if(szText.Height > szBox.Height)
32 | {
33 | box.ScrollBars = scrollBars | ScrollBars.Vertical;
34 | }
35 | else
36 | {
37 | box.ScrollBars = scrollBars & ~ScrollBars.Vertical;
38 | }
39 | }
40 | if((scrollBars | ScrollBars.Horizontal) == ScrollBars.Horizontal)
41 | {
42 | if(szText.Width > szBox.Width)
43 | {
44 | box.ScrollBars = scrollBars | ScrollBars.Horizontal;
45 | }
46 | else
47 | {
48 | box.ScrollBars = scrollBars & ~ScrollBars.Horizontal;
49 | }
50 | }
51 | };
52 | box.TextChanged += (sender, e) => SetScrollVisible();
53 | box.FontChanged += (sender, e) => SetScrollVisible();
54 | box.ClientSizeChanged += (sender, e) => SetScrollVisible();
55 | }
56 |
57 | /// TextBox只读时可以使用Ctrl+A全选快捷键
58 | public static void CanSelectAllWhenReadOnly(this TextBox box)
59 | {
60 | box.KeyDown += (sender, e) =>
61 | {
62 | if(box.ReadOnly && e.Control && e.KeyCode == Keys.A) box.SelectAll();
63 | };
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/ToolTipBox.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace BluePointLilac.Methods
4 | {
5 | public static class ToolTipBox
6 | {
7 | public static void SetToolTip(Control ctr, string tip)
8 | {
9 | if(tip.IsNullOrWhiteSpace()) return;
10 | ToolTip toolTip = new ToolTip { InitialDelay = 1 };
11 | toolTip.SetToolTip(ctr, tip);
12 | ctr.Disposed += (sender, e) => toolTip.Dispose();
13 | }
14 |
15 | public static void SetToolTip(ToolStripItem item, string tip)
16 | {
17 | //必须先设置item的Owner
18 | item.Owner.ShowItemToolTips = true;
19 | item.ToolTipText = tip;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/ContextMenuManager/BluePointLilac.Methods/WinOsVersion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BluePointLilac.Methods
4 | {
5 | // 判断Windows系统版本
6 | // https://docs.microsoft.com/windows/release-health/release-information
7 | public static class WinOsVersion
8 | {
9 | public static readonly Version Current = Environment.OSVersion.Version;
10 | public static readonly Version Win11 = new Version(10, 0, 22000);
11 | public static readonly Version Win10 = new Version(10, 0);
12 | public static readonly Version Win8_1 = new Version(6, 3);
13 | public static readonly Version Win8 = new Version(6, 2);
14 | public static readonly Version Win7 = new Version(6, 1);
15 | public static readonly Version Vista = new Version(6, 0);
16 | public static readonly Version XP = new Version(5, 1);
17 |
18 | public static readonly Version Win10_1507 = new Version(10, 0, 10240);
19 | public static readonly Version Win10_1511 = new Version(10, 0, 10586);
20 | public static readonly Version Win10_1607 = new Version(10, 0, 14393);
21 | public static readonly Version Win10_1703 = new Version(10, 0, 15063);
22 | public static readonly Version Win10_1709 = new Version(10, 0, 16299);
23 | public static readonly Version Win10_1803 = new Version(10, 0, 17134);
24 | public static readonly Version Win10_1809 = new Version(10, 0, 17763);
25 | public static readonly Version Win10_1903 = new Version(10, 0, 18362);
26 | public static readonly Version Win10_1909 = new Version(10, 0, 18363);
27 | public static readonly Version Win10_2004 = new Version(10, 0, 19041);
28 | public static readonly Version Win10_20H2 = new Version(10, 0, 19042);
29 | }
30 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/DetailedEditDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls
7 | {
8 | sealed class DetailedEditDialog : CommonDialog
9 | {
10 | public Guid GroupGuid { get; set; }
11 |
12 | public override void Reset() { }
13 |
14 | protected override bool RunDialog(IntPtr hwndOwner)
15 | {
16 | using(SubItemsForm frm = new SubItemsForm())
17 | using(DetailedEditList list = new DetailedEditList())
18 | {
19 | var location = GuidInfo.GetIconLocation(GroupGuid);
20 | frm.Icon = ResourceIcon.GetIcon(location.IconPath, location.IconIndex);
21 | frm.Text = AppString.Dialog.DetailedEdit.Replace("%s", GuidInfo.GetText(GroupGuid));
22 | frm.TopMost = AppConfig.TopMost;
23 | frm.AddList(list);
24 | list.GroupGuid = GroupGuid;
25 | list.UseUserDic = XmlDicHelper.DetailedEditGuidDic[GroupGuid];
26 | list.LoadItems();
27 | frm.ShowDialog();
28 | }
29 | return false;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/DictionariesBox.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Drawing;
6 | using System.IO;
7 | using System.Text;
8 | using System.Windows.Forms;
9 |
10 | namespace ContextMenuManager.Controls
11 | {
12 | sealed class DictionariesBox : TabControl
13 | {
14 | public DictionariesBox()
15 | {
16 | SuspendLayout();
17 | Dock = DockStyle.Fill;
18 | Controls.AddRange(pages);
19 | ForeColor = MyMainForm.FormFore;
20 | BackColor = MyMainForm.FormBack;
21 | Font = SystemFonts.MenuFont;
22 | Font = new Font(Font.FontFamily, Font.Size + 1F);
23 | cms.Items.AddRange(items);
24 | for(int i = 0; i < 6; i++)
25 | {
26 | boxs[i] = new ReadOnlyRichTextBox { Parent = pages[i] };
27 | if(i > 0) boxs[i].ContextMenuStrip = cms;
28 | }
29 | items[0].Click += (sender, e) => ExternalProgram.OpenNotepadWithText(GetInitialText());
30 | items[2].Click += (sender, e) => SaveFile();
31 | boxs[0].Controls.Add(btnOpenDir);
32 | btnOpenDir.Top = boxs[0].Height - btnOpenDir.Height;
33 | ToolTipBox.SetToolTip(btnOpenDir, AppString.Menu.FileLocation);
34 | btnOpenDir.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(AppConfig.DicsDir);
35 | SelectedIndexChanged += (sender, e) => LoadText();
36 | VisibleChanged += (sender, e) => this.SetEnabled(Visible);
37 | ResumeLayout();
38 | }
39 |
40 | readonly TabPage[] pages =
41 | {
42 | new TabPage(AppString.Other.DictionaryDescription),
43 | new TabPage(AppString.SideBar.AppLanguage),
44 | new TabPage(AppString.Other.GuidInfosDictionary),
45 | new TabPage(AppString.SideBar.DetailedEdit),
46 | new TabPage(AppString.SideBar.EnhanceMenu),
47 | new TabPage(AppString.Other.UwpMode)
48 | };
49 | readonly ReadOnlyRichTextBox[] boxs = new ReadOnlyRichTextBox[6];
50 | readonly PictureButton btnOpenDir = new PictureButton(AppImage.Open)
51 | {
52 | Anchor = AnchorStyles.Left | AnchorStyles.Bottom,
53 | Left = 0
54 | };
55 | readonly ContextMenuStrip cms = new ContextMenuStrip();
56 | readonly ToolStripItem[] items =
57 | {
58 | new RToolStripMenuItem(AppString.Menu.Edit),
59 | new RToolStripSeparator(),
60 | new RToolStripMenuItem(AppString.Menu.Save)
61 | };
62 |
63 | private void SaveFile()
64 | {
65 | using(SaveFileDialog dlg = new SaveFileDialog())
66 | {
67 | string dirPath = AppConfig.UserDicsDir;
68 | switch(SelectedIndex)
69 | {
70 | case 1:
71 | dirPath = AppConfig.LangsDir;
72 | dlg.FileName = AppConfig.ZH_CNINI;
73 | break;
74 | case 2:
75 | dlg.FileName = AppConfig.GUIDINFOSDICINI;
76 | break;
77 | case 3:
78 | dlg.FileName = AppConfig.DETAILEDEDITDICXML;
79 | break;
80 | case 4:
81 | dlg.FileName = AppConfig.ENHANCEMENUSICXML;
82 | break;
83 | case 5:
84 | dlg.FileName = AppConfig.UWPMODEITEMSDICXML;
85 | break;
86 | }
87 | dlg.Filter = $"{dlg.FileName}|*{Path.GetExtension(dlg.FileName)}";
88 | Directory.CreateDirectory(dirPath);
89 | dlg.InitialDirectory = dirPath;
90 | if(dlg.ShowDialog() == DialogResult.OK)
91 | {
92 | File.WriteAllText(dlg.FileName, GetInitialText(), Encoding.Unicode);
93 | }
94 | }
95 | }
96 |
97 | private string GetInitialText()
98 | {
99 | switch(SelectedIndex)
100 | {
101 | case 0:
102 | return AppString.Other.Dictionaries;
103 | case 1:
104 | return Properties.Resources.AppLanguageDic;
105 | case 2:
106 | return Properties.Resources.GuidInfosDic;
107 | case 3:
108 | return Properties.Resources.DetailedEditDic;
109 | case 4:
110 | return Properties.Resources.EnhanceMenusDic;
111 | case 5:
112 | return Properties.Resources.UwpModeItemsDic;
113 | default:
114 | return string.Empty;
115 | }
116 | }
117 |
118 | public void LoadText()
119 | {
120 | int index = SelectedIndex;
121 | if(boxs[index].Text.Length > 0) return;
122 | Action action = null;
123 | switch(index)
124 | {
125 | case 0:
126 | case 1:
127 | case 2:
128 | action = boxs[index].LoadIni; break;
129 | case 3:
130 | case 4:
131 | case 5:
132 | action = boxs[index].LoadXml; break;
133 | }
134 | BeginInvoke(action, new[] { GetInitialText() });
135 | }
136 | }
137 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/EnhanceMenusDialog.cs:
--------------------------------------------------------------------------------
1 | using ContextMenuManager.Methods;
2 | using System;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls
7 | {
8 | sealed class EnhanceMenusDialog : CommonDialog
9 | {
10 | public string ScenePath { get; set; }
11 |
12 | public override void Reset() { }
13 |
14 | protected override bool RunDialog(IntPtr hwndOwner)
15 | {
16 | using(SubItemsForm frm = new SubItemsForm())
17 | using(EnhanceMenuList list = new EnhanceMenuList())
18 | {
19 | frm.Text = AppString.SideBar.EnhanceMenu;
20 | frm.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
21 | frm.TopMost = AppConfig.TopMost;
22 | frm.AddList(list);
23 | list.ScenePath = ScenePath;
24 | list.UseUserDic = XmlDicHelper.EnhanceMenuPathDic[ScenePath];
25 | list.LoadItems();
26 | frm.ShowDialog();
27 | }
28 | return false;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/ExplorerRestarter.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | sealed class ExplorerRestarter : MyListItem
10 | {
11 | public ExplorerRestarter()
12 | {
13 | Visible = false;
14 | DoubleBuffered = false;
15 | Dock = DockStyle.Bottom;
16 | Image = AppImage.Explorer;
17 | Text = AppString.Other.RestartExplorer;
18 | ToolTipBox.SetToolTip(BtnRestart, AppString.Tip.RestartExplorer);
19 | AddCtr(BtnRestart);
20 | this.CanMoveForm();
21 | ShowHandler += () => Visible = true;
22 | HideHandler += () => Visible = false;
23 | BtnRestart.MouseDown += (sender, e) =>
24 | {
25 | ExternalProgram.RestartExplorer();
26 | Visible = false;
27 | };
28 | }
29 |
30 | public new bool Visible
31 | {
32 | get => base.Visible;
33 | set
34 | {
35 | bool flag = base.Visible != value && Parent != null;
36 | base.Visible = value;
37 | if(flag) Parent.Height += value ? Height : -Height;
38 | }
39 | }
40 |
41 | private readonly PictureButton BtnRestart = new PictureButton(AppImage.RestartExplorer);
42 |
43 | private static Action ShowHandler;
44 | private static Action HideHandler;
45 |
46 | public static new void Show() => ShowHandler?.Invoke();
47 | public static new void Hide() => HideHandler?.Invoke();
48 | }
49 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/FileExtensionDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | sealed class FileExtensionDialog : SelectDialog
10 | {
11 | public string Extension
12 | {
13 | get => Selected.Trim();
14 | set => Selected = value?.Trim();
15 | }
16 |
17 | public FileExtensionDialog()
18 | {
19 | CanEdit = true;
20 | Title = AppString.Dialog.SelectExtension;
21 | Items = FileExtensionItems.ToArray();
22 | }
23 |
24 | public static List FileExtensionItems
25 | {
26 | get
27 | {
28 | List items = new List();
29 | using (var key = RegistryEx.GetRegistryKey(FileExtension.FILEEXTSPATH))
30 | {
31 | if (key != null)
32 | {
33 | foreach (string keyName in key.GetSubKeyNames())
34 | {
35 | if (keyName.StartsWith(".")) items.Add(keyName.Substring(1));
36 | }
37 | }
38 | }
39 | return items;
40 | }
41 | }
42 |
43 | protected override bool RunDialog(IntPtr hwndOwner)
44 | {
45 | bool flag = base.RunDialog(hwndOwner);
46 | if(flag)
47 | {
48 | string extension = ObjectPath.RemoveIllegalChars(Extension);
49 | int index = extension.LastIndexOf('.');
50 | if(index >= 0) Extension = extension.Substring(index);
51 | else Extension = $".{extension}";
52 | }
53 | return flag;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/FoldSubItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Controls.Interfaces;
4 | using ContextMenuManager.Methods;
5 | using System;
6 | using System.Drawing;
7 | using System.IO;
8 | using System.Windows.Forms;
9 | using static ContextMenuManager.Methods.ObjectPath;
10 |
11 | namespace ContextMenuManager.Controls
12 | {
13 | class FoldSubItem : MyListItem
14 | {
15 | public FoldGroupItem FoldGroupItem { get; set; }
16 |
17 | public void Indent()
18 | {
19 | int w = 40.DpiZoom();
20 | Controls["Image"].Left += w;
21 | Controls["Text"].Left += w;
22 | }
23 | }
24 |
25 | class FoldGroupItem : MyListItem, IBtnShowMenuItem
26 | {
27 | private bool isFold;
28 | public bool IsFold
29 | {
30 | get => isFold;
31 | set
32 | {
33 | if(isFold == value) return;
34 | isFold = value;
35 | FoldMe(value);
36 | }
37 | }
38 |
39 | public string GroupPath { get; set; }
40 | public PathType PathType { get; set; }
41 |
42 | public MenuButton BtnShowMenu { get; set; }
43 | readonly PictureButton btnFold;
44 | readonly PictureButton btnOpenPath;
45 | readonly RToolStripMenuItem tsiFoldAll = new RToolStripMenuItem(AppString.Menu.FoldAll);
46 | readonly RToolStripMenuItem tsiUnfoldAll = new RToolStripMenuItem(AppString.Menu.UnfoldAll);
47 |
48 | public FoldGroupItem(string groupPath, PathType pathType)
49 | {
50 | btnFold = new PictureButton(AppImage.Up);
51 | BtnShowMenu = new MenuButton(this);
52 | btnOpenPath = new PictureButton(AppImage.Open);
53 |
54 | if(pathType == PathType.File || pathType == PathType.Directory)
55 | {
56 | groupPath = Environment.ExpandEnvironmentVariables(groupPath);
57 | }
58 | string tip = null;
59 | Action openPath = null;
60 | switch(pathType)
61 | {
62 | case PathType.File:
63 | tip = AppString.Menu.FileLocation;
64 | Text = Path.GetFileNameWithoutExtension(groupPath);
65 | Image = ResourceIcon.GetExtensionIcon(groupPath).ToBitmap();
66 | openPath = () => ExternalProgram.JumpExplorer(groupPath, AppConfig.OpenMoreExplorer);
67 | break;
68 | case PathType.Directory:
69 | tip = AppString.Menu.FileLocation;
70 | Text = Path.GetFileNameWithoutExtension(groupPath);
71 | Image = ResourceIcon.GetFolderIcon(groupPath).ToBitmap();
72 | openPath = () => ExternalProgram.OpenDirectory(groupPath);
73 | break;
74 | case PathType.Registry:
75 | tip = AppString.Menu.RegistryLocation;
76 | openPath = () => ExternalProgram.JumpRegEdit(groupPath, null, AppConfig.OpenMoreRegedit);
77 | break;
78 | }
79 | PathType = pathType;
80 | GroupPath = groupPath;
81 | Font = new Font(Font, FontStyle.Bold);
82 | AddCtrs(new[] { btnFold, btnOpenPath });
83 | ContextMenuStrip.Items.AddRange(new[] { tsiFoldAll, tsiUnfoldAll });
84 | MouseDown += (sender, e) =>
85 | {
86 | if(e.Button == MouseButtons.Left) Fold();
87 | };
88 | btnFold.MouseDown += (sender, e) =>
89 | {
90 | Fold();
91 | btnFold.Image = btnFold.BaseImage;
92 | };
93 | tsiFoldAll.Click += (sender, e) => FoldAll(true);
94 | tsiUnfoldAll.Click += (sender, e) => FoldAll(false);
95 | btnOpenPath.MouseDown += (sender, e) => openPath.Invoke();
96 | ToolTipBox.SetToolTip(btnOpenPath, tip);
97 | }
98 |
99 | public void SetVisibleWithSubItemCount()
100 | {
101 | foreach(Control ctr in Parent.Controls)
102 | {
103 | if(ctr is FoldSubItem item && item.FoldGroupItem == this)
104 | {
105 | Visible = true;
106 | return;
107 | }
108 | }
109 | Visible = false;
110 | }
111 |
112 | private void Fold()
113 | {
114 | Parent.SuspendLayout();
115 | IsFold = !IsFold;
116 | Parent.ResumeLayout();
117 | }
118 |
119 | private void FoldMe(bool isFold)
120 | {
121 | btnFold.BaseImage = isFold ? AppImage.Down : AppImage.Up;
122 | foreach(Control ctr in Parent?.Controls)
123 | {
124 | if(ctr is FoldSubItem item && item.FoldGroupItem == this) ctr.Visible = !isFold;
125 | }
126 | }
127 |
128 | private void FoldAll(bool isFold)
129 | {
130 | Parent.SuspendLayout();
131 | foreach(Control ctr in Parent.Controls)
132 | {
133 | if(ctr is FoldGroupItem groupItem) groupItem.IsFold = isFold;
134 | }
135 | Parent.ResumeLayout();
136 | }
137 | }
138 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/GuidBlockedItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Controls.Interfaces;
4 | using ContextMenuManager.Methods;
5 | using System;
6 | using System.Linq;
7 | using System.Windows.Forms;
8 |
9 | namespace ContextMenuManager.Controls
10 | {
11 | class GuidBlockedItem : MyListItem, IBtnShowMenuItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiGuidItem, ITsiRegPathItem
12 | {
13 | public GuidBlockedItem(string value)
14 | {
15 | InitializeComponents();
16 | Value = value;
17 | if(GuidEx.TryParse(value, out Guid guid))
18 | {
19 | Guid = guid;
20 | Image = GuidInfo.GetImage(guid);
21 | ItemFilePath = GuidInfo.GetFilePath(Guid);
22 | }
23 | else
24 | {
25 | Guid = Guid.Empty;
26 | Image = AppImage.SystemFile;
27 | }
28 | Text = ItemText;
29 | }
30 |
31 | public string Value { get; set; }
32 | public Guid Guid { get; set; }
33 | public string SearchText => Value;
34 | public string ValueName => Value;
35 | public string RegPath
36 | {
37 | get
38 | {
39 | foreach(string path in GuidBlockedList.BlockedPaths)
40 | {
41 | using(var key = RegistryEx.GetRegistryKey(path))
42 | {
43 | if(key == null) continue;
44 | if(key.GetValueNames().Contains(Value, StringComparer.OrdinalIgnoreCase)) return path;
45 | }
46 | }
47 | return null;
48 | }
49 | }
50 |
51 | public string ItemText
52 | {
53 | get
54 | {
55 | string text;
56 | if(GuidEx.TryParse(Value, out Guid guid)) text = GuidInfo.GetText(guid);
57 | else text = AppString.Message.MalformedGuid;
58 | text += "\n" + Value;
59 | return text;
60 | }
61 | }
62 |
63 | public string ItemFilePath { get; set; }
64 | public MenuButton BtnShowMenu { get; set; }
65 | public DetailedEditButton BtnDetailedEdit { get; set; }
66 | public WebSearchMenuItem TsiSearch { get; set; }
67 | public FileLocationMenuItem TsiFileLocation { get; set; }
68 | public FilePropertiesMenuItem TsiFileProperties { get; set; }
69 | public HandleGuidMenuItem TsiHandleGuid { get; set; }
70 | public RegLocationMenuItem TsiRegLocation { get; set; }
71 |
72 | readonly RToolStripMenuItem TsiDetails = new RToolStripMenuItem(AppString.Menu.Details);
73 | readonly RToolStripMenuItem TsiDelete = new RToolStripMenuItem(AppString.Menu.Delete);
74 |
75 | private void InitializeComponents()
76 | {
77 | BtnShowMenu = new MenuButton(this);
78 | BtnDetailedEdit = new DetailedEditButton(this);
79 | TsiSearch = new WebSearchMenuItem(this);
80 | TsiFileProperties = new FilePropertiesMenuItem(this);
81 | TsiFileLocation = new FileLocationMenuItem(this);
82 | TsiRegLocation = new RegLocationMenuItem(this);
83 | TsiHandleGuid = new HandleGuidMenuItem(this);
84 |
85 | ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiHandleGuid,
86 | new RToolStripSeparator(), TsiDetails, new RToolStripSeparator(), TsiDelete });
87 | TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,
88 | new RToolStripSeparator(), TsiFileProperties, TsiFileLocation, TsiRegLocation});
89 |
90 | TsiDelete.Click += (sender, e) => DeleteMe();
91 | }
92 |
93 | public void DeleteMe()
94 | {
95 | if(AppMessageBox.Show(AppString.Message.ConfirmDelete, MessageBoxButtons.YesNo) != DialogResult.Yes) return;
96 | Array.ForEach(GuidBlockedList.BlockedPaths, path => RegistryEx.DeleteValue(path, Value));
97 | if(!Guid.Equals(Guid.Empty)) ExplorerRestarter.Show();
98 | int index = Parent.Controls.GetChildIndex(this);
99 | index -= (index < Parent.Controls.Count - 1) ? 0 : 1;
100 | Parent.Controls[index].Focus();
101 | Dispose();
102 | }
103 | }
104 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/GuidBlockedList.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using Microsoft.Win32;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Windows.Forms;
9 |
10 | namespace ContextMenuManager.Controls
11 | {
12 | sealed class GuidBlockedList : MyList // 其他规则 GUID锁
13 | {
14 | public const string HKLMBLOCKED = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked";
15 | public const string HKCUBLOCKED = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked";
16 | public static readonly string[] BlockedPaths = { HKLMBLOCKED, HKCUBLOCKED };
17 |
18 | public void LoadItems()
19 | {
20 | AddNewItem();
21 | LoadBlockedItems();
22 | }
23 |
24 | private void LoadBlockedItems()
25 | {
26 | List values = new List();
27 | foreach(string path in BlockedPaths)
28 | {
29 | using(RegistryKey key = RegistryEx.GetRegistryKey(path))
30 | {
31 | if(key == null) continue;
32 | foreach(string value in key.GetValueNames())
33 | {
34 | if(values.Contains(value, StringComparer.OrdinalIgnoreCase)) continue;
35 | AddItem(new GuidBlockedItem(value));
36 | values.Add(value);
37 | }
38 | }
39 | }
40 | }
41 |
42 | private void AddNewItem()
43 | {
44 | NewItem newItem = new NewItem(AppString.Other.AddGuidBlockedItem);
45 | AddItem(newItem);
46 | newItem.AddNewItem += () =>
47 | {
48 | using(InputDialog dlg = new InputDialog { Title = AppString.Dialog.InputGuid })
49 | {
50 | if(GuidEx.TryParse(Clipboard.GetText(), out Guid guid)) dlg.Text = guid.ToString();
51 | if(dlg.ShowDialog() != DialogResult.OK) return;
52 | if(GuidEx.TryParse(dlg.Text, out guid))
53 | {
54 | string value = guid.ToString("B");
55 | Array.ForEach(BlockedPaths, path => Registry.SetValue(path, value, ""));
56 | for(int i = 1; i < Controls.Count; i++)
57 | {
58 | if(((GuidBlockedItem)Controls[i]).Guid.Equals(guid))
59 | {
60 | AppMessageBox.Show(AppString.Message.HasBeenAdded);
61 | return;
62 | }
63 | }
64 | InsertItem(new GuidBlockedItem(value), 1);
65 | ExplorerRestarter.Show();
66 | }
67 | else AppMessageBox.Show(AppString.Message.MalformedGuid);
68 | }
69 | };
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/IEItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Controls.Interfaces;
4 | using ContextMenuManager.Methods;
5 | using Microsoft.Win32;
6 | using System;
7 | using System.Drawing;
8 | using System.Windows.Forms;
9 |
10 | namespace ContextMenuManager.Controls
11 | {
12 | sealed class IEItem : MyListItem, ITsiRegPathItem, ITsiFilePathItem, ITsiRegDeleteItem, ITsiCommandItem,
13 | ITsiWebSearchItem, ITsiTextItem, ITsiRegExportItem, IBtnShowMenuItem, IChkVisibleItem
14 | {
15 | public static readonly string[] MeParts = { "MenuExt", "-MenuExt" };
16 |
17 | public IEItem(string regPath)
18 | {
19 | InitializeComponents();
20 | RegPath = regPath;
21 | }
22 |
23 | private string regPath;
24 | public string RegPath
25 | {
26 | get => regPath;
27 | set
28 | {
29 | regPath = value;
30 | Text = ItemText;
31 | Image = ItemImage;
32 | }
33 | }
34 | public string ValueName => null;
35 | private string KeyName => RegistryEx.GetKeyName(RegPath);
36 | private string BackupPath => $@"{IEList.IEPath}\{(ItemVisible ? MeParts[1] : MeParts[0])}\{KeyName}";
37 | private string MeKeyName => RegistryEx.GetKeyName(RegistryEx.GetParentPath(RegPath));
38 |
39 | public string ItemText
40 | {
41 | get => RegistryEx.GetKeyName(RegPath);
42 | set
43 | {
44 | string newPath = $@"{RegistryEx.GetParentPath(RegPath)}\{value.Replace("\\", "")}";
45 | string defaultValue = Registry.GetValue(newPath, "", null)?.ToString();
46 | if(!defaultValue.IsNullOrWhiteSpace())
47 | {
48 | AppMessageBox.Show(AppString.Message.HasBeenAdded);
49 | }
50 | else
51 | {
52 | RegistryEx.MoveTo(RegPath, newPath);
53 | RegPath = newPath;
54 | }
55 | }
56 | }
57 |
58 | public bool ItemVisible
59 | {
60 | get => MeKeyName.Equals(MeParts[0], StringComparison.OrdinalIgnoreCase);
61 | set
62 | {
63 | RegistryEx.MoveTo(RegPath, BackupPath);
64 | RegPath = BackupPath;
65 | }
66 | }
67 |
68 | public string ItemCommand
69 | {
70 | get => Registry.GetValue(RegPath, "", null)?.ToString();
71 | set
72 | {
73 | Registry.SetValue(RegPath, "", value);
74 | Image = ItemImage;
75 | }
76 | }
77 |
78 | public string SearchText => $@"{AppString.SideBar.IEMenu} {Text}";
79 | public string ItemFilePath => ObjectPath.ExtractFilePath(ItemCommand);
80 | private Icon ItemIcon => ResourceIcon.GetIcon(ItemFilePath) ?? ResourceIcon.GetExtensionIcon(ItemFilePath);
81 | private Image ItemImage => ItemIcon?.ToBitmap() ?? AppImage.NotFound;
82 |
83 | public MenuButton BtnShowMenu { get; set; }
84 | public VisibleCheckBox ChkVisible { get; set; }
85 | public WebSearchMenuItem TsiSearch { get; set; }
86 | public ChangeTextMenuItem TsiChangeText { get; set; }
87 | public ChangeCommandMenuItem TsiChangeCommand { get; set; }
88 | public FileLocationMenuItem TsiFileLocation { get; set; }
89 | public FilePropertiesMenuItem TsiFileProperties { get; set; }
90 | public RegLocationMenuItem TsiRegLocation { get; set; }
91 | public RegExportMenuItem TsiRegExport { get; set; }
92 | public DeleteMeMenuItem TsiDeleteMe { get; set; }
93 | readonly RToolStripMenuItem TsiDetails = new RToolStripMenuItem(AppString.Menu.Details);
94 |
95 | private void InitializeComponents()
96 | {
97 | BtnShowMenu = new MenuButton(this);
98 | ChkVisible = new VisibleCheckBox(this);
99 | TsiChangeText = new ChangeTextMenuItem(this);
100 | TsiChangeCommand = new ChangeCommandMenuItem(this);
101 | TsiSearch = new WebSearchMenuItem(this);
102 | TsiFileLocation = new FileLocationMenuItem(this);
103 | TsiFileProperties = new FilePropertiesMenuItem(this);
104 | TsiRegLocation = new RegLocationMenuItem(this);
105 | TsiRegExport = new RegExportMenuItem(this);
106 | TsiDeleteMe = new DeleteMeMenuItem(this);
107 |
108 | ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText,
109 | new RToolStripSeparator(), TsiDetails, new RToolStripSeparator(), TsiDeleteMe });
110 |
111 | TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new RToolStripSeparator(),
112 | TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport});
113 | }
114 |
115 | public void DeleteMe()
116 | {
117 | RegistryEx.DeleteKeyTree(RegPath);
118 | RegistryEx.DeleteKeyTree(BackupPath);
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/IEList.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using Microsoft.Win32;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Windows.Forms;
8 |
9 | namespace ContextMenuManager.Controls
10 | {
11 | sealed class IEList : MyList // 其他规则 IE浏览器
12 | {
13 | public const string IEPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer";
14 |
15 | public void LoadItems()
16 | {
17 | AddNewItem();
18 | LoadIEItems();
19 | }
20 |
21 | private void LoadIEItems()
22 | {
23 | List names = new List();
24 | using(RegistryKey ieKey = RegistryEx.GetRegistryKey(IEPath))
25 | {
26 | if(ieKey == null) return;
27 | foreach(string part in IEItem.MeParts)
28 | {
29 | using(RegistryKey meKey = ieKey.OpenSubKey(part))
30 | {
31 | if(meKey == null) continue;
32 | foreach(string keyName in meKey.GetSubKeyNames())
33 | {
34 | if(names.Contains(keyName, StringComparer.OrdinalIgnoreCase)) continue;
35 | using(RegistryKey key = meKey.OpenSubKey(keyName))
36 | {
37 | if(!string.IsNullOrEmpty(key.GetValue("")?.ToString()))
38 | {
39 | AddItem(new IEItem(key.Name));
40 | names.Add(keyName);
41 | }
42 | }
43 | }
44 | }
45 | }
46 | }
47 | }
48 |
49 | private void AddNewItem()
50 | {
51 | NewItem newItem = new NewItem();
52 | AddItem(newItem);
53 | newItem.AddNewItem += () =>
54 | {
55 | using(NewIEDialog dlg = new NewIEDialog())
56 | {
57 | if(dlg.ShowDialog() != DialogResult.OK) return;
58 | InsertItem(new IEItem(dlg.RegPath), 1);
59 | }
60 | };
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using ContextMenuManager.Methods;
3 | using System.Windows.Forms;
4 |
5 | namespace ContextMenuManager.Controls.Interfaces
6 | {
7 | interface IBtnDeleteItem
8 | {
9 | DeleteButton BtnDelete { get; set; }
10 | void DeleteMe();
11 | }
12 |
13 | sealed class DeleteButton : PictureButton
14 | {
15 | public DeleteButton(IBtnDeleteItem item) : base(AppImage.Delete)
16 | {
17 | MyListItem listItem = (MyListItem)item;
18 | listItem.AddCtr(this);
19 | MouseDown += (sender, e) =>
20 | {
21 | if(AppMessageBox.Show(AppString.Message.ConfirmDelete, MessageBoxButtons.YesNo) == DialogResult.Yes) item.DeleteMe();
22 | };
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/IBtnMoveUpDownItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using ContextMenuManager.Methods;
3 |
4 | namespace ContextMenuManager.Controls.Interfaces
5 | {
6 | interface IBtnMoveUpDownItem
7 | {
8 | MoveButton BtnMoveUp { get; set; }
9 | MoveButton BtnMoveDown { get; set; }
10 | }
11 |
12 | sealed class MoveButton : PictureButton
13 | {
14 | public MoveButton(IBtnMoveUpDownItem item, bool isUp) : base(isUp ? AppImage.Up : AppImage.Down)
15 | {
16 | ((MyListItem)item).AddCtr(this);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/IBtnShowMenuItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using ContextMenuManager.Methods;
3 | using System.Windows.Forms;
4 |
5 | namespace ContextMenuManager.Controls.Interfaces
6 | {
7 | interface IBtnShowMenuItem
8 | {
9 | ContextMenuStrip ContextMenuStrip { get; set; }
10 | MenuButton BtnShowMenu { get; set; }
11 | }
12 |
13 | sealed class MenuButton : PictureButton
14 | {
15 | public MenuButton(IBtnShowMenuItem item) : base(AppImage.Setting)
16 | {
17 | item.ContextMenuStrip = new ContextMenuStrip();
18 | ((MyListItem)item).AddCtr(this);
19 | bool isShow = false;
20 | MouseDown += (sender, e) =>
21 | {
22 | if(!isShow) item.ContextMenuStrip.Show(this, 0, Height);
23 | else item.ContextMenuStrip.Close();
24 | isShow = !isShow;
25 | };
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/IChkVisibleItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using ContextMenuManager.Methods;
3 |
4 | namespace ContextMenuManager.Controls.Interfaces
5 | {
6 | interface IChkVisibleItem
7 | {
8 | bool ItemVisible { get; set; }
9 | VisibleCheckBox ChkVisible { get; set; }
10 | }
11 |
12 | sealed class VisibleCheckBox : MyCheckBox
13 | {
14 | public VisibleCheckBox(IChkVisibleItem item)
15 | {
16 | MyListItem listItem = (MyListItem)item;
17 | listItem.AddCtr(this);
18 | CheckChanged += () => item.ItemVisible = Checked;
19 | listItem.ParentChanged += (sender, e) =>
20 | {
21 | if(listItem.IsDisposed) return;
22 | if(listItem.Parent == null) return;
23 | Checked = item.ItemVisible;
24 | if(listItem is FoldSubItem subItem && subItem.FoldGroupItem != null) return;
25 | if(listItem.FindForm() is ShellStoreDialog.ShellStoreForm) return;
26 | if(AppConfig.HideDisabledItems) listItem.Visible = Checked;
27 | };
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/IProtectOpenItem.cs:
--------------------------------------------------------------------------------
1 | namespace ContextMenuManager.Controls.Interfaces
2 | {
3 | interface IProtectOpenItem
4 | {
5 | bool ItemVisible { get; set; }
6 | bool TryProtectOpenItem();
7 | }
8 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiAdministratorItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System.IO;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls.Interfaces
7 | {
8 | interface ITsiAdministratorItem
9 | {
10 | ContextMenuStrip ContextMenuStrip { get; set; }
11 | RunAsAdministratorItem TsiAdministrator { get; set; }
12 | ShellLink ShellLink { get; }
13 | }
14 |
15 | sealed class RunAsAdministratorItem : RToolStripMenuItem
16 | {
17 | public RunAsAdministratorItem(ITsiAdministratorItem item) : base(AppString.Menu.RunAsAdministrator)
18 | {
19 | item.ContextMenuStrip.Opening += (sender, e) =>
20 | {
21 | if(item.ShellLink == null)
22 | {
23 | Enabled = false;
24 | return;
25 | }
26 | string filePath = item.ShellLink.TargetPath;
27 | string extension = Path.GetExtension(filePath)?.ToLower();
28 | switch(extension)
29 | {
30 | case ".exe":
31 | case ".bat":
32 | case ".cmd":
33 | Enabled = true;
34 | break;
35 | default:
36 | Enabled = false;
37 | break;
38 | }
39 | Checked = item.ShellLink.RunAsAdministrator;
40 | };
41 | Click += (sender, e) =>
42 | {
43 | item.ShellLink.RunAsAdministrator = !Checked;
44 | item.ShellLink.Save();
45 | if(item is WinXItem) ExplorerRestarter.Show();
46 | };
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls.Interfaces
8 | {
9 | interface ITsiCommandItem
10 | {
11 | string ItemCommand { get; set; }
12 | ChangeCommandMenuItem TsiChangeCommand { get; set; }
13 | }
14 |
15 | sealed class ChangeCommandMenuItem : RToolStripMenuItem
16 | {
17 | public bool CommandCanBeEmpty { get; set; }
18 |
19 | public ChangeCommandMenuItem(ITsiCommandItem item) : base(AppString.Menu.ChangeCommand)
20 | {
21 | Click += (sender, e) =>
22 | {
23 | string command = ChangeCommand(item.ItemCommand);
24 | if(command != null) item.ItemCommand = command;
25 | };
26 | }
27 |
28 | private string ChangeCommand(string command)
29 | {
30 | using(InputDialog dlg = new InputDialog())
31 | {
32 | dlg.Text = command;
33 | dlg.Title = AppString.Menu.ChangeCommand;
34 | dlg.Size = new Size(530, 260).DpiZoom();
35 | if(dlg.ShowDialog() != DialogResult.OK) return null;
36 | if(!CommandCanBeEmpty && string.IsNullOrEmpty(dlg.Text))
37 | {
38 | AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);
39 | return ChangeCommand(command);
40 | }
41 | else return dlg.Text;
42 | }
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.IO;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls.Interfaces
9 | {
10 | interface ITsiDeleteItem
11 | {
12 | DeleteMeMenuItem TsiDeleteMe { get; set; }
13 | void DeleteMe();
14 | }
15 |
16 | interface ITsiRegDeleteItem : ITsiDeleteItem
17 | {
18 | string Text { get; }
19 | string RegPath { get; }
20 | }
21 |
22 | sealed class DeleteMeMenuItem : RToolStripMenuItem
23 | {
24 | public DeleteMeMenuItem(ITsiDeleteItem item) : base(item is RestoreItem ? AppString.Menu.DeleteBackup : AppString.Menu.Delete)
25 | {
26 | Click += (sender, e) =>
27 | {
28 | if (item is ITsiRegDeleteItem regItem && AppConfig.AutoBackup)
29 | {
30 | if (AppMessageBox.Show(AppString.Message.DeleteButCanRestore, MessageBoxButtons.YesNo) != DialogResult.Yes)
31 | {
32 | return;
33 | }
34 | string date = DateTime.Today.ToString("yyyy-MM-dd");
35 | string time = DateTime.Now.ToString("HH-mm-ss");
36 | string filePath = $@"{AppConfig.RegBackupDir}\{date}\{regItem.Text} - {time}.reg";
37 | Directory.CreateDirectory(Path.GetDirectoryName(filePath));
38 | ExternalProgram.ExportRegistry(regItem.RegPath, filePath);
39 | }
40 | else if (AppMessageBox.Show(item is RestoreItem ? AppString.Message.ConfirmDeleteBackupPermanently : AppString.Message.ConfirmDeletePermanently,
41 | MessageBoxButtons.YesNo) != DialogResult.Yes)
42 | {
43 | return;
44 | }
45 | MyListItem listItem = (MyListItem)item;
46 | MyList list = (MyList)listItem.Parent;
47 | int index = list.GetItemIndex(listItem);
48 | try
49 | {
50 | item.DeleteMe();
51 | }
52 | catch
53 | {
54 | AppMessageBox.Show(AppString.Message.AuthorityProtection);
55 | return;
56 | }
57 | list.Controls.Remove(listItem);
58 | list.Controls[index < list.Controls.Count ? index : (list.Controls.Count - 1)].Focus();
59 | listItem.Dispose();
60 | };
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiFilePathItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System.IO;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls.Interfaces
7 | {
8 | interface ITsiFilePathItem
9 | {
10 | string ItemFilePath { get; }
11 | ContextMenuStrip ContextMenuStrip { get; set; }
12 | FileLocationMenuItem TsiFileLocation { get; set; }
13 | FilePropertiesMenuItem TsiFileProperties { get; set; }
14 | }
15 |
16 | sealed class FileLocationMenuItem : RToolStripMenuItem
17 | {
18 | public FileLocationMenuItem(ITsiFilePathItem item) : base(AppString.Menu.FileLocation)
19 | {
20 | item.ContextMenuStrip.Opening += (sender, e) =>
21 | {
22 | Visible = item.ItemFilePath != null;
23 | };
24 | Click += (sender, e) => ExternalProgram.JumpExplorer(item.ItemFilePath, AppConfig.OpenMoreExplorer);
25 | }
26 | }
27 |
28 | sealed class FilePropertiesMenuItem : RToolStripMenuItem
29 | {
30 | public FilePropertiesMenuItem(ITsiFilePathItem item) : base(AppString.Menu.FileProperties)
31 | {
32 | item.ContextMenuStrip.Opening += (sender, e) =>
33 | {
34 | string path = item.ItemFilePath;
35 | Visible = Directory.Exists(path) || File.Exists(path);
36 | };
37 | Click += (sender, e) => ExternalProgram.ShowPropertiesDialog(item.ItemFilePath);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls.Interfaces
8 | {
9 | interface ITsiIconItem
10 | {
11 | ChangeIconMenuItem TsiChangeIcon { get; set; }
12 | string IconLocation { get; set; }
13 | string IconPath { get; set; }
14 | int IconIndex { get; set; }
15 | Image Image { get; set; }
16 | Icon ItemIcon { get; }
17 | }
18 |
19 | sealed class ChangeIconMenuItem : RToolStripMenuItem
20 | {
21 | public ChangeIconMenuItem(ITsiIconItem item) : base(AppString.Menu.ChangeIcon)
22 | {
23 | Click += (sender, e) =>
24 | {
25 | using(IconDialog dlg = new IconDialog())
26 | {
27 | dlg.IconPath = item.IconPath;
28 | dlg.IconIndex = item.IconIndex;
29 | if(dlg.ShowDialog() != DialogResult.OK) return;
30 | using(Icon icon = ResourceIcon.GetIcon(dlg.IconPath, dlg.IconIndex))
31 | {
32 | Image image = icon?.ToBitmap();
33 | if(image == null) return;
34 | item.Image = image;
35 | item.IconPath = dlg.IconPath;
36 | item.IconIndex = dlg.IconIndex;
37 | item.IconLocation = $"{dlg.IconPath},{dlg.IconIndex}";
38 | }
39 | }
40 | };
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System;
4 | using System.IO;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls.Interfaces
8 | {
9 | interface ITsiRegExportItem
10 | {
11 | string Text { get; set; }
12 | string RegPath { get; }
13 | ContextMenuStrip ContextMenuStrip { get; set; }
14 | RegExportMenuItem TsiRegExport { get; set; }
15 | }
16 |
17 | sealed class RegExportMenuItem : RToolStripMenuItem
18 | {
19 | public RegExportMenuItem(ITsiRegExportItem item) : base(AppString.Menu.ExportRegistry)
20 | {
21 | item.ContextMenuStrip.Opening += (sender, e) =>
22 | {
23 | using(var key = RegistryEx.GetRegistryKey(item.RegPath))
24 | Visible = key != null;
25 | };
26 | Click += (sender, e) =>
27 | {
28 | using(SaveFileDialog dlg = new SaveFileDialog())
29 | {
30 | string date = DateTime.Today.ToString("yyyy-MM-dd");
31 | string time = DateTime.Now.ToString("HH-mm-ss");
32 | string filePath = $@"{AppConfig.RegBackupDir}\{date}\{item.Text} - {time}.reg";
33 | string dirPath = Path.GetDirectoryName(filePath);
34 | string fileName = Path.GetFileName(filePath);
35 | Directory.CreateDirectory(dirPath);
36 | dlg.FileName = fileName;
37 | dlg.InitialDirectory = dirPath;
38 | dlg.Filter = $"{AppString.Dialog.RegistryFile}|*.reg";
39 | if(dlg.ShowDialog() == DialogResult.OK)
40 | {
41 | ExternalProgram.ExportRegistry(item.RegPath, dlg.FileName);
42 | }
43 | if(Directory.GetFileSystemEntries(dirPath).Length == 0)
44 | {
45 | Directory.Delete(dirPath);
46 | }
47 | }
48 | };
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiRegPathItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System.Windows.Forms;
4 |
5 | namespace ContextMenuManager.Controls.Interfaces
6 | {
7 | interface ITsiRegPathItem
8 | {
9 | string RegPath { get; }
10 | string ValueName { get; }
11 | ContextMenuStrip ContextMenuStrip { get; set; }
12 | RegLocationMenuItem TsiRegLocation { get; set; }
13 | }
14 |
15 | sealed class RegLocationMenuItem : RToolStripMenuItem
16 | {
17 | public RegLocationMenuItem(ITsiRegPathItem item) : base(AppString.Menu.RegistryLocation)
18 | {
19 | Click += (sender, e) => ExternalProgram.JumpRegEdit(item.RegPath, item.ValueName, AppConfig.OpenMoreRegedit);
20 | item.ContextMenuStrip.Opening += (sender, e) =>
21 | {
22 | using(var key = RegistryEx.GetRegistryKey(item.RegPath))
23 | Visible = key != null;
24 | };
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiRestoreItem.cs:
--------------------------------------------------------------------------------
1 | using ContextMenuManager.Methods;
2 | using System.Windows.Forms;
3 |
4 | namespace ContextMenuManager.Controls.Interfaces
5 | {
6 | interface ITsiRestoreItem
7 | {
8 | DeleteMeMenuItem TsiDeleteMe { get; set; }
9 | void RestoreMe();
10 | }
11 |
12 | sealed class RestoreMeMenuItem : RToolStripMenuItem
13 | {
14 | public RestoreMeMenuItem(ITsiRestoreItem item) : base(AppString.Menu.RestoreBackup)
15 | {
16 | Click += (sender, e) =>
17 | {
18 | item.RestoreMe();
19 | };
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Drawing;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls.Interfaces
9 | {
10 | interface ITsiShortcutCommandItem
11 | {
12 | ShellLink ShellLink { get; }
13 | ShortcutCommandMenuItem TsiChangeCommand { get; set; }
14 | ContextMenuStrip ContextMenuStrip { get; set; }
15 | }
16 |
17 | sealed class ShortcutCommandMenuItem : RToolStripMenuItem
18 | {
19 | public ShortcutCommandMenuItem(ITsiShortcutCommandItem item) : base(AppString.Menu.ChangeCommand)
20 | {
21 | item.ContextMenuStrip.Opening += (sender, e) =>
22 | {
23 | Visible = !string.IsNullOrEmpty(item.ShellLink?.TargetPath);
24 | };
25 | }
26 |
27 | public bool ChangeCommand(ShellLink shellLink)
28 | {
29 | using(CommandDialog dlg = new CommandDialog())
30 | {
31 | dlg.Command = shellLink.TargetPath;
32 | dlg.Arguments = shellLink.Arguments;
33 | if(dlg.ShowDialog() != DialogResult.OK) return false;
34 | shellLink.TargetPath = dlg.Command;
35 | shellLink.Arguments = dlg.Arguments;
36 | shellLink.Save();
37 | return true;
38 | }
39 | }
40 |
41 | sealed class CommandDialog : CommonDialog
42 | {
43 | public string Command { get; set; }
44 | public string Arguments { get; set; }
45 |
46 | public override void Reset() { }
47 |
48 | protected override bool RunDialog(IntPtr hwndOwner)
49 | {
50 | using(CommandForm frm = new CommandForm())
51 | {
52 | frm.Command = Command;
53 | frm.Arguments = Arguments;
54 | frm.TopMost = AppConfig.TopMost;
55 | bool flag = frm.ShowDialog() == DialogResult.OK;
56 | if(flag)
57 | {
58 | Command = frm.Command;
59 | Arguments = frm.Arguments;
60 | }
61 | return flag;
62 | }
63 | }
64 |
65 | sealed class CommandForm : ResizeLimitedForm
66 | {
67 | public CommandForm()
68 | {
69 | AcceptButton = btnOK;
70 | CancelButton = btnCancel;
71 | VerticalResizable = false;
72 | Font = SystemFonts.MessageBoxFont;
73 | Text = AppString.Menu.ChangeCommand;
74 | SizeGripStyle = SizeGripStyle.Hide;
75 | StartPosition = FormStartPosition.CenterParent;
76 | MaximizeBox = MinimizeBox = ShowIcon = ShowInTaskbar = false;
77 | InitializeComponents();
78 | }
79 |
80 | public string Command
81 | {
82 | get => txtCommand.Text;
83 | set => txtCommand.Text = value;
84 | }
85 |
86 | public string Arguments
87 | {
88 | get => txtArguments.Text;
89 | set => txtArguments.Text = value;
90 | }
91 |
92 | readonly Label lblCommand = new Label
93 | {
94 | Text = AppString.Dialog.ItemCommand,
95 | AutoSize = true
96 | };
97 | readonly Label lblArguments = new Label
98 | {
99 | Text = AppString.Dialog.CommandArguments,
100 | AutoSize = true
101 | };
102 | readonly TextBox txtCommand = new TextBox();
103 | readonly TextBox txtArguments = new TextBox();
104 | readonly Button btnOK = new Button
105 | {
106 | DialogResult = DialogResult.OK,
107 | Text = ResourceString.OK,
108 | AutoSize = true
109 | };
110 | readonly Button btnCancel = new Button
111 | {
112 | DialogResult = DialogResult.Cancel,
113 | Text = ResourceString.Cancel,
114 | AutoSize = true
115 | };
116 |
117 | private void InitializeComponents()
118 | {
119 | Controls.AddRange(new Control[] { lblCommand, lblArguments, txtCommand, txtArguments, btnOK, btnCancel });
120 | int a = 20.DpiZoom();
121 | lblArguments.Left = lblCommand.Left = lblCommand.Top = txtCommand.Top = a;
122 | lblArguments.Top = txtArguments.Top = txtCommand.Bottom + a;
123 | btnOK.Top = btnCancel.Top = txtArguments.Bottom + a;
124 | int b = Math.Max(lblCommand.Width, lblArguments.Width) + 3 * a;
125 | ClientSize = new Size(250.DpiZoom() + b, btnOK.Bottom + a);
126 | btnOK.Anchor = btnCancel.Anchor = AnchorStyles.Right | AnchorStyles.Top;
127 | btnCancel.Left = ClientSize.Width - btnCancel.Width - a;
128 | btnOK.Left = btnCancel.Left - btnOK.Width - a;
129 | Resize += (sender, e) =>
130 | {
131 | txtArguments.Width = txtCommand.Width = ClientSize.Width - b;
132 | txtArguments.Left = txtCommand.Left = btnCancel.Right - txtCommand.Width;
133 | };
134 | OnResize(null);
135 | MinimumSize = Size;
136 | }
137 | }
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls.Interfaces
7 | {
8 | interface ITsiTextItem
9 | {
10 | string Text { get; set; }
11 | string ItemText { get; set; }
12 | ChangeTextMenuItem TsiChangeText { get; set; }
13 | }
14 |
15 | sealed class ChangeTextMenuItem : RToolStripMenuItem
16 | {
17 | public ChangeTextMenuItem(ITsiTextItem item) : base(AppString.Menu.ChangeText)
18 | {
19 | Click += (sender, e) =>
20 | {
21 | string name = ChangeText(item.Text);
22 | if(name != null) item.ItemText = name;
23 | };
24 | }
25 |
26 | private string ChangeText(string text)
27 | {
28 | using(InputDialog dlg = new InputDialog { Text = text, Title = AppString.Menu.ChangeText })
29 | {
30 | if(dlg.ShowDialog() != DialogResult.OK) return null;
31 | if(dlg.Text.Length == 0)
32 | {
33 | AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);
34 | return ChangeText(text);
35 | }
36 | else if(ResourceString.GetDirectString(dlg.Text).Length == 0)
37 | {
38 | AppMessageBox.Show(AppString.Message.StringParsingFailed);
39 | return ChangeText(text);
40 | }
41 | else return dlg.Text;
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/Interfaces/ITsiWebSearchItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System.Windows.Forms;
4 |
5 | namespace ContextMenuManager.Controls.Interfaces
6 | {
7 | interface ITsiWebSearchItem
8 | {
9 | string SearchText { get; }
10 | WebSearchMenuItem TsiSearch { get; set; }
11 | }
12 |
13 | sealed class WebSearchMenuItem : RToolStripMenuItem
14 | {
15 | public WebSearchMenuItem(ITsiWebSearchItem item) : base(AppString.Menu.WebSearch)
16 | {
17 | Click += (sender, e) =>
18 | {
19 | string url = AppConfig.EngineUrl.Replace("%s", item.SearchText);
20 | ExternalProgram.OpenWebUrl(url);
21 | };
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/NewIEDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System;
4 | using System.IO;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | sealed class NewIEDialog : CommonDialog
10 | {
11 | public string RegPath { get; private set; }
12 | public override void Reset() { }
13 |
14 | protected override bool RunDialog(IntPtr hwndOwner)
15 | {
16 | using(NewIEForm frm = new NewIEForm())
17 | {
18 | frm.TopMost = AppConfig.TopMost;
19 | bool flag = frm.ShowDialog() == DialogResult.OK;
20 | if(flag) RegPath = frm.RegPath;
21 | return flag;
22 | }
23 | }
24 |
25 | sealed class NewIEForm : NewItemForm
26 | {
27 | public string RegPath { get; set; }
28 |
29 | protected override void InitializeComponents()
30 | {
31 | base.InitializeComponents();
32 | btnOK.Click += (sender, e) =>
33 | {
34 | if(ItemText.IsNullOrWhiteSpace())
35 | {
36 | AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);
37 | return;
38 | }
39 | if(ItemCommand.IsNullOrWhiteSpace())
40 | {
41 | AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);
42 | return;
43 | }
44 | AddNewItem();
45 | DialogResult = DialogResult.OK;
46 | };
47 |
48 | btnBrowse.Click += (sender, e) =>
49 | {
50 | using(OpenFileDialog dlg = new OpenFileDialog())
51 | {
52 | if(dlg.ShowDialog() != DialogResult.OK) return;
53 | ItemFilePath = dlg.FileName;
54 | ItemText = Path.GetFileNameWithoutExtension(dlg.FileName);
55 | }
56 | };
57 | }
58 |
59 | private void AddNewItem()
60 | {
61 | RegPath = $@"{IEList.IEPath}\{IEItem.MeParts[0]}\{ItemText.Replace("\\", "")}";
62 | Microsoft.Win32.Registry.SetValue(RegPath, "", ItemCommand);
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/NewItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 |
6 | namespace ContextMenuManager.Controls
7 | {
8 | class NewItem : MyListItem
9 | {
10 | public NewItem() : this(AppString.Other.NewItem) { }
11 |
12 | public NewItem(string text)
13 | {
14 | Text = text;
15 | Image = AppImage.NewItem;
16 | AddCtr(BtnAddNewItem);
17 | ToolTipBox.SetToolTip(BtnAddNewItem, text);
18 | BtnAddNewItem.MouseDown += (sender, e) => AddNewItem?.Invoke();
19 | MouseDoubleClick += (sender, e) => AddNewItem?.Invoke();
20 |
21 | }
22 | public Action AddNewItem;
23 | readonly PictureButton BtnAddNewItem = new PictureButton(AppImage.AddNewItem);
24 | }
25 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/NewItemForm.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Drawing;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls
9 | {
10 | class NewItemForm : ResizeLimitedForm
11 | {
12 | public NewItemForm()
13 | {
14 | AcceptButton = btnOK;
15 | CancelButton = btnCancel;
16 | Text = AppString.Other.NewItem;
17 | Font = SystemFonts.MenuFont;
18 | MaximizeBox = MinimizeBox = false;
19 | ShowIcon = ShowInTaskbar = false;
20 | StartPosition = FormStartPosition.CenterParent;
21 | SizeGripStyle = SizeGripStyle.Hide;
22 | VerticalResizable = false;
23 | InitializeComponents();
24 | }
25 |
26 | public string ItemText { get => txtText.Text; set => txtText.Text = value; }
27 | public string ItemFilePath { get => txtFilePath.Text; set => txtFilePath.Text = value; }
28 | public string Arguments { get => txtArguments.Text; set => txtArguments.Text = value; }
29 | public string ItemCommand
30 | {
31 | get
32 | {
33 | string filePath = ItemFilePath;
34 | string arguments = Arguments;
35 | if(arguments.IsNullOrWhiteSpace()) return filePath;
36 | if(filePath.IsNullOrWhiteSpace()) return arguments;
37 | if(filePath.Contains(" ")) filePath = $"\"{filePath}\"";
38 | if(!arguments.Contains("\"")) arguments = $"\"{arguments}\"";
39 | return $"{filePath} {arguments}";
40 | }
41 | }
42 |
43 | protected readonly Label lblText = new Label
44 | {
45 | Text = AppString.Dialog.ItemText,
46 | AutoSize = true
47 | };
48 | protected readonly Label lblCommand = new Label
49 | {
50 | Text = AppString.Dialog.ItemCommand,
51 | AutoSize = true
52 | };
53 | protected readonly Label lblArguments = new Label
54 | {
55 | Text = AppString.Dialog.CommandArguments,
56 | AutoSize = true
57 | };
58 | protected readonly TextBox txtText = new TextBox();
59 | protected readonly TextBox txtFilePath = new TextBox();
60 | protected readonly TextBox txtArguments = new TextBox();
61 | protected readonly Button btnBrowse = new Button
62 | {
63 | Text = AppString.Dialog.Browse,
64 | AutoSize = true
65 | };
66 | protected readonly Button btnOK = new Button
67 | {
68 | Text = ResourceString.OK,
69 | AutoSize = true
70 | };
71 | protected readonly Button btnCancel = new Button
72 | {
73 | DialogResult = DialogResult.Cancel,
74 | Text = ResourceString.Cancel,
75 | AutoSize = true
76 | };
77 |
78 | protected virtual void InitializeComponents()
79 | {
80 | Controls.AddRange(new Control[] { lblText, lblCommand, lblArguments,
81 | txtText, txtFilePath, txtArguments, btnBrowse, btnOK, btnCancel });
82 | int a = 20.DpiZoom();
83 | btnBrowse.Anchor = btnOK.Anchor = btnCancel.Anchor = AnchorStyles.Right | AnchorStyles.Top;
84 | txtText.Top = lblText.Top = lblText.Left = lblCommand.Left = lblArguments.Left = a;
85 | btnBrowse.Top = txtFilePath.Top = lblCommand.Top = txtText.Bottom + a;
86 | lblArguments.Top = txtArguments.Top = txtFilePath.Bottom + a;
87 | btnOK.Top = btnCancel.Top = txtArguments.Bottom + a;
88 | btnCancel.Left = btnBrowse.Left = ClientSize.Width - btnCancel.Width - a;
89 | btnOK.Left = btnCancel.Left - btnOK.Width - a;
90 | int b = Math.Max(Math.Max(lblText.Width, lblCommand.Width), lblArguments.Width) + btnBrowse.Width + 4 * a;
91 | ClientSize = new Size(320.DpiZoom() + b, btnOK.Bottom + a);
92 | MinimumSize = Size;
93 | Resize += (sender, e) =>
94 | {
95 | txtText.Width = txtFilePath.Width = txtArguments.Width = ClientSize.Width - b;
96 | txtText.Left = txtFilePath.Left = txtArguments.Left = btnBrowse.Left - txtFilePath.Width - a;
97 | };
98 | OnResize(null);
99 | }
100 | }
101 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/NewLnkFileDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System;
4 | using System.IO;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | sealed class NewLnkFileDialog : CommonDialog
10 | {
11 | public string ItemText { get; set; }
12 | public string ItemFilePath { get; set; }
13 | public string Arguments { get; set; }
14 | public string FileFilter { get; set; }
15 | public override void Reset() { }
16 |
17 | protected override bool RunDialog(IntPtr hwndOwner)
18 | {
19 | using(NewLnkForm frm = new NewLnkForm())
20 | {
21 | frm.FileFilter = FileFilter;
22 | frm.TopMost = AppConfig.TopMost;
23 | bool flag = frm.ShowDialog() == DialogResult.OK;
24 | if(flag)
25 | {
26 | ItemText = frm.ItemText;
27 | ItemFilePath = frm.ItemFilePath;
28 | Arguments = frm.Arguments;
29 | }
30 | return flag;
31 | }
32 | }
33 |
34 | sealed class NewLnkForm : NewItemForm
35 | {
36 | public string FileFilter { get; set; }
37 |
38 | readonly RadioButton rdoFile = new RadioButton
39 | {
40 | Text = AppString.SideBar.File,
41 | AutoSize = true,
42 | Checked = true
43 | };
44 | readonly RadioButton rdoFolder = new RadioButton
45 | {
46 | Text = AppString.SideBar.Folder,
47 | AutoSize = true
48 | };
49 |
50 | protected override void InitializeComponents()
51 | {
52 | base.InitializeComponents();
53 | Controls.AddRange(new Control[] { rdoFile, rdoFolder });
54 | rdoFile.Top = rdoFolder.Top = btnOK.Top + (btnOK.Height - rdoFile.Height) / 2;
55 | rdoFile.Left = lblCommand.Left;
56 | rdoFolder.Left = rdoFile.Right + 20.DpiZoom();
57 |
58 | btnBrowse.Click += (sender, e) =>
59 | {
60 | if(rdoFile.Checked) BrowseFile();
61 | else BrowseFolder();
62 | };
63 |
64 | btnOK.Click += (sender, e) =>
65 | {
66 | if(ItemText.IsNullOrWhiteSpace())
67 | {
68 | AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);
69 | }
70 | else if(ItemFilePath.IsNullOrWhiteSpace())
71 | {
72 | AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);
73 | }
74 | else if(rdoFile.Checked && !ObjectPath.GetFullFilePath(ItemFilePath, out _))
75 | {
76 | AppMessageBox.Show(AppString.Message.FileNotExists);
77 | }
78 | else if(rdoFolder.Checked && !Directory.Exists(ItemFilePath))
79 | {
80 | AppMessageBox.Show(AppString.Message.FolderNotExists);
81 | }
82 | else DialogResult = DialogResult.OK;
83 | };
84 |
85 | txtFilePath.TextChanged += (sender, e) =>
86 | {
87 | if(Path.GetExtension(ItemFilePath).ToLower() == ".lnk")
88 | {
89 | using(ShellLink shortcut = new ShellLink(ItemFilePath))
90 | {
91 | if(File.Exists(shortcut.TargetPath))
92 | {
93 | ItemFilePath = shortcut.TargetPath;
94 | }
95 | }
96 | }
97 | };
98 | }
99 |
100 | private void BrowseFile()
101 | {
102 | using(OpenFileDialog dlg = new OpenFileDialog())
103 | {
104 | dlg.Filter = FileFilter;
105 | //取消获取lnk目标路径,可选中UWP快捷方式
106 | dlg.DereferenceLinks = false;
107 | if(dlg.ShowDialog() == DialogResult.OK)
108 | {
109 | ItemFilePath = dlg.FileName;
110 | string extension = Path.GetExtension(dlg.FileName).ToLower();
111 | if(extension == ".lnk")
112 | {
113 | using(ShellLink shortcut = new ShellLink(dlg.FileName))
114 | {
115 | if(File.Exists(shortcut.TargetPath))
116 | {
117 | ItemFilePath = shortcut.TargetPath;
118 | Arguments = shortcut.Arguments;
119 | }
120 | }
121 | }
122 | ItemText = Path.GetFileNameWithoutExtension(dlg.FileName);
123 | }
124 | }
125 | }
126 |
127 | private void BrowseFolder()
128 | {
129 | using(FolderBrowserDialog dlg = new FolderBrowserDialog())
130 | {
131 | if(Directory.Exists(ItemFilePath)) dlg.SelectedPath = ItemFilePath;
132 | else dlg.SelectedPath = Application.StartupPath;
133 | if(dlg.ShowDialog() == DialogResult.OK)
134 | {
135 | ItemFilePath = dlg.SelectedPath;
136 | ItemText = Path.GetFileNameWithoutExtension(dlg.SelectedPath);
137 | }
138 | }
139 | }
140 | }
141 | }
142 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/NewOpenWithDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using ContextMenuManager.Methods;
3 | using System;
4 | using System.Diagnostics;
5 | using System.IO;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls
9 | {
10 | sealed class NewOpenWithDialog : CommonDialog
11 | {
12 | public string RegPath { get; private set; }
13 | public override void Reset() { }
14 |
15 | protected override bool RunDialog(IntPtr hwndOwner)
16 | {
17 | using(NewOpenWithForm frm = new NewOpenWithForm())
18 | {
19 | frm.TopMost = AppConfig.TopMost;
20 | bool flag = frm.ShowDialog() == DialogResult.OK;
21 | if(flag) RegPath = frm.RegPath;
22 | return flag;
23 | }
24 | }
25 |
26 | sealed class NewOpenWithForm : NewItemForm
27 | {
28 | public string RegPath { get; private set; }
29 |
30 | private string FilePath;
31 | private string FileName => Path.GetFileName(FilePath);
32 | private string AppRegPath => $@"{RegistryEx.CLASSES_ROOT}\Applications\{FileName}";
33 | private string CommandPath => $@"{AppRegPath}\shell\open\command";
34 |
35 | protected override void InitializeComponents()
36 | {
37 | base.InitializeComponents();
38 | btnBrowse.Click += (sender, e) => BrowseFile();
39 | btnOK.Click += (sender, e) =>
40 | {
41 | if(string.IsNullOrEmpty(ItemText))
42 | {
43 | AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);
44 | return;
45 | }
46 | if(ItemCommand.IsNullOrWhiteSpace())
47 | {
48 | AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);
49 | return;
50 | }
51 | FilePath = ObjectPath.ExtractFilePath(base.ItemFilePath);
52 | using(var key = RegistryEx.GetRegistryKey(CommandPath))
53 | {
54 | string path = ObjectPath.ExtractFilePath(key?.GetValue("")?.ToString());
55 | string name = Path.GetFileName(path);
56 | if(FilePath != null && FilePath.Equals(path, StringComparison.OrdinalIgnoreCase))
57 | {
58 | AppMessageBox.Show(AppString.Message.HasBeenAdded);
59 | return;
60 | }
61 | if(FileName == null || FileName.Equals(name, StringComparison.OrdinalIgnoreCase))
62 | {
63 | AppMessageBox.Show(AppString.Message.UnsupportedFilename);
64 | return;
65 | }
66 | }
67 | AddNewItem();
68 | DialogResult = DialogResult.OK;
69 | };
70 | }
71 |
72 | private void BrowseFile()
73 | {
74 | using(OpenFileDialog dlg = new OpenFileDialog())
75 | {
76 | dlg.Filter = $"{AppString.Dialog.Program}|*.exe";
77 | if(dlg.ShowDialog() == DialogResult.OK)
78 | {
79 | base.ItemFilePath = dlg.FileName;
80 | Arguments = "\"%1\"";
81 | ItemText = FileVersionInfo.GetVersionInfo(dlg.FileName).FileDescription;
82 | }
83 | }
84 | }
85 |
86 | private void AddNewItem()
87 | {
88 | using(var key = RegistryEx.GetRegistryKey(AppRegPath, true, true))
89 | {
90 | key.SetValue("FriendlyAppName", ItemText);
91 | }
92 | using(var cmdKey = RegistryEx.GetRegistryKey(CommandPath, true, true))
93 | {
94 | cmdKey.SetValue("", ItemCommand);
95 | RegPath = cmdKey.Name;
96 | }
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/OpenWithItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Controls.Interfaces;
4 | using ContextMenuManager.Methods;
5 | using Microsoft.Win32;
6 | using System;
7 | using System.Diagnostics;
8 | using System.Drawing;
9 | using System.IO;
10 | using System.Windows.Forms;
11 |
12 | namespace ContextMenuManager.Controls
13 | {
14 | sealed class OpenWithItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiTextItem,
15 | ITsiCommandItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiRegDeleteItem, ITsiRegExportItem
16 | {
17 |
18 | public OpenWithItem(string regPath)
19 | {
20 | InitializeComponents();
21 | RegPath = regPath;
22 | }
23 |
24 | private string regPath;
25 | public string RegPath
26 | {
27 | get => regPath;
28 | set
29 | {
30 | regPath = value;
31 | ItemFilePath = ObjectPath.ExtractFilePath(ItemCommand);
32 | Text = ItemText;
33 | Image = ItemIcon.ToBitmap();
34 | }
35 | }
36 | public string ValueName => null;
37 | private string ShellPath => RegistryEx.GetParentPath(RegPath);
38 | private string AppPath => RegistryEx.GetParentPath(RegistryEx.GetParentPath(ShellPath));
39 | private bool NameEquals => RegistryEx.GetKeyName(AppPath).Equals(Path.GetFileName(ItemFilePath), StringComparison.OrdinalIgnoreCase);
40 | private Icon ItemIcon => Icon.ExtractAssociatedIcon(ItemFilePath);
41 |
42 | public string ItemText
43 | {
44 | get
45 | {
46 | string name = null;
47 | if(NameEquals)
48 | {
49 | name = Registry.GetValue(AppPath, "FriendlyAppName", null)?.ToString();
50 | name = ResourceString.GetDirectString(name);
51 | }
52 | if(string.IsNullOrEmpty(name)) name = FileVersionInfo.GetVersionInfo(ItemFilePath).FileDescription;
53 | if(string.IsNullOrEmpty(name)) name = Path.GetFileName(ItemFilePath);
54 | return name;
55 | }
56 | set
57 | {
58 | Registry.SetValue(AppPath, "FriendlyAppName", value);
59 | Text = ResourceString.GetDirectString(value);
60 | }
61 | }
62 |
63 | public string ItemCommand
64 | {
65 | get => Registry.GetValue(RegPath, "", null)?.ToString();
66 | set
67 | {
68 | if(ObjectPath.ExtractFilePath(value) != ItemFilePath)
69 | {
70 | AppMessageBox.Show(AppString.Message.CannotChangePath);
71 | }
72 | else Registry.SetValue(RegPath, "", value);
73 | }
74 | }
75 |
76 | public bool ItemVisible
77 | {
78 | get => Registry.GetValue(AppPath, "NoOpenWith", null) == null;
79 | set
80 | {
81 | if(value) RegistryEx.DeleteValue(AppPath, "NoOpenWith");
82 | else Registry.SetValue(AppPath, "NoOpenWith", "");
83 | }
84 | }
85 |
86 | public string SearchText => $"{AppString.SideBar.OpenWith} {Text}";
87 | public string ItemFilePath { get; private set; }
88 | public string ItemFileName => Path.GetFileName(ItemFilePath);
89 |
90 | public VisibleCheckBox ChkVisible { get; set; }
91 | public MenuButton BtnShowMenu { get; set; }
92 | public ChangeTextMenuItem TsiChangeText { get; set; }
93 | public ChangeCommandMenuItem TsiChangeCommand { get; set; }
94 | public WebSearchMenuItem TsiSearch { get; set; }
95 | public FilePropertiesMenuItem TsiFileProperties { get; set; }
96 | public FileLocationMenuItem TsiFileLocation { get; set; }
97 | public RegLocationMenuItem TsiRegLocation { get; set; }
98 | public DeleteMeMenuItem TsiDeleteMe { get; set; }
99 | public RegExportMenuItem TsiRegExport { get; set; }
100 |
101 | readonly RToolStripMenuItem TsiDetails = new RToolStripMenuItem(AppString.Menu.Details);
102 |
103 | private void InitializeComponents()
104 | {
105 | BtnShowMenu = new MenuButton(this);
106 | ChkVisible = new VisibleCheckBox(this);
107 | TsiChangeText = new ChangeTextMenuItem(this);
108 | TsiChangeCommand = new ChangeCommandMenuItem(this);
109 | TsiSearch = new WebSearchMenuItem(this);
110 | TsiFileProperties = new FilePropertiesMenuItem(this);
111 | TsiFileLocation = new FileLocationMenuItem(this);
112 | TsiRegLocation = new RegLocationMenuItem(this);
113 | TsiRegExport = new RegExportMenuItem(this);
114 | TsiDeleteMe = new DeleteMeMenuItem(this);
115 |
116 | ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText,
117 | new RToolStripSeparator(), TsiDetails, new RToolStripSeparator(), TsiDeleteMe });
118 |
119 | TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new RToolStripSeparator(),
120 | TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport });
121 |
122 | ContextMenuStrip.Opening += (sender, e) => TsiChangeText.Enabled = NameEquals;
123 | }
124 |
125 | public void DeleteMe()
126 | {
127 | RegistryEx.DeleteKeyTree(RegPath);
128 | using(RegistryKey key = RegistryEx.GetRegistryKey(ShellPath))
129 | {
130 | if(key.GetSubKeyNames().Length == 0) RegistryEx.DeleteKeyTree(AppPath);
131 | }
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/OpenWithList.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using Microsoft.Win32;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Windows.Forms;
9 |
10 | namespace ContextMenuManager.Controls
11 | {
12 | sealed class OpenWithList : MyList // 主页 打开方式
13 | {
14 | public void LoadItems()
15 | {
16 | LoadOpenWithItems();
17 | SortItemByText();
18 | AddNewItem();
19 | //Win8及以上版本系统才有在应用商店中查找应用
20 | if (WinOsVersion.Current >= WinOsVersion.Win8)
21 | {
22 | VisibleRegRuleItem storeItem = new VisibleRegRuleItem(VisibleRegRuleItem.UseStoreOpenWith);
23 | InsertItem(storeItem, 1);
24 | }
25 | }
26 |
27 | private void LoadOpenWithItems()
28 | {
29 | using(RegistryKey root = Registry.ClassesRoot)
30 | using(RegistryKey appKey = root.OpenSubKey("Applications"))
31 | {
32 | foreach(string appName in appKey.GetSubKeyNames())
33 | {
34 | if(!appName.Contains('.')) continue;//需要为有扩展名的文件名
35 | using(RegistryKey shellKey = appKey.OpenSubKey($@"{appName}\shell"))
36 | {
37 | if(shellKey == null) continue;
38 |
39 | List names = shellKey.GetSubKeyNames().ToList();
40 | if(names.Contains("open", StringComparer.OrdinalIgnoreCase)) names.Insert(0, "open");
41 |
42 | string keyName = names.Find(name =>
43 | {
44 | using(RegistryKey cmdKey = shellKey.OpenSubKey(name))
45 | return cmdKey.GetValue("NeverDefault") == null;
46 | });
47 | if(keyName == null) continue;
48 |
49 | using(RegistryKey commandKey = shellKey.OpenSubKey($@"{keyName}\command"))
50 | {
51 | string command = commandKey?.GetValue("")?.ToString();
52 | if(ObjectPath.ExtractFilePath(command) != null)
53 | {
54 | OpenWithItem item = new OpenWithItem(commandKey.Name);
55 | AddItem(item);
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
63 | private void AddNewItem()
64 | {
65 | NewItem newItem = new NewItem();
66 | InsertItem(newItem, 0);
67 | newItem.AddNewItem += () =>
68 | {
69 | using(NewOpenWithDialog dlg = new NewOpenWithDialog())
70 | {
71 | if(dlg.ShowDialog() == DialogResult.OK)
72 | InsertItem(new OpenWithItem(dlg.RegPath), 2);
73 | }
74 | };
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/RForm.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using System.Drawing;
3 | using System.Runtime.InteropServices;
4 | using System;
5 | using System.Windows.Forms;
6 |
7 | namespace BluePointLilac.Controls
8 | {
9 | ///
10 | /// Edited from: https://github.com/seerge/g-helper
11 | ///
12 | public class RForm : Form
13 | {
14 | protected override void OnLoad(EventArgs e)
15 | {
16 | StartPosition = FormStartPosition.CenterScreen;
17 | base.OnLoad(e);
18 | }
19 |
20 | public static Color ButtonMain => MyMainForm.ButtonMain;
21 | public static Color ButtonSecond => MyMainForm.ButtonSecond;
22 |
23 | public static Color FormBack => MyMainForm.FormBack;
24 | public static Color FormFore => MyMainForm.FormFore;
25 | public static Color FormBorder => MyMainForm.FormBorder;
26 |
27 | [DllImport("UXTheme.dll", SetLastError = true, EntryPoint = "#138")]
28 | public static extern bool CheckSystemDarkModeStatus();
29 |
30 | [DllImport("DwmApi")] //System.Runtime.InteropServices
31 | private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, int[] attrValue, int attrSize);
32 |
33 | public bool darkTheme = false;
34 | protected override CreateParams CreateParams
35 | {
36 | get
37 | {
38 | var parms = base.CreateParams;
39 | parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
40 | parms.ClassStyle &= ~0x00020000;
41 | return parms;
42 | }
43 | }
44 |
45 | private static bool IsDarkTheme()
46 | {
47 | using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"))
48 | {
49 | var registryValueObject = key?.GetValue("AppsUseLightTheme");
50 |
51 | if (registryValueObject == null) return false;
52 | return (int)registryValueObject <= 0;
53 | }
54 | }
55 |
56 | public bool InitTheme()
57 | {
58 | bool newDarkTheme = IsDarkTheme();
59 | bool changed = darkTheme != newDarkTheme;
60 | darkTheme = newDarkTheme;
61 |
62 | if (changed)
63 | {
64 | DwmSetWindowAttribute(Handle, 20, new[] { darkTheme ? 1 : 0 }, 4);
65 | Adjust();
66 | Invalidate();
67 | }
68 |
69 | return changed;
70 | }
71 |
72 | protected void ApplyDarkModeToDataGridView(DataGridView dgv)
73 | {
74 | // Background color
75 | dgv.BackgroundColor = MyMainForm.FormBack;
76 | dgv.DefaultCellStyle.BackColor = MyMainForm.FormBack;
77 | dgv.DefaultCellStyle.ForeColor = MyMainForm.FormFore;
78 |
79 | // Grid color
80 | dgv.GridColor = Color.DimGray;
81 |
82 | // Header style
83 | dgv.ColumnHeadersDefaultCellStyle.BackColor = MyMainForm.FormBack;
84 | dgv.ColumnHeadersDefaultCellStyle.ForeColor = MyMainForm.FormFore;
85 | dgv.ColumnHeadersDefaultCellStyle.SelectionBackColor = MyMainForm.MainColor;
86 | dgv.ColumnHeadersDefaultCellStyle.SelectionForeColor = MyMainForm.FormFore;
87 | dgv.EnableHeadersVisualStyles = false; // Ensure custom header styles apply
88 |
89 | // Row styles
90 | dgv.RowsDefaultCellStyle.BackColor = MyMainForm.FormBack;
91 | dgv.RowsDefaultCellStyle.ForeColor = MyMainForm.FormFore;
92 | dgv.AlternatingRowsDefaultCellStyle.BackColor = MyMainForm.FormBack;
93 |
94 | // Selection color
95 | dgv.DefaultCellStyle.SelectionBackColor = MyMainForm.MainColor;
96 | dgv.DefaultCellStyle.SelectionForeColor = MyMainForm.FormFore;
97 | }
98 |
99 | private void Adjust()
100 | {
101 | BackColor = FormBack;
102 | ForeColor = FormFore;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/RToolStripMenuItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using System;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace ContextMenuManager.Controls
7 | {
8 | internal class RToolStripMenuItem : ToolStripMenuItem
9 | {
10 | public RToolStripMenuItem() : base()
11 | {
12 | ForeColor = MyMainForm.FormFore;
13 | BackColor = MyMainForm.FormBack;
14 | }
15 |
16 | public RToolStripMenuItem(string text) : base(text)
17 | {
18 | ForeColor = MyMainForm.FormFore;
19 | BackColor = MyMainForm.FormBack;
20 | }
21 |
22 | public RToolStripMenuItem(string text, Image image) : base(text, image)
23 | {
24 | ForeColor = MyMainForm.FormFore;
25 | BackColor = MyMainForm.FormBack;
26 | }
27 |
28 | public RToolStripMenuItem(string text, Image image, EventHandler onClick) : base(text, image, onClick)
29 | {
30 | ForeColor = MyMainForm.FormFore;
31 | BackColor = MyMainForm.FormBack;
32 | }
33 |
34 | public RToolStripMenuItem(string text, Image image, EventHandler onClick, string name) : base(text, image, onClick, name)
35 | {
36 | ForeColor = MyMainForm.FormFore;
37 | BackColor = MyMainForm.FormBack;
38 | }
39 | }
40 |
41 | public class RToolStripSeparator : ToolStripSeparator
42 | {
43 | public RToolStripSeparator() : base()
44 | {
45 | ForeColor = MyMainForm.FormFore;
46 | BackColor = MyMainForm.FormBack;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/RestoreItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using ContextMenuManager.Controls.Interfaces;
3 | using ContextMenuManager.Methods;
4 | using System.IO;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | interface ITsiRestoreFile
10 | {
11 | void RestoreItems(string restoreFile);
12 | }
13 |
14 | sealed class RestoreItem : MyListItem, IBtnShowMenuItem, ITsiFilePathItem, ITsiDeleteItem, ITsiRestoreItem
15 | {
16 | public RestoreItem(ITsiRestoreFile item, string filePath, string deviceName, string creatTime)
17 | {
18 | InitializeComponents();
19 | restoreInterface = item;
20 | FilePath = filePath;
21 | Text = AppString.Other.RestoreItemText.Replace("%device", deviceName).Replace("%time", creatTime);
22 | Image = AppImage.BackupItem;
23 | }
24 |
25 | // 恢复函数接口对象
26 | private readonly ITsiRestoreFile restoreInterface;
27 |
28 | // 备份文件目录
29 | private string filePath;
30 | public string FilePath
31 | {
32 | get => filePath;
33 | set => filePath = value;
34 | }
35 | public string ItemFilePath { get { return filePath; } }
36 |
37 | public MenuButton BtnShowMenu { get; set; }
38 | public FilePropertiesMenuItem TsiFileProperties { get; set; }
39 | public FileLocationMenuItem TsiFileLocation { get; set; }
40 | public DeleteMeMenuItem TsiDeleteMe { get; set; }
41 | public RestoreMeMenuItem TsiRestoreMe { get; set; }
42 |
43 | readonly RToolStripMenuItem TsiDetails = new RToolStripMenuItem(AppString.Menu.Details);
44 |
45 | private void InitializeComponents()
46 | {
47 | BtnShowMenu = new MenuButton(this);
48 | TsiFileLocation = new FileLocationMenuItem(this);
49 | TsiFileProperties = new FilePropertiesMenuItem(this);
50 | TsiDeleteMe = new DeleteMeMenuItem(this);
51 | TsiRestoreMe = new RestoreMeMenuItem(this);
52 |
53 | // 设置菜单:详细信息;删除备份;恢复备份
54 | ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiDetails, new RToolStripSeparator(),
55 | TsiRestoreMe, new RToolStripSeparator(), TsiDeleteMe });
56 |
57 | // 详细信息
58 | TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiFileProperties, TsiFileLocation });
59 | }
60 |
61 | public void DeleteMe()
62 | {
63 | File.Delete(filePath);
64 | }
65 |
66 | public void RestoreMe()
67 | {
68 | restoreInterface.RestoreItems(filePath);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/RestoreListDialog.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Drawing;
7 | using System.Windows.Forms;
8 |
9 | namespace ContextMenuManager.Controls
10 | {
11 | sealed class RestoreListDialog : CommonDialog
12 | {
13 | public List RestoreData { get; set; }
14 |
15 | public override void Reset() { }
16 |
17 | protected override bool RunDialog(IntPtr hwndOwner)
18 | {
19 | MainForm mainForm = (MainForm)Control.FromHandle(hwndOwner);
20 | if (mainForm != null)
21 | {
22 | using (RestoreListForm frm = new RestoreListForm())
23 | {
24 | frm.ShowDonateList(RestoreData);
25 | frm.Left = mainForm.Left + (mainForm.Width + mainForm.SideBar.Width - frm.Width) / 2;
26 | frm.Top = mainForm.Top + 150.DpiZoom();
27 | frm.TopMost = AppConfig.TopMost;
28 | frm.ShowDialog();
29 | }
30 | }
31 | return true;
32 | }
33 |
34 | sealed class RestoreListForm : RForm
35 | {
36 | public RestoreListForm()
37 | {
38 | Font = SystemFonts.DialogFont;
39 | Text = AppString.Dialog.RestoreDetails;
40 | SizeGripStyle = SizeGripStyle.Hide;
41 | StartPosition = FormStartPosition.Manual;
42 | Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
43 | MinimizeBox = MaximizeBox = ShowInTaskbar = false;
44 | ClientSize = new Size(520, 350).DpiZoom();
45 | MinimumSize = Size;
46 | dgvRestore.ColumnHeadersDefaultCellStyle.Alignment
47 | = dgvRestore.RowsDefaultCellStyle.Alignment
48 | = DataGridViewContentAlignment.BottomCenter;
49 | Controls.AddRange(new Control[] { lblRestore, dgvRestore });
50 | lblRestore.Resize += (sender, e) => OnResize(null);
51 | this.AddEscapeButton();
52 | InitTheme();
53 | ApplyDarkModeToDataGridView(dgvRestore);
54 | }
55 |
56 | readonly DataGridView dgvRestore = new DataGridView
57 | {
58 | ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize,
59 | AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells,
60 | SelectionMode = DataGridViewSelectionMode.FullRowSelect,
61 | BackgroundColor = SystemColors.Control,
62 | BorderStyle = BorderStyle.None,
63 | AllowUserToResizeRows = false,
64 | AllowUserToAddRows = false,
65 | RowHeadersVisible = false,
66 | MultiSelect = false,
67 | ReadOnly = true
68 | };
69 |
70 | readonly Label lblRestore = new Label {
71 | Width = 480.DpiZoom()
72 | };
73 |
74 | protected override void OnResize(EventArgs e)
75 | {
76 | base.OnResize(e);
77 | int a = 20.DpiZoom();
78 | lblRestore.Location = new Point(a, a);
79 | lblRestore.Width = ClientSize.Width;
80 | dgvRestore.Location = new Point(a, lblRestore.Bottom + a);
81 | dgvRestore.Width = ClientSize.Width - 2 * a;
82 | dgvRestore.Height = ClientSize.Height - 3 * a - lblRestore.Height;
83 | }
84 |
85 | public void ShowDonateList(List restoreList)
86 | {
87 | string[] heads = new[] { AppString.Dialog.ItemLocation, AppString.Dialog.RestoredValue };
88 | dgvRestore.ColumnCount = heads.Length;
89 | dgvRestore.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
90 | int restoreCount = restoreList.Count;
91 | for (int n = 0; n < heads.Length; n++)
92 | {
93 | dgvRestore.Columns[n].HeaderText = heads[n];
94 | }
95 | for (int n = 0; n < restoreCount; n++)
96 | {
97 | RestoreChangedItem item = restoreList[n];
98 | Scenes scene = item.BackupScene;
99 | string sceneText = BackupHelper.BackupScenesText[(int)scene];
100 | string[] values;
101 | string changedValue = item.ItemData;
102 | if (changedValue == false.ToString()) changedValue = AppString.Dialog.Disabled;
103 | if (changedValue == true.ToString()) changedValue = AppString.Dialog.Enabled;
104 | if (Array.IndexOf(BackupHelper.TypeBackupScenesText, sceneText) != -1)
105 | {
106 | values = new[] { AppString.ToolBar.Type + " -> " + sceneText + " -> " + item.KeyName, changedValue };
107 | }
108 | else if (Array.IndexOf(BackupHelper.RuleBackupScenesText, sceneText) != -1)
109 | {
110 | values = new[] { AppString.ToolBar.Rule + " -> " + sceneText + " -> " + item.KeyName, changedValue };
111 | }
112 | else
113 | {
114 | values = new[] { AppString.ToolBar.Home + " -> " + sceneText + " -> " + item.KeyName, changedValue };
115 | }
116 | dgvRestore.Rows.Add(values);
117 | }
118 | lblRestore.Text = AppString.Message.RestoreSucceeded.Replace("%s", restoreCount.ToString()); ;
119 | }
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/SendToList.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.IO;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls
9 | {
10 | sealed class SendToList : MyList // 主页 发送到
11 | {
12 | public static readonly string SendToPath = Environment.ExpandEnvironmentVariables(@"%AppData%\Microsoft\Windows\SendTo");
13 | public static readonly string DefaultSendToPath = Environment.ExpandEnvironmentVariables(@"%SystemDrive%\Users\Default\AppData\Roaming\Microsoft\Windows\SendTo");
14 |
15 | public void LoadItems()
16 | {
17 | foreach(string path in Directory.GetFileSystemEntries(SendToPath))
18 | {
19 | if(Path.GetFileName(path).ToLower() == "desktop.ini") continue;
20 | AddItem(new SendToItem(path));
21 | }
22 | SortItemByText();
23 | AddNewItem();
24 | AddDirItem(); // 发送到右键菜单Ink文件的文件夹存放位置
25 | AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.SendToDrive));
26 | AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.DeferBuildSendTo));
27 | }
28 |
29 | private void AddNewItem()
30 | {
31 | NewItem newItem = new NewItem();
32 | InsertItem(newItem, 0);
33 | newItem.AddNewItem += () =>
34 | {
35 | using(NewLnkFileDialog dlg = new NewLnkFileDialog())
36 | {
37 | dlg.FileFilter = $"{AppString.Dialog.Program}|*.exe;*.bat;*.cmd;*.vbs;*.vbe;*.js;*.jse;*.wsf";
38 | if(dlg.ShowDialog() != DialogResult.OK) return;
39 | string lnkPath = $@"{SendToPath}\{ObjectPath.RemoveIllegalChars(dlg.ItemText)}.lnk";
40 | lnkPath = ObjectPath.GetNewPathWithIndex(lnkPath, ObjectPath.PathType.File);
41 | using(ShellLink shellLink = new ShellLink(lnkPath))
42 | {
43 | shellLink.TargetPath = dlg.ItemFilePath;
44 | shellLink.WorkingDirectory = Path.GetDirectoryName(dlg.ItemFilePath);
45 | shellLink.Arguments = dlg.Arguments;
46 | shellLink.Save();
47 | }
48 | DesktopIni.SetLocalizedFileNames(lnkPath, dlg.ItemText);
49 | InsertItem(new SendToItem(lnkPath), 2);
50 | }
51 | };
52 | }
53 |
54 | private void AddDirItem()
55 | {
56 | MyListItem item = new MyListItem
57 | {
58 | Text = Path.GetFileNameWithoutExtension(SendToPath),
59 | Image = ResourceIcon.GetFolderIcon(SendToPath).ToBitmap()
60 | };
61 | PictureButton btnPath = new PictureButton(AppImage.Open);
62 | ToolTipBox.SetToolTip(btnPath, AppString.Menu.FileLocation);
63 | btnPath.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(SendToPath);
64 | item.AddCtr(btnPath);
65 | InsertItem(item, 1);
66 | item.ContextMenuStrip = new ContextMenuStrip();
67 | var tsiRestoreDefault = new RToolStripMenuItem(AppString.Menu.RestoreDefault);
68 | item.ContextMenuStrip.Items.Add(tsiRestoreDefault);
69 | tsiRestoreDefault.Enabled = Directory.Exists(DefaultSendToPath);
70 | tsiRestoreDefault.Click += (sender, e) =>
71 | {
72 | if(AppMessageBox.Show(AppString.Message.RestoreDefault, MessageBoxButtons.OKCancel) == DialogResult.OK)
73 | {
74 | File.SetAttributes(SendToPath, FileAttributes.Normal);
75 | Directory.Delete(SendToPath, true);
76 | Directory.CreateDirectory(SendToPath);
77 | File.SetAttributes(SendToPath, File.GetAttributes(DefaultSendToPath));
78 | foreach(string srcPath in Directory.GetFiles(DefaultSendToPath))
79 | {
80 | string dstPath = $@"{SendToPath}\{Path.GetFileName(srcPath)}";
81 | File.Copy(srcPath, dstPath);
82 | }
83 | ClearItems();
84 | LoadItems();
85 | }
86 | };
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/SubItemsForm.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | namespace ContextMenuManager.Controls
8 | {
9 | sealed class SubItemsForm : RForm
10 | {
11 | public SubItemsForm()
12 | {
13 | SuspendLayout();
14 | StartPosition = FormStartPosition.CenterParent;
15 | ShowInTaskbar = MaximizeBox = MinimizeBox = false;
16 | MinimumSize = Size = new Size(646, 419).DpiZoom();
17 | Controls.AddRange(new Control[] { listBox, statusBar });
18 | statusBar.CanMoveForm();
19 | this.AddEscapeButton();
20 | ResumeLayout();
21 | InitTheme();
22 | }
23 |
24 | readonly MyListBox listBox = new MyListBox { Dock = DockStyle.Fill };
25 | readonly MyStatusBar statusBar = new MyStatusBar();
26 |
27 | public void AddList(MyList myList)
28 | {
29 | myList.Owner = listBox;
30 | myList.HoveredItemChanged += (sender, e) =>
31 | {
32 | if(!AppConfig.ShowFilePath) return;
33 | MyListItem item = myList.HoveredItem;
34 | foreach(string prop in new[] { "ItemFilePath", "RegPath", "GroupPath" })
35 | {
36 | string path = item.GetType().GetProperty(prop)?.GetValue(item, null)?.ToString();
37 | if(!path.IsNullOrWhiteSpace()) { statusBar.Text = path; return; }
38 | }
39 | statusBar.Text = item.Text;
40 | };
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/SwitchDicList.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.Drawing;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager.Controls
9 | {
10 | class SwitchDicList : MyList // 其他菜单 增强菜单
11 | {
12 | public bool UseUserDic { get; set; }
13 |
14 | public virtual void LoadItems()
15 | {
16 | AddSwitchItem();
17 | }
18 |
19 | public void AddSwitchItem()
20 | {
21 | SwitchDicItem item = new SwitchDicItem { UseUserDic = UseUserDic };
22 | item.UseDicChanged += () =>
23 | {
24 | UseUserDic = item.UseUserDic;
25 | ClearItems();
26 | LoadItems();
27 | };
28 | AddItem(item);
29 | }
30 | }
31 |
32 | sealed class SwitchDicItem : MyListItem
33 | {
34 | public SwitchDicItem()
35 | {
36 | Text = AppString.Other.SwitchDictionaries;
37 | AddCtr(cmbDic);
38 | cmbDic.AutosizeDropDownWidth();
39 | cmbDic.Font = new Font(Font.FontFamily, Font.Size + 1F);
40 | cmbDic.Items.AddRange(new[] { AppString.Other.WebDictionaries, AppString.Other.UserDictionaries });
41 | cmbDic.SelectionChangeCommitted += (sender, e) =>
42 | {
43 | Focus();
44 | UseUserDic = cmbDic.SelectedIndex == 1;
45 | };
46 | }
47 |
48 | private bool? useUserDic = null;
49 | public bool UseUserDic
50 | {
51 | get => useUserDic == true;
52 | set
53 | {
54 | if(useUserDic == value) return;
55 | bool flag = useUserDic == null;
56 | useUserDic = value;
57 | Image = UseUserDic ? AppImage.User : AppImage.Web;
58 | cmbDic.SelectedIndex = value ? 1 : 0;
59 | if(!flag) UseDicChanged?.Invoke();
60 | }
61 | }
62 |
63 | public Action UseDicChanged;
64 |
65 | readonly RComboBox cmbDic = new RComboBox
66 | {
67 | DropDownStyle = ComboBoxStyle.DropDownList,
68 | Width = 120.DpiZoom()
69 | };
70 | }
71 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Controls/UwpModeItem.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Controls.Interfaces;
4 | using ContextMenuManager.Methods;
5 | using Microsoft.Win32;
6 | using System;
7 | using System.Windows.Forms;
8 |
9 | namespace ContextMenuManager.Controls
10 | {
11 | sealed class UwpModeItem : MyListItem, IChkVisibleItem, ITsiRegPathItem, ITsiFilePathItem,
12 | IBtnShowMenuItem, ITsiWebSearchItem, ITsiRegExportItem, ITsiRegDeleteItem, ITsiGuidItem
13 | {
14 | public UwpModeItem(string uwpName, Guid guid)
15 | {
16 | Guid = guid;
17 | UwpName = uwpName;
18 | InitializeComponents();
19 | Visible = UwpHelper.GetPackageName(uwpName) != null;
20 | Image = GuidInfo.GetImage(guid);
21 | Text = ItemText;
22 | }
23 |
24 | public Guid Guid { get; set; }
25 | public string UwpName { get; set; }
26 |
27 | public bool ItemVisible // 是否显示于右键菜单中
28 | {
29 | get
30 | {
31 | foreach(string path in GuidBlockedList.BlockedPaths)
32 | {
33 | using(RegistryKey key = RegistryEx.GetRegistryKey(path))
34 | {
35 | if(key == null) continue;
36 | if(key.GetValue(Guid.ToString("B")) != null) return false;
37 | }
38 | }
39 | return true;
40 | }
41 | set
42 | {
43 | foreach(string path in GuidBlockedList.BlockedPaths)
44 | {
45 | if(value)
46 | {
47 | RegistryEx.DeleteValue(path, Guid.ToString("B"));
48 | }
49 | else
50 | {
51 | Registry.SetValue(path, Guid.ToString("B"), "");
52 | }
53 | }
54 | ExplorerRestarter.Show();
55 | }
56 | }
57 |
58 | public string ItemText => GuidInfo.GetText(Guid);
59 | public string RegPath => UwpHelper.GetRegPath(UwpName, Guid);
60 | public string ItemFilePath => UwpHelper.GetFilePath(UwpName, Guid);
61 |
62 | public string SearchText => Text;
63 | public string ValueName => "DllPath";
64 | public MenuButton BtnShowMenu { get; set; }
65 | public VisibleCheckBox ChkVisible { get; set; }
66 | public DetailedEditButton BtnDetailedEdit { get; set; }
67 | public RegLocationMenuItem TsiRegLocation { get; set; }
68 | public FileLocationMenuItem TsiFileLocation { get; set; }
69 | public FilePropertiesMenuItem TsiFileProperties { get; set; }
70 | public WebSearchMenuItem TsiSearch { get; set; }
71 | public DeleteMeMenuItem TsiDeleteMe { get; set; }
72 | public RegExportMenuItem TsiRegExport { get; set; }
73 | public HandleGuidMenuItem TsiHandleGuid { get; set; }
74 |
75 | readonly RToolStripMenuItem TsiDetails = new RToolStripMenuItem(AppString.Menu.Details);
76 |
77 | private void InitializeComponents()
78 | {
79 | BtnShowMenu = new MenuButton(this);
80 | ChkVisible = new VisibleCheckBox(this);
81 | BtnDetailedEdit = new DetailedEditButton(this);
82 | TsiSearch = new WebSearchMenuItem(this);
83 | TsiFileLocation = new FileLocationMenuItem(this);
84 | TsiFileProperties = new FilePropertiesMenuItem(this);
85 | TsiRegLocation = new RegLocationMenuItem(this);
86 | TsiDeleteMe = new DeleteMeMenuItem(this);
87 | TsiRegExport = new RegExportMenuItem(this);
88 | TsiHandleGuid = new HandleGuidMenuItem(this);
89 |
90 | ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid,
91 | new RToolStripSeparator(), TsiDetails, new RToolStripSeparator(), TsiDeleteMe });
92 | TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new RToolStripSeparator(),
93 | TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport });
94 | }
95 |
96 | public void DeleteMe()
97 | {
98 | RegistryEx.DeleteKeyTree(RegPath);
99 | }
100 | }
101 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Methods/AppMessageBox.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System.Windows.Forms;
3 |
4 | namespace ContextMenuManager.Methods
5 | {
6 | public static class AppMessageBox
7 | {
8 | public static DialogResult Show(string text, MessageBoxButtons buttons = MessageBoxButtons.OK,
9 | MessageBoxIcon icon = MessageBoxIcon.Warning, string caption = null)
10 | {
11 | return MessageBoxEx.Show(text, caption ?? AppString.General.AppName, buttons, icon);
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Methods/DesktopIni.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using System.IO;
3 |
4 | namespace ContextMenuManager.Methods
5 | {
6 | static class DesktopIni
7 | {
8 | private const string LocalizedFileNames = "LocalizedFileNames";
9 |
10 | public static string GetDesktopIniPath(string filePath) => $@"{Path.GetDirectoryName(filePath)}\desktop.ini";
11 |
12 | public static void DeleteLocalizedFileNames(string filePath)
13 | {
14 | IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));
15 | string fileName = Path.GetFileName(filePath);
16 | writer.DeleteKey(LocalizedFileNames, fileName);
17 | }
18 |
19 | public static void SetLocalizedFileNames(string filePath, string name)
20 | {
21 | IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));
22 | string fileName = Path.GetFileName(filePath);
23 | writer.SetValue(LocalizedFileNames, fileName, name);
24 | }
25 |
26 | public static string GetLocalizedFileNames(string filePath, bool translate = false)
27 | {
28 | IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));
29 | string fileName = Path.GetFileName(filePath);
30 | string name = writer.GetValue(LocalizedFileNames, fileName);
31 | if(translate) name = ResourceString.GetDirectString(name);
32 | return name;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Methods/UwpHelper.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Methods;
2 | using Microsoft.Win32;
3 | using System;
4 | using System.IO;
5 |
6 | namespace ContextMenuManager.Methods
7 | {
8 | static class UwpHelper
9 | {
10 | private const string PackageRegPath = @"HKEY_CLASSES_ROOT\PackagedCom\Package";
11 | private const string PackagesRegPath = @"HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages";
12 |
13 | public static string GetPackageName(string uwpName)
14 | {
15 | if(string.IsNullOrEmpty(uwpName)) return null;
16 | using(RegistryKey packageKey = RegistryEx.GetRegistryKey(PackageRegPath))
17 | {
18 | if(packageKey == null) return null;
19 | foreach(string packageName in packageKey.GetSubKeyNames())
20 | {
21 | if(packageName.StartsWith(uwpName, StringComparison.OrdinalIgnoreCase))
22 | {
23 | return packageName;
24 | }
25 | }
26 | }
27 | return null;
28 | }
29 |
30 | public static string GetRegPath(string uwpName, Guid guid)
31 | {
32 | string packageName = GetPackageName(uwpName);
33 | if(packageName == null) return null;
34 | else return $@"{PackageRegPath}\{packageName}\Class\{guid:B}";
35 | }
36 |
37 | public static string GetFilePath(string uwpName, Guid guid)
38 | {
39 | string regPath = GetRegPath(uwpName, guid);
40 | if(regPath == null) return null;
41 | string packageName = GetPackageName(uwpName);
42 | using(RegistryKey pKey = RegistryEx.GetRegistryKey($@"{PackagesRegPath}\{packageName}"))
43 | {
44 | if(pKey == null) return null;
45 | string dirPath = pKey.GetValue("Path")?.ToString();
46 | string dllPath = Registry.GetValue(regPath, "DllPath", null)?.ToString();
47 | string filePath = $@"{dirPath}\{dllPath}";
48 | if(File.Exists(filePath)) return filePath;
49 | string[] names = pKey.GetSubKeyNames();
50 | if(names.Length == 1)
51 | {
52 | filePath = "shell:AppsFolder\\" + names[0];
53 | return filePath;
54 | }
55 | if(Directory.Exists(dirPath)) return dirPath;
56 | return null;
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Program.cs:
--------------------------------------------------------------------------------
1 | using BluePointLilac.Controls;
2 | using BluePointLilac.Methods;
3 | using ContextMenuManager.Methods;
4 | using System;
5 | using System.IO;
6 | using System.Windows.Forms;
7 |
8 | namespace ContextMenuManager
9 | {
10 | //兼容.Net3.5和.Net4.0,兼容Vista - Win11
11 | static class Program
12 | {
13 | [STAThread]
14 | static void Main()
15 | {
16 | #if DEBUG
17 | if (AppConfig.EnableLog)
18 | {
19 | using (StreamWriter sw = new StreamWriter(AppConfig.DebugLogPath, true))
20 | {
21 | sw.WriteLine($@"--------------------{DateTime.Now:yyyy-MM-dd HH:mm:ss}--------------------");
22 | }
23 | }
24 | #endif
25 | MyMainForm.InitColors();
26 | Application.EnableVisualStyles();
27 | Application.SetCompatibleTextRenderingDefault(false);
28 | if(SingleInstance.IsRunning()) return;
29 | AppString.LoadStrings();
30 | Updater.PeriodicUpdate();
31 | XmlDicHelper.ReloadDics();
32 | Application.Run(new MainForm());
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/App.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | true
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/AppIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/AppIcon.ico
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("右键菜单管理工具")]
5 | [assembly: AssemblyDescription("右键菜单管理工具")]
6 | [assembly: AssemblyConfiguration("")]
7 | [assembly: AssemblyCompany("蓝点lilac Jack251970")]
8 | [assembly: AssemblyProduct("右键菜单管理工具")]
9 | [assembly: AssemblyCopyright("Copyright @ 2020-2025 蓝点lilac Jack251970")]
10 | [assembly: AssemblyTrademark("蓝点lilac Jack25197")]
11 | [assembly: AssemblyCulture("")]
12 | [assembly: ComVisible(false)]
13 | [assembly: Guid("35190ec1-2515-488d-a2e9-825d6ff67aa2")]
14 | [assembly: AssemblyVersion("3.4.0.1")]
15 | [assembly: AssemblyFileVersion("3.4.0.1")]
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/About.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/About.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Add.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/AddExisting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/AddExisting.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/AddSeparator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/AddSeparator.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/BackupItem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/BackupItem.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/CheckUpdate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/CheckUpdate.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/ContextMenuStyle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/ContextMenuStyle.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Custom.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Delete.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Donate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Donate.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/DownLoad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/DownLoad.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Enhance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Enhance.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Home.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Jump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Jump.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/MicrosoftStore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/MicrosoftStore.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/NewFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/NewFolder.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/NewItem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/NewItem.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Open.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Refresh.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Select.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Setting.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Sort.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Star.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/SubItems.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/SubItems.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Translate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Translate.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Type.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Up.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/User.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/User.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Images/Web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/Images/Web.png
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | return 0;
6 | }
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/ShellNew/0.rar
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.reg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/ShellNew/0.reg
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1}
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/ContextMenuManager/Properties/Resources/ShellNew/0.xlsx
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/ShellNew/0.zip:
--------------------------------------------------------------------------------
1 | PK
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Resources/Texts/UwpModeItemsDic.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ContextMenuManager.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.6.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ContextMenuManager/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Logo/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Logo/Logo.png
--------------------------------------------------------------------------------
/README-en.md:
--------------------------------------------------------------------------------
1 | **[简体中文](README.md)** | **English**
2 |
3 | # ContextMenuManager
4 | 
5 | ------
6 | > 🖱️ A program to manage the Windows right-click context menu with support of Windows 7 - 11.
7 |
8 | ## 💕 Thanks
9 | * This project is based on [https://github.com/BluePointLilac/ContextMenuManager](https://github.com/BluePointLilac/ContextMenuManager), thanks to [蓝点lilac](https://github.com/BluePointLilac)!
10 | * Thanks to [蓝芸柒](https://github.com/LanYunSeven) for new icons!
11 |
12 | ## 🚀 Download
13 | * [Latest Version][Latest]
14 | [Github Releases][GitHub Releases]
15 | [Gitee Releases][Gitee Releases]
16 | * Note: Download the zip file (recommended) or the exe file in the Assets list
17 | * About .NET versions: This application is based on the the .Net 4.8, and it is compatible with Windows 7, 8, 8.1, 10, 11.
18 | Win8, 8.1, 10, 11 come with .NET 4.8. Vista and Win7 does not come with .NET 4.8.
You may need to install the appropriate [.NET Framework Runtime Library][.NET Framework Runtime Library].
19 |
20 | ## ⭐ Features
21 | * Enable and disable context menu options for files, folders, submenus (e.g. open, send to), Internet Explorer, and Win+X, etc., and backup and restore right-click menus
22 | * Modify menu names and icons
23 | * Delete context menu entries
24 | * Navigate menus in the registry or File Explorer
25 | * Add custom menu items and commands
26 |
27 | ## 🖥️ Compatibility
28 | * Windows 7, 8, 8.1, 10, 11
29 | * 32 and 64 bit operating systems
30 | * Support for display scaling, optimal at 150% DPI
31 | * Localization support: contributions are welcome
32 |
33 | ## 🖼️ Screenshots
34 |
35 |
36 |
37 |
38 |
39 |
40 | ## 🔣 Resources
41 |
42 |
43 |
44 |
45 |
46 |
47 | ## 🪧 Notices
48 | * The program needs to read, write and delete a lot of registry entries and files, these behaviours are sensitive and may be mistakenly reported as viruses by Windows Defender, etc. If this happens, please add it to the whitelist by yourself.
49 |
50 | * Some special menu items (Shell extensions, file encryption, etc.) may not be displayed in the context menu, but will still show as enabled within the program; this is normal.
51 |
52 | * Different context menu manager programs may use different methods for disabling menu options. Using multiple managers at the same time is not recommended.
53 |
54 | * While other programs may use destructive methods, this program utilizes the registry keys provided by the system to hide menu items when possible.
55 |
56 | * If you have used other context menu managers in the past, use that program to restore the menu items before using this one in order to avoid any potential issues.
57 |
58 | * This program is not designed to perform clean uninstalls; however, it can help you find the registry and file locations of menu items so that they can be modified. If you are not familiar with such operations, it is recommended you use the enable/disable functions only.
59 |
60 | ## 🏆 Contributors
61 | Thanks to our amazing contributors!
62 |
63 | [](https://github.com/Jack251970/ContextMenuManager/graphs/contributors)
64 |
65 | Made with [contrib.rocks](https://contrib.rocks).
66 |
67 | [Latest]: https://github.com/Jack251970/ContextMenuManager/releases/latest
68 | [GitHub Releases]: https://github.com/Jack251970/ContextMenuManager/releases
69 | [Gitee Releases]: https://gitee.com/Jack251970/ContextMenuManager/releases
70 | [.NET Framework Runtime Library]: https://dotnet.microsoft.com/download/dotnet-framework
71 |
72 | ## ❤️ Thank You
73 |
74 | If you are enjoying this plugin, then please support my work and enthusiasm by buying me a coffee on
75 | [https://ko-fi/jackye](https://ko-fi.com/jackye).
76 |
77 | [
](https://ko-fi.com/jackye)
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **简体中文** | **[English](README-en.md)**
2 |
3 | # ContextMenuManager
4 | 
5 | ------
6 | > 🖱️ 一个纯粹的Windows右键菜单管理程序,支持 Windows 7 ~ 11。
7 |
8 | ## 💕 特别感谢
9 | * 本项目基于 [https://github.com/BluePointLilac/ContextMenuManager](https://github.com/BluePointLilac/ContextMenuManager) 进行开发,感谢作者 [蓝点lilac](https://github.com/BluePointLilac)!
10 | * 感谢由 [蓝芸柒](https://github.com/LanYunSeven) 制作的的新图标!
11 |
12 | ## 🚀 程序下载
13 | * [最新版本][Latest]
14 | [GitHub Releases][GitHub Releases]
15 | [Gitee Releases][Gitee Releases]
16 | * 下载说明:在Assets文件列表里面下载zip(建议)或者直接下载exe
17 | * .NET版本说明:程序基于.NET4.8,适用于Win11、10、8.1、8、7
18 | Win8、8.1、10、11自带.NET4.8,win7不自带.NET4.8
19 | 自带.NET可直接运行程序,不自带则需要安装对应版本的[.NET Framework运行库]
20 |
21 | ## ⭐ 主要功能
22 | * 启用或禁用文件、文件夹、新建、发送到、打开方式、自定义文件格式、IE浏览器、WinX等右键菜单项目并对右键菜单进行备份和恢复
23 | * 对上述场景右键菜单项目进行修改名称、修改图标、导航注册表位置、导航文件位置、永久删除等操作
24 | * 对上述场景右键菜单自定义添加项目,自定义菜单命令
25 |
26 | ## 🖥️ 兼容性
27 | * 适用于 Windows 7、8、8.1、10、11
28 | * 适用于 64位、32位 的系统
29 | * 适用于高分屏,最佳显示缩放比为150%
30 | * 程序支持国际化多语言显示,欢迎为此程序制作语言字典
31 |
32 | ## 🖼️ 运行截图
33 |
34 |
35 |
36 |
37 |
38 |
39 | ## 🔣 资源引用
40 |
41 |
42 |
43 |
44 |
45 |
46 | ## 🪧 温馨提示
47 | * 程序需要对大量的注册表项和文件进行读写删改操作,这些行为比较敏感,可能会被 Windows Defender 等误报为病毒,如发生此情况请自行添加进白名单。
48 |
49 | * 一些特殊菜单项(Shell 扩展、加密文件等)可能会受到其他因素影响导致不会直接显示在右键菜单中,但是按照程序使用的通用规则在此程序中仍会显示为启用,这是正常的现象。
50 |
51 | * 每个右键管理程序禁用菜单方法可能不同,建议不要同时使用多个右键菜单管理程序。
52 |
53 | * 大部分程序使用简单暴力的备份删除法,此程序尽可能使用了系统提供的键值进行隐藏以便于之后的恢复。
54 |
55 | * 通过其他程序禁用的菜单项目。请先使用对应程序还原,不然可能无法在此程序中看到它。
56 |
57 | * 此程序不用于清理未卸载干净的程序,但是可以帮助你快速定位菜单项相关注册表位置和文件位置,你可以根据相关内容进行你的操作。如果你是一个电脑小白,建议只使用启用/禁用功能。
58 |
59 | ## 🏆 贡献者
60 | 感谢我们的贡献者们!
61 |
62 | [](https://github.com/Jack251970/ContextMenuManager/graphs/contributors)
63 |
64 | 由 [contrib.rocks](https://contrib.rocks) 生成。
65 |
66 | [Latest]: https://github.com/Jack251970/ContextMenuManager/releases/latest
67 | [GitHub Releases]: https://github.com/Jack251970/ContextMenuManager/releases
68 | [Gitee Releases]: https://gitee.com/Jack251970/ContextMenuManager/releases
69 | [.NET Framework运行库]: https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/net48
70 |
71 | ## ❤️ 感谢
72 |
73 | 要是你觉得这插件好用,就请我喝杯咖啡支持一下吧!
74 |
75 | [
](https://ko-fi.com/jackye)
76 |
--------------------------------------------------------------------------------
/Screenshot/AppImage-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/AppImage-dark.png
--------------------------------------------------------------------------------
/Screenshot/AppImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/AppImage.png
--------------------------------------------------------------------------------
/Screenshot/Screenshot-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/Screenshot-dark.png
--------------------------------------------------------------------------------
/Screenshot/Screenshot-en-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/Screenshot-en-dark.png
--------------------------------------------------------------------------------
/Screenshot/Screenshot-en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/Screenshot-en.png
--------------------------------------------------------------------------------
/Screenshot/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/Screenshot/Screenshot.png
--------------------------------------------------------------------------------
/languages/pt-BR.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/languages/pt-BR.ini
--------------------------------------------------------------------------------
/languages/ru-RU.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jack251970/ContextMenuManager/05f79d92f396125909e114754a126b086a0945ca/languages/ru-RU.ini
--------------------------------------------------------------------------------