Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fd1285ad8 | ||
|
|
91a67c29a7 | ||
|
|
c8ce0b6dfc | ||
|
|
c075f4982b | ||
|
|
303355ce63 | ||
|
|
a392c2c6da | ||
|
|
72d6f44e47 | ||
|
|
2e695e43bf | ||
|
|
207c2fc685 | ||
|
|
3939dc7924 | ||
|
|
97521e034f | ||
|
|
d91bba6521 | ||
|
|
7e1c30ffa0 | ||
|
|
e957101268 | ||
|
|
c25c605672 | ||
|
|
54a8982e6d | ||
|
|
7b68e8b581 | ||
|
|
3a66bff0cc | ||
|
|
6022809080 |
@@ -1,9 +1,9 @@
|
||||
Imports System.ComponentModel.Composition
|
||||
Imports System.IO
|
||||
|
||||
Imports vbnet
|
||||
Imports mpvnet
|
||||
Imports vbnet.UI.MainModule
|
||||
Imports mpvnet.StaticUsing
|
||||
|
||||
Imports CSScriptLibrary
|
||||
|
||||
<Export(GetType(IAddon))>
|
||||
@@ -11,7 +11,7 @@ Public Class CSScriptAddon
|
||||
Implements IAddon
|
||||
|
||||
Sub New()
|
||||
Dim scriptDir = Folder.AppDataRoaming + "mpv\scripts"
|
||||
Dim scriptDir = mp.mpvConfFolderPath + "scripts"
|
||||
If Not Directory.Exists(scriptDir) Then Return
|
||||
Dim csFiles = Directory.GetFiles(scriptDir, "*.cs")
|
||||
If csFiles.Count = 0 Then Return
|
||||
@@ -21,7 +21,7 @@ Public Class CSScriptAddon
|
||||
Try
|
||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
||||
Catch ex As Exception
|
||||
MsgException(ex)
|
||||
MsgError(ex.ToString)
|
||||
End Try
|
||||
Next
|
||||
End Sub
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\mpvnet\bin\Debug\Addons\CSScript\</OutputPath>
|
||||
<OutputPath>..\mpv.net\bin\Debug\Addons\CSScriptAddon\</OutputPath>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
@@ -52,11 +52,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mpvnet, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\mpvnet\bin\Debug\mpvnet.exe</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Data" />
|
||||
@@ -65,10 +60,6 @@
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="vbnet">
|
||||
<HintPath>..\vbnet\bin\Debug\vbnet.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
@@ -121,5 +112,12 @@
|
||||
<ItemGroup>
|
||||
<Content Include="CSScriptLibrary.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -8,11 +8,11 @@ Imports System.Runtime.InteropServices
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("PowerShellAddon")>
|
||||
<Assembly: AssemblyTitle("CSScriptAddon")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("PowerShellAddon")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2017")>
|
||||
<Assembly: AssemblyProduct("CSScriptAddon")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2019")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
63
README.md
63
README.md
@@ -1,17 +1,20 @@
|
||||
# mpv.net
|
||||
|
||||
mpv.net is a libmpv based media player for Windows, it looks and works like mpv, even shares the settings and therefore the mpv documentation applies, it can be found at:
|
||||
mpv.net is a libmpv based media player for Windows, it looks and works like mpv, even shares the settings and therefore the mpv documentation applies.
|
||||
|
||||
https://mpv.io/manual/master/
|
||||
mpv and mpv.net have a learning curve and are only suitable for experienced users.
|
||||
|
||||
mpv manual: https://mpv.io/manual/master/
|
||||
|
||||
### Features
|
||||
|
||||
- Customizable context menu defined in the same file as the keybindings
|
||||
- Addon API for .NET languages
|
||||
- Python scripting implemented with IronPython
|
||||
- C# scripting implemented with CS-Script
|
||||
- mpv's OSC, IPC, Lua/JS, conf files and more
|
||||
- Context menu which can be customized
|
||||
- Addons implemented with the Managed Extension Framework (MEF)
|
||||
- C# scripts implemented with CS-Script
|
||||
|
||||

|
||||

|
||||
|
||||
### Context Menu
|
||||
|
||||
@@ -19,7 +22,9 @@ The context menu can be customized via input.conf file located at:
|
||||
|
||||
C:\Users\Frank\AppData\Roaming\mpv\input.conf
|
||||
|
||||
https://github.com/stax76/mpvnet/blob/master/mpvnet/Resources/input_conf.txt
|
||||
if it misses mpv.net generates it with the following defaults:
|
||||
|
||||
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input_conf.txt
|
||||
|
||||
### C# Scripting
|
||||
|
||||
@@ -44,8 +49,50 @@ class Script
|
||||
}
|
||||
```
|
||||
|
||||
### Python Scripting
|
||||
|
||||
A simple Python script located at: C:\Users\user\AppData\Roaming\mpv\scripts
|
||||
|
||||
```
|
||||
# when seeking displays position and
|
||||
# duration like so: 70:00 / 80:00
|
||||
# which is different from mpv which
|
||||
# uses 01:10:00 / 01:20:00
|
||||
|
||||
import math
|
||||
|
||||
def seek():
|
||||
mp.commandv('show-text',
|
||||
format(mp.get_property_number("time-pos")) + " / " + format(mp.get_property_number("duration")))
|
||||
|
||||
def format(f):
|
||||
sec = round(f)
|
||||
|
||||
if sec < 0:
|
||||
sec = 0
|
||||
|
||||
pos_min_floor = math.floor(sec / 60)
|
||||
sec_rest = sec - pos_min_floor * 60
|
||||
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest)
|
||||
|
||||
def add_zero(val):
|
||||
val = round(val)
|
||||
return "" + str(int(val)) if (val > 9) else "0" + str(int(val))
|
||||
|
||||
mp.register_event("seek", seek) # or use: mp.Seek += seek
|
||||
```
|
||||
|
||||
### Changes
|
||||
|
||||
### 1.1
|
||||
|
||||
- added support for Python scripting via IronPython
|
||||
- show tracks and show playlist didn't work because the duration wasn't defined in the key bindings
|
||||
|
||||
### 1.0
|
||||
|
||||
- much more feature packed context menu
|
||||
|
||||
### 0.2.5
|
||||
|
||||
- mpv lib updated to 2019-02-24
|
||||
@@ -70,4 +117,4 @@ class Script
|
||||
|
||||
### 0.2.1
|
||||
|
||||
- right-click in fullscreen in the right-left corner closes the app
|
||||
- right-click in fullscreen in the right-left corner closes the app
|
||||
|
||||
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Rating")]
|
||||
[assembly: AssemblyTitle("RatingAddon")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Rating")]
|
||||
[assembly: AssemblyProduct("RatingAddon")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using mpvnet;
|
||||
using System.IO;
|
||||
|
||||
namespace Rating
|
||||
using mpvnet;
|
||||
|
||||
namespace RatingAddon
|
||||
{
|
||||
[Export(typeof(IAddon))]
|
||||
public class Rating : IAddon
|
||||
public class RatingAddon : IAddon
|
||||
{
|
||||
private Dictionary<string, int> Dic = new Dictionary<string, int>();
|
||||
|
||||
public Rating()
|
||||
public RatingAddon()
|
||||
{
|
||||
mpv.ClientMessage += mpv_ClientMessage;
|
||||
mpv.Shutdown += mpv_Shutdown;
|
||||
mp.ClientMessage += mpv_ClientMessage;
|
||||
mp.Shutdown += mpv_Shutdown;
|
||||
}
|
||||
|
||||
private void mpv_Shutdown()
|
||||
@@ -51,8 +51,8 @@ namespace Rating
|
||||
if (args?.Length != 2 || args[0] != "rate-file" || ! int.TryParse(args[1], out rating))
|
||||
return;
|
||||
|
||||
Dic[mpv.GetStringProp("path")] = rating;
|
||||
mpv.Command("show-text", $"Rating: {rating}");
|
||||
Dic[mp.GetStringProp("path")] = rating;
|
||||
mp.Command("show-text", $"Rating: {rating}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<ProjectGuid>{55C88710-539D-4402-84C8-31694841C731}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Rating</RootNamespace>
|
||||
<RootNamespace>RatingAddon</RootNamespace>
|
||||
<AssemblyName>RatingAddon</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
@@ -17,7 +17,7 @@
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\mpvnet\bin\Debug\Addons\Rating\</OutputPath>
|
||||
<OutputPath>..\mpv.net\bin\Debug\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
@@ -67,10 +67,6 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mpvnet">
|
||||
<HintPath>..\mpvnet\bin\Debug\mpvnet.exe</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -82,8 +78,15 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Rating.cs" />
|
||||
<Compile Include="RatingAddon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,31 +0,0 @@
|
||||
// when seeking displays position and
|
||||
// duration like so: 00:00 / 120:00
|
||||
// this is different from MPC which
|
||||
// uses 00:00:00 / 02:00:00
|
||||
|
||||
function add_zero(val)
|
||||
{
|
||||
val = Math.round(val);
|
||||
return val > 9 ? "" + val : "0" + val;
|
||||
}
|
||||
|
||||
function format(val)
|
||||
{
|
||||
var sec = Math.round(val);
|
||||
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
|
||||
pos_min_floor = Math.floor(sec / 60);
|
||||
sec_rest = sec - pos_min_floor * 60;
|
||||
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest);
|
||||
}
|
||||
|
||||
function on_seek(_)
|
||||
{
|
||||
mp.commandv("show-text",
|
||||
format(mp.get_property_number("time-pos")) + " / " +
|
||||
format(mp.get_property_number("duration")));
|
||||
}
|
||||
|
||||
mp.register_event("seek", on_seek);
|
||||
22
mpv.net.sln
22
mpv.net.sln
@@ -3,15 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.8
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpvnet\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{55C88710-539D-4402-84C8-31694841C731} = {55C88710-539D-4402-84C8-31694841C731}
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA} = {71808A87-8B1C-4DF8-957C-D79C3B164CCA}
|
||||
EndProjectSection
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rating", "RatingAddon\Rating.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vbnet", "vbnet\vbnet.vbproj", "{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
|
||||
EndProject
|
||||
@@ -49,18 +43,6 @@ Global
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}.Release|x86.Build.0 = Release|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
||||
@@ -1,31 +1,11 @@
|
||||
/**
|
||||
*mpv.net
|
||||
*Copyright(C) 2017 stax76
|
||||
*
|
||||
*This program is free software: you can redistribute it and/or modify
|
||||
*it under the terms of the GNU General Public License as published by
|
||||
*the Free Software Foundation, either version 3 of the License, or
|
||||
*(at your option) any later version.
|
||||
*
|
||||
*This program is distributed in the hope that it will be useful,
|
||||
*but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
*GNU General Public License for more details.
|
||||
*
|
||||
*You should have received a copy of the GNU General Public License
|
||||
*along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.ComponentModel.Composition.Hosting;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using static vbnet.UI.MainModule;
|
||||
|
||||
// MEF (Managed Extension Framework)
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -48,7 +28,7 @@ namespace mpvnet
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
||||
|
||||
dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\Addons";
|
||||
dir = mp.mpvConfFolderPath + "\\Addons";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
@@ -62,7 +42,7 @@ namespace mpvnet
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MsgException(e);
|
||||
MsgError(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using vbnet;
|
||||
using static vbnet.UI.MainModule;
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -51,48 +50,46 @@ namespace mpvnet
|
||||
d.Filter = Misc.GetFilter(Misc.FileTypes);
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
mpv.LoadFiles(d.FileNames);
|
||||
mp.LoadFiles(d.FileNames);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void open_config_folder(string[] args)
|
||||
{
|
||||
ProcessHelp.Start(Folder.AppDataRoaming + "mpv");
|
||||
Process.Start(mp.mpvConfFolderPath);
|
||||
}
|
||||
|
||||
public static void show_keys(string[] args)
|
||||
{
|
||||
ProcessHelp.Start(OS.GetTextEditor(), '"' + mpv.InputConfPath + '"');
|
||||
Process.Start(mp.InputConfPath);
|
||||
}
|
||||
|
||||
private static void CreateMpvConf()
|
||||
{
|
||||
if (!File.Exists(mpv.mpvConfPath))
|
||||
if (!File.Exists(mp.mpvConfPath))
|
||||
{
|
||||
var dirPath = Folder.AppDataRoaming + "mpv\\";
|
||||
if (!Directory.Exists(mp.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mp.mpvConfFolderPath);
|
||||
|
||||
if (!Directory.Exists(dirPath))
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
File.WriteAllText(mpv.mpvConfPath, "# https://mpv.io/manual/master/#configuration-files");
|
||||
File.WriteAllText(mp.mpvConfPath, "# https://mpv.io/manual/master/#configuration-files");
|
||||
}
|
||||
}
|
||||
|
||||
public static void show_prefs(string[] args)
|
||||
{
|
||||
CreateMpvConf();
|
||||
ProcessHelp.Start(OS.GetTextEditor(), '"' + mpv.mpvConfPath + '"');
|
||||
Process.Start(mp.mpvConfPath);
|
||||
}
|
||||
|
||||
public static void history(string[] args)
|
||||
{
|
||||
var fp = Folder.AppDataRoaming + "mpv\\history.txt";
|
||||
var fp = mp.mpvConfFolderPath + "history.txt";
|
||||
|
||||
if (File.Exists(fp))
|
||||
Process.Start(fp);
|
||||
else
|
||||
if (MsgQuestion($"Create history.txt file in config folder?{BR2}mpv.net will write the date, time and filename of opened files to it.") == DialogResult.OK)
|
||||
if (MsgQuestion("Create history.txt file in config folder?\r\n\r\nmpv.net will write the date, time and filename of opened files to it.") == DialogResult.OK)
|
||||
File.WriteAllText(fp, "");
|
||||
}
|
||||
|
||||
@@ -106,7 +103,7 @@ namespace mpvnet
|
||||
CreateMpvConf();
|
||||
|
||||
bool changed = false;
|
||||
string fp = mpv.mpvConfPath;
|
||||
string fp = mp.mpvConfPath;
|
||||
var confLines = File.ReadAllLines(fp);
|
||||
|
||||
for (int i = 0; i < confLines.Length; i++)
|
||||
@@ -133,25 +130,25 @@ namespace mpvnet
|
||||
|
||||
public static void show_info(string[] args)
|
||||
{
|
||||
var fi = new FileInfo(mpv.GetStringProp("path"));
|
||||
var fi = new FileInfo(mp.GetStringProp("path"));
|
||||
|
||||
using (var mi = new MediaInfo(fi.FullName))
|
||||
{
|
||||
var w = mi.GetInfo(StreamKind.Video, "Width");
|
||||
var h = mi.GetInfo(StreamKind.Video, "Height");
|
||||
var pos = TimeSpan.FromSeconds(mpv.GetIntProp("time-pos"));
|
||||
var dur = TimeSpan.FromSeconds(mpv.GetIntProp("duration"));
|
||||
string mibr = mi.GetInfo(StreamKind.Video, "BitRate");
|
||||
var w = mi.GetInfo(MediaInfoStreamKind.Video, "Width");
|
||||
var h = mi.GetInfo(MediaInfoStreamKind.Video, "Height");
|
||||
var pos = TimeSpan.FromSeconds(mp.GetIntProp("time-pos"));
|
||||
var dur = TimeSpan.FromSeconds(mp.GetIntProp("duration"));
|
||||
string mibr = mi.GetInfo(MediaInfoStreamKind.Video, "BitRate");
|
||||
|
||||
if (mibr == "")
|
||||
mibr = "0";
|
||||
|
||||
var br = Convert.ToInt32(mibr) / 1000.0 / 1000.0;
|
||||
var vf = mpv.GetStringProp("video-format").ToUpper();
|
||||
var vf = mp.GetStringProp("video-format").ToUpper();
|
||||
var fn = fi.Name;
|
||||
|
||||
if (fn.Length > 60)
|
||||
fn = fn.Insert(59, BR);
|
||||
fn = fn.Insert(59, "\r\n");
|
||||
|
||||
var info =
|
||||
FormatTime(pos.TotalMinutes) + ":" +
|
||||
@@ -161,7 +158,7 @@ namespace mpvnet
|
||||
((int)(fi.Length / 1024 / 1024)).ToString() +
|
||||
$" MB - {w} x {h}\n{vf} - {br.ToString("f1")} Mb/s" + "\n" + fn;
|
||||
|
||||
mpv.Command("show-text", info, "5000");
|
||||
mp.Command("show-text", info, "5000");
|
||||
|
||||
string FormatTime(double value) => ((int)(Math.Floor(value))).ToString("00");
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
BIN
mpv.net/IronPython/IKVM.Reflection.dll
Normal file
BIN
mpv.net/IronPython/IKVM.Reflection.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPython.Modules.dll
Normal file
BIN
mpv.net/IronPython/IronPython.Modules.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPython.dll
Normal file
BIN
mpv.net/IronPython/IronPython.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPythonAddon.dll
Normal file
BIN
mpv.net/IronPython/IronPythonAddon.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/Microsoft.Dynamic.dll
Normal file
BIN
mpv.net/IronPython/Microsoft.Dynamic.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/Microsoft.Scripting.dll
Normal file
BIN
mpv.net/IronPython/Microsoft.Scripting.dll
Normal file
Binary file not shown.
@@ -43,7 +43,7 @@
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(1553, 1000);
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
@@ -52,8 +52,6 @@
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "mpv.net";
|
||||
this.Activated += new System.EventHandler(this.MainForm_Activated);
|
||||
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
@@ -4,10 +4,8 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using vbnet;
|
||||
using vbnet.UI;
|
||||
using static vbnet.UI.MainModule;
|
||||
using System.Diagnostics;
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -18,7 +16,7 @@ namespace mpvnet
|
||||
|
||||
private Point LastCursorPosChanged;
|
||||
private int LastCursorChangedTickCount;
|
||||
private bool IsCloseRequired = true;
|
||||
private bool IsClosed;
|
||||
|
||||
public ContextMenuStripEx CMS;
|
||||
|
||||
@@ -32,8 +30,7 @@ namespace mpvnet
|
||||
SetFormPosSize();
|
||||
Instance = this;
|
||||
Hwnd = Handle;
|
||||
ChangeFullscreen((mpv.mpvConv.ContainsKey("fullscreen") && mpv.mpvConv["fullscreen"] == "yes") || (mpv.mpvConv.ContainsKey("fs") && mpv.mpvConv["fs"] == "yes"));
|
||||
ToolStripManager.Renderer = new ToolStripRendererEx(ToolStripRenderModeEx.SystemDefault);
|
||||
ChangeFullscreen((mp.mpvConv.ContainsKey("fullscreen") && mp.mpvConv["fullscreen"] == "yes") || (mp.mpvConv.ContainsKey("fs") && mp.mpvConv["fs"] == "yes"));
|
||||
CMS = new ContextMenuStripEx(components);
|
||||
CMS.Opened += CMS_Opened;
|
||||
ContextMenuStrip = CMS;
|
||||
@@ -47,17 +44,15 @@ namespace mpvnet
|
||||
|
||||
public void BuildMenu()
|
||||
{
|
||||
if (!File.Exists(mpv.InputConfPath))
|
||||
if (!File.Exists(mp.InputConfPath))
|
||||
{
|
||||
var dirPath = Folder.AppDataRoaming + "mpv\\";
|
||||
if (!Directory.Exists(mp.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mp.mpvConfFolderPath);
|
||||
|
||||
if (!Directory.Exists(dirPath))
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
File.WriteAllText(mpv.InputConfPath, Properties.Resources.input_conf);
|
||||
File.WriteAllText(mp.InputConfPath, Properties.Resources.input_conf);
|
||||
}
|
||||
|
||||
foreach (var i in File.ReadAllText(mpv.InputConfPath).SplitLinesNoEmpty())
|
||||
foreach (var i in File.ReadAllText(mp.InputConfPath).SplitLinesNoEmpty())
|
||||
{
|
||||
if (!i.Contains("#menu:"))
|
||||
continue;
|
||||
@@ -78,11 +73,11 @@ namespace mpvnet
|
||||
var menuItem = CMS.Add(path, () => {
|
||||
try
|
||||
{
|
||||
mpv.CommandString(cmd, false);
|
||||
mp.CommandString(cmd, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MsgException(e);
|
||||
MsgError(e.ToString());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -98,15 +93,15 @@ namespace mpvnet
|
||||
|
||||
private string LastHistory;
|
||||
|
||||
private void mpv_PlaybackRestart()
|
||||
private void mp_PlaybackRestart()
|
||||
{
|
||||
var fn = mpv.GetStringProp("filename");
|
||||
var fn = mp.GetStringProp("filename");
|
||||
BeginInvoke(new Action(() => { Text = fn + " - mpv.net " + Application.ProductVersion; }));
|
||||
var fp = Folder.AppDataRoaming + "mpv\\history.txt";
|
||||
var fp = mp.mpvConfFolderPath + "history.txt";
|
||||
|
||||
if (LastHistory != fn && File.Exists(fp))
|
||||
{
|
||||
File.AppendAllText(fp, DateTime.Now.ToString() + " " + Path.GetFileNameWithoutExtension(fn) + BR);
|
||||
File.AppendAllText(fp, DateTime.Now.ToString() + " " + Path.GetFileNameWithoutExtension(fn) + "\r\n");
|
||||
LastHistory = fn;
|
||||
}
|
||||
}
|
||||
@@ -123,26 +118,26 @@ namespace mpvnet
|
||||
|
||||
void HandleException(Exception e)
|
||||
{
|
||||
MsgException(e);
|
||||
MsgError(e.ToString());
|
||||
}
|
||||
|
||||
private void Mpv_VideoSizeChanged()
|
||||
private void mp_VideoSizeChanged()
|
||||
{
|
||||
BeginInvoke(new Action(() => SetFormPosSize()));
|
||||
}
|
||||
|
||||
private void Mpv_AfterShutdown()
|
||||
private void mp_Shutdown()
|
||||
{
|
||||
if (IsCloseRequired)
|
||||
if (!IsClosed)
|
||||
Invoke(new Action(() => Close()));
|
||||
}
|
||||
|
||||
public bool IsFullscreen
|
||||
{
|
||||
get { return WindowState == FormWindowState.Maximized; }
|
||||
get => WindowState == FormWindowState.Maximized;
|
||||
}
|
||||
|
||||
void MpvChangeFullscreen(bool value)
|
||||
void mp_ChangeFullscreen(bool value)
|
||||
{
|
||||
BeginInvoke(new Action(() => ChangeFullscreen(value)));
|
||||
}
|
||||
@@ -171,19 +166,19 @@ namespace mpvnet
|
||||
case 0x0100: // WM_KEYDOWN
|
||||
case 0x0101: // WM_KEYUP
|
||||
case 0x020A: // WM_MOUSEWHEEL
|
||||
if (mpv.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mpv.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
||||
if (!IsMouseInOSC())
|
||||
mpv.CommandString("cycle fullscreen");
|
||||
mp.CommandString("cycle fullscreen");
|
||||
break;
|
||||
case 0x0214: // WM_SIZING
|
||||
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
||||
var r = rc;
|
||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||
float aspect = mpv.VideoSize.Width / (float)mpv.VideoSize.Height;
|
||||
float aspect = mp.VideoSize.Width / (float)mp.VideoSize.Height;
|
||||
int d_w = (int)(c_h * aspect - c_w);
|
||||
int d_h = (int)(c_w / aspect - c_h);
|
||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||
@@ -203,10 +198,10 @@ namespace mpvnet
|
||||
|
||||
void SetFormPosSize()
|
||||
{
|
||||
if (IsFullscreen || mpv.VideoSize.Width == 0) return;
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
var wa = Screen.GetWorkingArea(this);
|
||||
int h = (int)(wa.Height * 0.6);
|
||||
int w = (int)(h * mpv.VideoSize.Width / (float)mpv.VideoSize.Height);
|
||||
int w = (int)(h * mp.VideoSize.Width / (float)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var r = new Native.RECT(new Rectangle(0, 0, w, h));
|
||||
NativeHelp.AddWindowBorders(Handle, ref r);
|
||||
@@ -232,7 +227,7 @@ namespace mpvnet
|
||||
base.OnDragDrop(e);
|
||||
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
mpv.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
@@ -254,7 +249,7 @@ namespace mpvnet
|
||||
var p2 = PointToScreen(e.Location);
|
||||
|
||||
if (Math.Abs(p1.X - p2.X) < 10 && Math.Abs(p1.Y - p2.Y) < 10)
|
||||
mpv.Command("quit");
|
||||
mp.Command("quit");
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
@@ -262,19 +257,12 @@ namespace mpvnet
|
||||
base.OnMouseMove(e);
|
||||
|
||||
// send mouse command to make OSC show
|
||||
mpv.CommandString($"mouse {e.X} {e.Y}");
|
||||
mp.CommandString($"mouse {e.X} {e.Y}");
|
||||
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
CursorHelp.Show();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
IsCloseRequired = false;
|
||||
mpv.Command("quit");
|
||||
}
|
||||
|
||||
bool IsMouseInOSC()
|
||||
{
|
||||
return PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||
@@ -295,18 +283,27 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs ea)
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
mpv.Init();
|
||||
mpv.ObserveBoolProp("fullscreen", MpvChangeFullscreen);
|
||||
mpv.AfterShutdown += Mpv_AfterShutdown;
|
||||
mpv.VideoSizeChanged += Mpv_VideoSizeChanged;
|
||||
mpv.PlaybackRestart += mpv_PlaybackRestart;
|
||||
base.OnLoad(e);
|
||||
mp.Init();
|
||||
mp.ObserveBoolProp("fullscreen", mp_ChangeFullscreen);
|
||||
mp.Shutdown += mp_Shutdown;
|
||||
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
||||
mp.PlaybackRestart += mp_PlaybackRestart;
|
||||
}
|
||||
|
||||
private void MainForm_Activated(object sender, EventArgs ea)
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
|
||||
base.OnFormClosed(e);
|
||||
IsClosed = true;
|
||||
mp.Command("quit");
|
||||
|
||||
for (int i = 0; i < 99; i++)
|
||||
{
|
||||
if (mp.IsShutdownComplete) break;
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
84
mpv.net/MediaInfo.cs
Normal file
84
mpv.net/MediaInfo.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class MediaInfo : IDisposable
|
||||
{
|
||||
private IntPtr Handle;
|
||||
private static bool Loaded;
|
||||
|
||||
public MediaInfo(string sourcepath)
|
||||
{
|
||||
if (!Loaded)
|
||||
{
|
||||
if (LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
||||
throw new Exception("Failed to load MediaInfo.dll.");
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
Handle = MediaInfo_New();
|
||||
MediaInfo_Open(Handle, sourcepath);
|
||||
}
|
||||
|
||||
public string GetInfo(MediaInfoStreamKind streamKind, string parameter)
|
||||
{
|
||||
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, streamKind, 0, parameter, MediaInfoInfoKind.Text, MediaInfoInfoKind.Name));
|
||||
}
|
||||
|
||||
private bool Disposed;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
Disposed = true;
|
||||
MediaInfo_Close(Handle);
|
||||
MediaInfo_Delete(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
~MediaInfo()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr LoadLibrary(string path);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
private static extern IntPtr MediaInfo_New();
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
private static extern void MediaInfo_Delete(IntPtr Handle);
|
||||
|
||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int MediaInfo_Open(IntPtr Handle, string FileName);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
private static extern int MediaInfo_Close(IntPtr Handle);
|
||||
|
||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr MediaInfo_Get(IntPtr Handle, MediaInfoStreamKind StreamKind, int StreamNumber, string Parameter, MediaInfoInfoKind KindOfInfo, MediaInfoInfoKind KindOfSearch);
|
||||
}
|
||||
|
||||
public enum MediaInfoStreamKind
|
||||
{
|
||||
General,
|
||||
Video,
|
||||
Audio,
|
||||
Text,
|
||||
Chapters,
|
||||
Image
|
||||
}
|
||||
|
||||
public enum MediaInfoInfoKind
|
||||
{
|
||||
Name,
|
||||
Text,
|
||||
Measure,
|
||||
Options,
|
||||
NameText,
|
||||
MeasureText,
|
||||
Info,
|
||||
HowTo
|
||||
}
|
||||
508
mpv.net/Menu.cs
Normal file
508
mpv.net/Menu.cs
Normal file
@@ -0,0 +1,508 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using Microsoft.Win32;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
public class ContextMenuStripEx : ContextMenuStrip
|
||||
{
|
||||
public ContextMenuStripEx()
|
||||
{
|
||||
}
|
||||
|
||||
public ContextMenuStripEx(IContainer container) : base(container)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnHandleCreated(EventArgs e)
|
||||
{
|
||||
base.OnHandleCreated(e);
|
||||
Renderer = new ToolStripRendererEx();
|
||||
}
|
||||
|
||||
public ActionMenuItem Add(string path)
|
||||
{
|
||||
return Add(path, null);
|
||||
}
|
||||
|
||||
public ActionMenuItem Add(string path, Action action)
|
||||
{
|
||||
return Add(path, action, true);
|
||||
}
|
||||
|
||||
public ActionMenuItem Add(string path, Action action, bool enabled)
|
||||
{
|
||||
var ret = ActionMenuItem.Add(Items, path, action);
|
||||
if (ret == null)
|
||||
return null;
|
||||
ret.Enabled = enabled;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ActionMenuItem Add(string path, Action action, Func<bool> enabledFunc)
|
||||
{
|
||||
var ret = ActionMenuItem.Add(Items, path, action);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public class ActionMenuItem : MenuItemEx
|
||||
{
|
||||
private Action Action;
|
||||
|
||||
public ActionMenuItem()
|
||||
{
|
||||
}
|
||||
|
||||
public ActionMenuItem(string text, Action action)
|
||||
{
|
||||
this.Text = text;
|
||||
this.Action = action;
|
||||
}
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
Application.DoEvents();
|
||||
if (Action != null)
|
||||
Action();
|
||||
base.OnClick(e);
|
||||
}
|
||||
|
||||
public static ActionMenuItem Add<T>(ToolStripItemCollection items, string path, Action<T> action, T value)
|
||||
{
|
||||
return Add(items, path, () => action(value));
|
||||
}
|
||||
|
||||
public static ActionMenuItem Add(ToolStripItemCollection items, string path, Action action)
|
||||
{
|
||||
var a = path.Split(new[] { " > ", " | " }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var l = items;
|
||||
|
||||
for (var x = 0; x <= a.Length - 1; x++)
|
||||
{
|
||||
var found = false;
|
||||
|
||||
foreach (var i in l.OfType<ToolStripMenuItem>())
|
||||
{
|
||||
if (x < a.Length - 1)
|
||||
{
|
||||
if (i.Text == a[x] + " ")
|
||||
{
|
||||
found = true;
|
||||
l = i.DropDownItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (x == a.Length - 1)
|
||||
{
|
||||
if (a[x] == "-")
|
||||
l.Add(new ToolStripSeparator());
|
||||
else
|
||||
{
|
||||
ActionMenuItem item = new ActionMenuItem(a[x] + " ", action);
|
||||
l.Add(item);
|
||||
l = item.DropDownItems;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionMenuItem item = new ActionMenuItem();
|
||||
item.Text = a[x] + " ";
|
||||
l.Add(item);
|
||||
l = item.DropDownItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class MenuItemEx : ToolStripMenuItem
|
||||
{
|
||||
public static bool UseTooltips { get; set; }
|
||||
|
||||
public MenuItemEx()
|
||||
{
|
||||
}
|
||||
|
||||
public MenuItemEx(string text) : base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override Size GetPreferredSize(Size constrainingSize)
|
||||
{
|
||||
var ret = base.GetPreferredSize(constrainingSize);
|
||||
ret.Height = Convert.ToInt32(Font.Height * 1.4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void CloseAll(object item)
|
||||
{
|
||||
if (item is ToolStripItem)
|
||||
{
|
||||
var d = (ToolStripItem)item;
|
||||
CloseAll(d.Owner);
|
||||
}
|
||||
|
||||
if (item is ToolStripDropDown)
|
||||
{
|
||||
var d = (ToolStripDropDown)item;
|
||||
d.Close();
|
||||
CloseAll(d.OwnerItem);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
Application.DoEvents();
|
||||
base.OnClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
public class ToolStripRendererEx : ToolStripSystemRenderer
|
||||
{
|
||||
public static Color ColorChecked { get; set; }
|
||||
public static Color ColorBorder { get; set; }
|
||||
public static Color ColorTop { get; set; }
|
||||
public static Color ColorBottom { get; set; }
|
||||
public static Color ColorBackground { get; set; }
|
||||
|
||||
public static Color ColorToolStrip1 { get; set; }
|
||||
public static Color ColorToolStrip2 { get; set; }
|
||||
public static Color ColorToolStrip3 { get; set; }
|
||||
public static Color ColorToolStrip4 { get; set; }
|
||||
|
||||
private int TextOffset;
|
||||
|
||||
public ToolStripRendererEx()
|
||||
{
|
||||
var argb = Convert.ToInt32(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", 0));
|
||||
if (argb == 0)
|
||||
argb = Color.LightBlue.ToArgb();
|
||||
InitColors(Color.FromArgb(argb));
|
||||
}
|
||||
|
||||
public static void InitColors(Color c)
|
||||
{
|
||||
ColorBorder = HSLColor.Convert(c).ToColorSetLuminosity(100);
|
||||
ColorChecked = HSLColor.Convert(c).ToColorSetLuminosity(200);
|
||||
ColorBottom = HSLColor.Convert(c).ToColorSetLuminosity(220);
|
||||
ColorBackground = HSLColor.Convert(c).ToColorSetLuminosity(230);
|
||||
ColorTop = HSLColor.Convert(c).ToColorSetLuminosity(240);
|
||||
|
||||
ColorToolStrip1 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 1)));
|
||||
ColorToolStrip2 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.7f)));
|
||||
ColorToolStrip3 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.1f)));
|
||||
ColorToolStrip4 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.4f)));
|
||||
}
|
||||
|
||||
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
|
||||
{
|
||||
ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, Color.FromArgb(160, 175, 195), ButtonBorderStyle.Solid);
|
||||
}
|
||||
|
||||
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
|
||||
{
|
||||
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
if (e.Item is ToolStripMenuItem && !(e.Item.Owner is MenuStrip))
|
||||
{
|
||||
var r = e.TextRectangle;
|
||||
|
||||
var dropDown = e.ToolStrip as ToolStripDropDownMenu;
|
||||
|
||||
if (dropDown == null || dropDown.ShowImageMargin || dropDown.ShowCheckMargin)
|
||||
TextOffset = Convert.ToInt32(e.Item.Height * 1.1);
|
||||
else
|
||||
TextOffset = Convert.ToInt32(e.Item.Height * 0.2);
|
||||
|
||||
e.TextRectangle = new Rectangle(TextOffset, Convert.ToInt32((e.Item.Height - r.Height) / 2.0), r.Width, r.Height);
|
||||
}
|
||||
|
||||
base.OnRenderItemText(e);
|
||||
}
|
||||
|
||||
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
|
||||
{
|
||||
if (!(e.ToolStrip is ToolStripDropDownMenu) && !(e.ToolStrip.LayoutStyle == ToolStripLayoutStyle.VerticalStackWithOverflow))
|
||||
{
|
||||
Rectangle r = new Rectangle(-1, -1, e.AffectedBounds.Width, e.AffectedBounds.Height);
|
||||
|
||||
using (SolidBrush b = new SolidBrush(ColorToolStrip2))
|
||||
{
|
||||
e.Graphics.FillRectangle(b, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
|
||||
{
|
||||
e.Item.ForeColor = Color.Black;
|
||||
|
||||
var r = new Rectangle(Point.Empty, e.Item.Size);
|
||||
var g = e.Graphics;
|
||||
|
||||
if (!(e.Item.Owner is MenuStrip))
|
||||
g.Clear(ColorBackground);
|
||||
|
||||
if (e.Item.Selected && e.Item.Enabled)
|
||||
{
|
||||
if (e.Item.Owner is MenuStrip)
|
||||
DrawButton(e);
|
||||
else
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
var r2 = new Rectangle(r.X + 2, r.Y, r.Width - 4, r.Height - 1);
|
||||
|
||||
using (Pen pen = new Pen(ColorBorder))
|
||||
{
|
||||
g.DrawRectangle(pen, r2);
|
||||
}
|
||||
|
||||
r2.Inflate(-1, -1);
|
||||
|
||||
using (SolidBrush b = new SolidBrush(ColorBottom))
|
||||
{
|
||||
g.FillRectangle(b, r2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawButton(ToolStripItemRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
var r = new Rectangle(Point.Empty, e.Item.Size);
|
||||
var r2 = new Rectangle(r.X, r.Y, r.Width - 1, r.Height - 1);
|
||||
|
||||
using (Pen pen = new Pen(ColorBorder))
|
||||
{
|
||||
g.DrawRectangle(pen, r2);
|
||||
}
|
||||
|
||||
r2.Inflate(-1, -1);
|
||||
|
||||
var tsb = e.Item as ToolStripButton;
|
||||
|
||||
if (!(tsb == null) && tsb.Checked)
|
||||
{
|
||||
using (SolidBrush brush = new SolidBrush(ColorChecked))
|
||||
{
|
||||
g.FillRectangle(brush, r2);
|
||||
}
|
||||
}
|
||||
else
|
||||
using (SolidBrush brush = new SolidBrush(ColorBottom))
|
||||
{
|
||||
g.FillRectangle(brush, r2);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e)
|
||||
{
|
||||
if (e.Item.Selected)
|
||||
DrawButton(e);
|
||||
}
|
||||
|
||||
protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e)
|
||||
{
|
||||
var button = (ToolStripButton)e.Item;
|
||||
if (e.Item.Selected || button.Checked)
|
||||
DrawButton(e);
|
||||
}
|
||||
|
||||
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
|
||||
{
|
||||
var value = e.Direction == ArrowDirection.Down ? 0x36 : 0x34;
|
||||
var s = Convert.ToChar(value).ToString();
|
||||
var font = new Font("Marlett", e.Item.Font.Size - 2);
|
||||
var size = e.Graphics.MeasureString(s, font);
|
||||
var x = Convert.ToInt32(e.Item.Width - size.Width);
|
||||
var y = Convert.ToInt32((e.Item.Height - size.Height) / 2.0) + 1;
|
||||
e.Graphics.DrawString(s, font, Brushes.Black, x, y);
|
||||
}
|
||||
|
||||
protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e)
|
||||
{
|
||||
var x = Convert.ToInt32(e.ImageRectangle.Height * 0.2);
|
||||
e.Graphics.DrawImage(e.Image, new Point(x, x));
|
||||
}
|
||||
|
||||
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
|
||||
{
|
||||
if (e.Item.IsOnDropDown)
|
||||
{
|
||||
e.Graphics.Clear(ColorBackground);
|
||||
var right = e.Item.Width - Convert.ToInt32(TextOffset / 5.0);
|
||||
var top = e.Item.Height / 2;
|
||||
top -= 1;
|
||||
var b = e.Item.Bounds;
|
||||
|
||||
using (Pen p = new Pen(Color.Gray))
|
||||
{
|
||||
e.Graphics.DrawLine(p, new Point(TextOffset, top), new Point(right, top));
|
||||
}
|
||||
}
|
||||
else if (e.Vertical)
|
||||
{
|
||||
var b = e.Item.Bounds;
|
||||
|
||||
using (Pen p = new Pen(SystemColors.ControlDarkDark))
|
||||
{
|
||||
e.Graphics.DrawLine(p,
|
||||
Convert.ToInt32(b.Width / 2.0),
|
||||
Convert.ToInt32(b.Height * 0.15),
|
||||
Convert.ToInt32(b.Width / 2.0),
|
||||
Convert.ToInt32(b.Height * 0.85));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct HSLColor
|
||||
{
|
||||
public HSLColor(Color color) : this()
|
||||
{
|
||||
SetRGB(color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public HSLColor(int h, int s, int l) : this()
|
||||
{
|
||||
Hue = h;
|
||||
Saturation = s;
|
||||
Luminosity = l;
|
||||
}
|
||||
|
||||
private double hue;
|
||||
|
||||
public int Hue {
|
||||
get => System.Convert.ToInt32(hue * 240);
|
||||
set => hue = CheckRange(value / 240.0);
|
||||
}
|
||||
|
||||
private double saturation;
|
||||
|
||||
public int Saturation {
|
||||
get => System.Convert.ToInt32(saturation * 240);
|
||||
set => saturation = CheckRange(value / 240.0);
|
||||
}
|
||||
|
||||
private double luminosity;
|
||||
|
||||
public int Luminosity {
|
||||
get => System.Convert.ToInt32(luminosity * 240);
|
||||
set => luminosity = CheckRange(value / 240.0);
|
||||
}
|
||||
|
||||
private double CheckRange(double value)
|
||||
{
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
else if (value > 1)
|
||||
value = 1;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public Color ToColorAddLuminosity(int luminosity)
|
||||
{
|
||||
Luminosity += luminosity;
|
||||
return ToColor();
|
||||
}
|
||||
|
||||
public Color ToColorSetLuminosity(int luminosity)
|
||||
{
|
||||
Luminosity = luminosity;
|
||||
return ToColor();
|
||||
}
|
||||
|
||||
public Color ToColor()
|
||||
{
|
||||
double r = 0, g = 0, b = 0;
|
||||
|
||||
if (luminosity != 0)
|
||||
{
|
||||
if (saturation == 0)
|
||||
{
|
||||
b = luminosity;
|
||||
g = luminosity;
|
||||
r = luminosity;
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp2 = GetTemp2(this);
|
||||
var temp1 = 2.0 * luminosity - temp2;
|
||||
|
||||
r = GetColorComponent(temp1, temp2, hue + 1.0 / 3.0);
|
||||
g = GetColorComponent(temp1, temp2, hue);
|
||||
b = GetColorComponent(temp1, temp2, hue - 1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
return Color.FromArgb(
|
||||
System.Convert.ToInt32(255 * r),
|
||||
System.Convert.ToInt32(255 * g),
|
||||
System.Convert.ToInt32(255 * b));
|
||||
}
|
||||
|
||||
private static double GetColorComponent(double temp1, double temp2, double temp3)
|
||||
{
|
||||
temp3 = MoveIntoRange(temp3);
|
||||
|
||||
if (temp3 < 1 / 6.0)
|
||||
return temp1 + (temp2 - temp1) * 6.0 * temp3;
|
||||
else if (temp3 < 0.5)
|
||||
return temp2;
|
||||
else if (temp3 < 2 / 3.0)
|
||||
return temp1 + ((temp2 - temp1) * (2 / 3.0 - temp3) * 6);
|
||||
else
|
||||
return temp1;
|
||||
}
|
||||
|
||||
private static double MoveIntoRange(double temp3)
|
||||
{
|
||||
if (temp3 < 0)
|
||||
temp3 += 1;
|
||||
else if (temp3 > 1)
|
||||
temp3 -= 1;
|
||||
|
||||
return temp3;
|
||||
}
|
||||
|
||||
private static double GetTemp2(HSLColor hslColor)
|
||||
{
|
||||
double temp2;
|
||||
|
||||
if (hslColor.luminosity < 0.5)
|
||||
temp2 = hslColor.luminosity * (1.0 + hslColor.saturation);
|
||||
else
|
||||
temp2 = hslColor.luminosity + hslColor.saturation - (hslColor.luminosity * hslColor.saturation);
|
||||
|
||||
return temp2;
|
||||
}
|
||||
|
||||
public static HSLColor Convert(Color c)
|
||||
{
|
||||
HSLColor r = new HSLColor();
|
||||
r.hue = c.GetHue() / 360.0;
|
||||
r.luminosity = c.GetBrightness();
|
||||
r.saturation = c.GetSaturation();
|
||||
return r;
|
||||
}
|
||||
|
||||
public void SetRGB(int red, int green, int blue)
|
||||
{
|
||||
var hc = HSLColor.Convert(Color.FromArgb(red, green, blue));
|
||||
hue = hc.hue;
|
||||
saturation = hc.saturation;
|
||||
luminosity = hc.luminosity;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -24,4 +25,22 @@ namespace mpvnet
|
||||
int IComparerOfString_Compare(string x, string y) => StrCmpLogical(x, y);
|
||||
int IComparer<string>.Compare(string x, string y) => IComparerOfString_Compare(x, y);
|
||||
}
|
||||
|
||||
public class StaticUsing
|
||||
{
|
||||
public static void MsgInfo(string message)
|
||||
{
|
||||
MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
public static void MsgError(string message)
|
||||
{
|
||||
MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
public static DialogResult MsgQuestion(string message)
|
||||
{
|
||||
return MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,17 +61,17 @@ namespace mpvnet
|
||||
|
||||
public Size Size
|
||||
{
|
||||
get { return new Size(Right - Left, Bottom - Top); }
|
||||
get => new Size(Right - Left, Bottom - Top);
|
||||
}
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return Right - Left; }
|
||||
get => Right - Left;
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return Bottom - Top; }
|
||||
get => Bottom - Top;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.2.5.0")]
|
||||
[assembly: AssemblyFileVersion("0.2.5.0")]
|
||||
[assembly: AssemblyVersion("1.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||
@@ -61,19 +61,6 @@ namespace mpvnet.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
///#key command key caption menu path/caption
|
||||
///
|
||||
///o script-message mpv.net open-files #menu: O; Open Files
|
||||
///
|
||||
///Space cycle pause #menu: Space ; Play/Pause
|
||||
///s stop #menu: S ; Stop
|
||||
///
|
||||
///F11 playlist-prev #menu: F11 ; Navigate | Previous
|
||||
///F12 playlist-next #menu: F12 ; Navigate | Next
|
||||
///
|
||||
///Ctrl++ add video-zoom 0.1 #menu: Ctrl++ ; Pan && Scan | Increase Size
|
||||
///Ctrl+- add video-zoom -0.1 #menu: Ct [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string input_conf {
|
||||
get {
|
||||
@@ -81,4 +68,4 @@ namespace mpvnet.Properties {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
mpv.net/PyScript.cs
Normal file
33
mpv.net/PyScript.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
using IronPython.Hosting;
|
||||
using Microsoft.Scripting.Hosting;
|
||||
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class PyScript
|
||||
{
|
||||
ScriptEngine engine;
|
||||
ScriptScope scope;
|
||||
|
||||
public PyScript(string code)
|
||||
{
|
||||
try
|
||||
{
|
||||
engine = Python.CreateEngine();
|
||||
scope = engine.CreateScope();
|
||||
scope.ImportModule("clr");
|
||||
engine.Execute("import clr", scope);
|
||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||
engine.Execute("from mpvnet import *", scope);
|
||||
engine.Execute(code, scope);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MsgError(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
140
mpv.net/Resources/input_conf.txt
Normal file
140
mpv.net/Resources/input_conf.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
# mpv.net key bindings, mouse bindings and context menu configuration
|
||||
|
||||
o script-message mpv.net open-files #menu: O ; Open Files...
|
||||
_ ignore #menu: _ ; -
|
||||
Space cycle pause #menu: Space, Enter ; Play/Pause
|
||||
Enter cycle pause
|
||||
s stop #menu: S ; Stop
|
||||
_ ignore #menu: _ ; -
|
||||
f cycle fullscreen #menu: F ; Toggle Fullscreen
|
||||
|
||||
F11 playlist-prev #menu: F11 ; Navigate > Previous
|
||||
F12 playlist-next #menu: F12 ; Navigate > Next
|
||||
_ ignore #menu: _ ; Navigate > -
|
||||
PGUP add chapter 1 #menu: Page Up ; Navigate > Next Chapter
|
||||
PGDWN add chapter -1 #menu: Page Down ; Navigate > Previous Chapter
|
||||
|
||||
. frame-step #menu: . ; Seek > Next Frame
|
||||
, frame-back-step #menu: , ; Seek > Previous Frame
|
||||
_ ignore #menu: _ ; Seek > -
|
||||
Right no-osd seek 7 #menu: Right ; Seek > 7 sec forward
|
||||
Left no-osd seek -7 #menu: Left ; Seek > 7 sec backward
|
||||
_ ignore #menu: _ ; Seek > -
|
||||
Up no-osd seek 40 #menu: Up ; Seek > 40 sec forward
|
||||
Down no-osd seek -40 #menu: Down ; Seek > 40 sec backward
|
||||
_ ignore #menu: _ ; Seek > -
|
||||
Ctrl+Right no-osd seek 300 #menu: Ctrl+Right ; Seek > 5 min forward
|
||||
Ctrl+Left no-osd seek -300 #menu: Ctrl+Left ; Seek > 5 min backward
|
||||
|
||||
Ctrl++ add video-zoom 0.1 #menu: Ctrl++ ; Pan && Scan > Increase Size
|
||||
Ctrl+- add video-zoom -0.1 #menu: Ctrl+- ; Pan && Scan > Decrease Size
|
||||
_ ignore #menu: _ ; Pan && Scan > -
|
||||
Shift+Left add video-pan-x -0.01 #menu: Shift+Left ; Pan && Scan > Move Left
|
||||
Shift+Right add video-pan-x 0.01 #menu: Shift+Right ; Pan && Scan > Move Right
|
||||
_ ignore #menu: _ ; Pan && Scan > -
|
||||
Shift+Up add video-pan-y -0.01 #menu: Shift+Up ; Pan && Scan > Move Up
|
||||
Shift+Down add video-pan-y 0.01 #menu: Shift+Down ; Pan && Scan > Move Down
|
||||
_ ignore #menu: _ ; Pan && Scan > -
|
||||
w add panscan -0.1 #menu: W ; Pan && Scan > Decrease Height
|
||||
W add panscan +0.1 #menu: Shift+W ; Pan && Scan > Increase Height
|
||||
_ ignore #menu: _ ; Pan && Scan > -
|
||||
Shift+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0 #menu: Alt+Backspace ; Pan && Scan > Reset
|
||||
|
||||
Ctrl+1 add contrast -1 #menu: Ctrl+1 ; Video > Decrease Contrast
|
||||
Ctrl+2 add contrast 1 #menu: Ctrl+2 ; Video > Increase Contrast
|
||||
_ ignore #menu: _ ; Video > -
|
||||
Ctrl+3 add brightness -1 #menu: Ctrl+3 ; Video > Decrease Brightness
|
||||
Ctrl+4 add brightness 1 #menu: Ctrl+4 ; Video > Increase Brightness
|
||||
_ ignore #menu: _ ; Video > -
|
||||
Ctrl+5 add gamma -1 #menu: Ctrl+5 ; Video > Decrease Gamma
|
||||
Ctrl+6 add gamma 1 #menu: Ctrl+6 ; Video > Increase Gamma
|
||||
_ ignore #menu: _ ; Video > -
|
||||
Ctrl+7 add saturation -1 #menu: Ctrl+7 ; Video > Decrease Saturation
|
||||
Ctrl+8 add saturation 1 #menu: Ctrl+8 ; Video > Increase Saturation
|
||||
_ ignore #menu: _ ; Video > -
|
||||
Ctrl+S async screenshot #menu: Ctrl+S ; Video > Take Screenshot
|
||||
Ctrl+Shift+S screenshot each-frame #menu: Ctrl+Shift+S ; Video > Take Screenshots All Frames
|
||||
_ ignore #menu: _ ; Video > -
|
||||
d cycle deinterlace #menu: D ; Video > Toggle Deinterlace
|
||||
a cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1" #menu: A ; Video > Cycle Aspect Ratio
|
||||
|
||||
KP7 cycle audio #menu: Keypad 7 ; Audio > Cycle/Next
|
||||
_ ignore #menu: _ ; Audio > -
|
||||
KP6 add audio-delay 0.100 #menu: Keypad 6 ; Audio > Delay +0.1
|
||||
KP9 add audio-delay -0.100 #menu: Keypad 9 ; Audio > Delay -0.1
|
||||
|
||||
KP8 cycle sub #menu: Keypad 8 ; Subtitle > Cycle/Next
|
||||
v cycle sub-visibility #menu: V ; Subtitle > Toggle Visibility
|
||||
_ ignore #menu: _ ; Subtitle > -
|
||||
z add sub-delay -0.1 #menu: Z ; Subtitle > Delay -0.1
|
||||
Z add sub-delay +0.1 #menu: Shift+Z ; Subtitle > Delay +0.1
|
||||
_ ignore #menu: _ ; Subtitle > -
|
||||
r add sub-pos -1 #menu: R ; Subtitle > Move Up
|
||||
R add sub-pos +1 #menu: Shift+R ; Subtitle > Move Down
|
||||
_ ignore #menu: _ ; Subtitle > -
|
||||
_ add sub-scale -0.1 #menu: _ ; Subtitle > Decrease Subtitle Font Size
|
||||
_ add sub-scale +0.1 #menu: _ ; Subtitle > Increase Subtitle Font Size
|
||||
_ ignore #menu: _ ; Subtitle > -
|
||||
|
||||
+ add volume 10 #menu: + ; Volume > Up
|
||||
- add volume -10 #menu: - ; Volume > Down
|
||||
WHEEL_UP add volume 10
|
||||
WHEEL_DOWN add volume -10
|
||||
_ ignore #menu: _ ; Volume > -
|
||||
m cycle mute #menu: M ; Volume > Mute
|
||||
|
||||
[ multiply speed 0.9 #menu: [ ; Speed > -10%
|
||||
] multiply speed 1.1 #menu: ] ; Speed > +10%
|
||||
_ ignore #menu: _ ; Speed > -
|
||||
{ multiply speed 0.5 #menu: { ; Speed > Half
|
||||
} multiply speed 2.0 #menu: } ; Speed > Double
|
||||
_ ignore #menu: _ ; Speed > -
|
||||
BS set speed 1 #menu: Backspace ; Speed > Reset
|
||||
|
||||
KP0 script-message rate-file 0 #menu: Keypad 0 ; Addons > Rating > 0stars
|
||||
KP1 script-message rate-file 1 #menu: Keypad 1 ; Addons > Rating > 1stars
|
||||
KP2 script-message rate-file 2 #menu: Keypad 2 ; Addons > Rating > 2stars
|
||||
KP3 script-message rate-file 3 #menu: Keypad 3 ; Addons > Rating > 3stars
|
||||
KP4 script-message rate-file 4 #menu: Keypad 4 ; Addons > Rating > 4stars
|
||||
KP5 script-message rate-file 5 #menu: Keypad 5 ; Addons > Rating > 5stars
|
||||
|
||||
_ script-message mpv.net set-setting hwdec yes #menu: _ ; Settings > Hardware Decoding > Enable
|
||||
_ script-message mpv.net set-setting hwdec no #menu: _ ; Settings > Hardware Decoding > Disable
|
||||
p script-message mpv.net show-prefs #menu: P ; Settings > Show Preferences
|
||||
k script-message mpv.net show-keys #menu: K ; Settings > Show Keys
|
||||
c script-message mpv.net open-config-folder #menu: C ; Settings > Open Config Folder
|
||||
|
||||
i script-message mpv.net show-info #menu: I ; Tools | Info
|
||||
t script-binding stats/display-stats #menu: T ; Tools > Show Statistics
|
||||
T script-binding stats/display-stats-toggle #menu: Shift+T ; Tools > Toggle Statistics
|
||||
_ ignore #menu: _ ; Tools > -
|
||||
h script-message mpv.net history #menu: H ; Tools > Show History
|
||||
l ab-loop #menu: L ; Tools > Set/clear A-B loop points
|
||||
L cycle-values loop-file "inf" "no" #menu: Shift+L ; Tools > Toggle Infinite Looping
|
||||
DEL script-binding osc/visibility #menu: Delete ; Tools > Toggle OSC Visibility
|
||||
Ctrl+H cycle-values hwdec "auto" "no" #menu: Ctrl+H ; Tools > Cycle Hardware Decoding
|
||||
F8 show-text ${playlist} 5000 #menu: F8 ; Tools > Show Playlist
|
||||
F9 show-text ${track-list} 5000 #menu: F9 ; Tools > Show Audio/Video/Subtitle List
|
||||
|
||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: _ ; Tools > Web > Show mpv manual
|
||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: _ ; Tools > Web > Show mpv default keys
|
||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpvnet #menu: _ ; Tools > Web > Show mpv.net web site
|
||||
_ ignore #menu: _ ; -
|
||||
Esc quit #menu: Escape ; Exit
|
||||
Q quit-watch-later #menu: Shift+Q ; Exit Watch Later
|
||||
|
||||
> playlist-next
|
||||
< playlist-prev
|
||||
|
||||
POWER quit
|
||||
PLAY cycle pause
|
||||
PAUSE cycle pause
|
||||
PLAYPAUSE cycle pause
|
||||
STOP quit
|
||||
FORWARD seek 60
|
||||
REWIND seek -60
|
||||
VOLUME_UP add volume 2
|
||||
VOLUME_DOWN add volume -2
|
||||
MUTE cycle mute
|
||||
CLOSE_WIN quit
|
||||
CLOSE_WIN {encode} quit 4
|
||||
120
mpv.net/StringExtensions.cs
Normal file
120
mpv.net/StringExtensions.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string ExtFull(this string filepath)
|
||||
{
|
||||
return Ext(filepath, true);
|
||||
}
|
||||
|
||||
public static string Ext(this string filepath)
|
||||
{
|
||||
return Ext(filepath, false);
|
||||
}
|
||||
|
||||
public static string Ext(this string filepath, bool dot)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filepath))
|
||||
return "";
|
||||
|
||||
var chars = filepath.ToCharArray();
|
||||
|
||||
for (var x = filepath.Length - 1; x >= 0; x += -1)
|
||||
{
|
||||
if (chars[x] == Path.DirectorySeparatorChar)
|
||||
return "";
|
||||
|
||||
if (chars[x] == '.')
|
||||
return filepath.Substring(x + (dot ? 0 : 1)).ToLower();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string Left(this string value, int index)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || index < 0)
|
||||
return "";
|
||||
|
||||
if (index > value.Length)
|
||||
return value;
|
||||
|
||||
return value.Substring(0, index);
|
||||
}
|
||||
|
||||
public static string Left(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(0, value.IndexOf(start));
|
||||
}
|
||||
|
||||
public static string LeftLast(this string value, string start)
|
||||
{
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(0, value.LastIndexOf(start));
|
||||
}
|
||||
|
||||
public static string Right(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(value.IndexOf(start) + start.Length);
|
||||
}
|
||||
|
||||
public static string RightLast(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(value.LastIndexOf(start) + start.Length);
|
||||
}
|
||||
|
||||
public static string[] SplitNoEmpty(this string value, params string[] delimiters)
|
||||
{
|
||||
return value.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public static string[] SplitKeepEmpty(this string value, params string[] delimiters)
|
||||
{
|
||||
return value.Split(delimiters, StringSplitOptions.None);
|
||||
}
|
||||
|
||||
public static string[] SplitNoEmptyAndWhiteSpace(this string value, params string[] delimiters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return null;
|
||||
|
||||
var a = SplitNoEmpty(value, delimiters);
|
||||
|
||||
for (var i = 0; i <= a.Length - 1; i++)
|
||||
a[i] = a[i].Trim();
|
||||
|
||||
var l = a.ToList();
|
||||
|
||||
while (l.Contains(""))
|
||||
l.Remove("");
|
||||
|
||||
return l.ToArray();
|
||||
}
|
||||
|
||||
public static string[] SplitLinesNoEmpty(this string value)
|
||||
{
|
||||
return SplitNoEmpty(value, Environment.NewLine);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,9 @@ namespace mpvnet
|
||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref IntPtr data);
|
||||
|
||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref double data);
|
||||
|
||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref byte[] data);
|
||||
|
||||
@@ -102,7 +105,8 @@ namespace mpvnet
|
||||
MPV_EVENT_PLAYBACK_RESTART = 21,
|
||||
MPV_EVENT_PROPERTY_CHANGE = 22,
|
||||
MPV_EVENT_CHAPTER_CHANGE = 23,
|
||||
MPV_EVENT_QUEUE_OVERFLOW = 24
|
||||
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
||||
MPV_EVENT_HOOK = 25
|
||||
}
|
||||
|
||||
public enum mpv_format
|
||||
@@ -131,7 +135,16 @@ namespace mpvnet
|
||||
MPV_LOG_LEVEL_TRACE = 70,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public enum mpv_end_file_reason
|
||||
{
|
||||
MPV_END_FILE_REASON_EOF = 0,
|
||||
MPV_END_FILE_REASON_STOP = 2,
|
||||
MPV_END_FILE_REASON_QUIT = 3,
|
||||
MPV_END_FILE_REASON_ERROR = 4,
|
||||
MPV_END_FILE_REASON_REDIRECT = 5
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct mpv_event_log_message
|
||||
{
|
||||
public string prefix;
|
||||
@@ -159,9 +172,16 @@ namespace mpvnet
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct mpv_event_property
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPUTF8Str)] public string name;
|
||||
public string name;
|
||||
public mpv_format format;
|
||||
public IntPtr data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct mpv_event_end_file
|
||||
{
|
||||
public int reason;
|
||||
public int error;
|
||||
}
|
||||
}
|
||||
}
|
||||
553
mpv.net/mp.cs
Normal file
553
mpv.net/mp.cs
Normal file
@@ -0,0 +1,553 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using static mpvnet.libmpv;
|
||||
using static mpvnet.Native;
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
using PyRT = IronPython.Runtime;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
||||
|
||||
public class mp
|
||||
{
|
||||
public static event Action VideoSizeChanged;
|
||||
// Lua/JS evens libmpv events
|
||||
|
||||
// MPV_EVENT_NONE
|
||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||
public static event Action LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
||||
public static event Action GetPropertyReply; // get-property-reply MPV_EVENT_GET_PROPERTY_REPLY
|
||||
public static event Action SetPropertyReply; // set-property-reply MPV_EVENT_SET_PROPERTY_REPLY
|
||||
public static event Action CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
||||
public static event Action StartFile; // start-file MPV_EVENT_START_FILE
|
||||
public static event Action<EndFileEventMode> EndFile; // end-file MPV_EVENT_END_FILE
|
||||
public static event Action FileLoaded; // file-loaded MPV_EVENT_FILE_LOADED
|
||||
public static event Action TracksChanged; // MPV_EVENT_TRACKS_CHANGED
|
||||
public static event Action TrackSwitched; // MPV_EVENT_TRACK_SWITCHED
|
||||
public static event Action Idle; // idle MPV_EVENT_IDLE
|
||||
public static event Action Pause; // MPV_EVENT_PAUSE
|
||||
public static event Action Unpause; // MPV_EVENT_UNPAUSE
|
||||
public static event Action Tick; // tick MPV_EVENT_TICK
|
||||
public static event Action ScriptInputDispatch; // MPV_EVENT_SCRIPT_INPUT_DISPATCH
|
||||
public static event Action<string[]> ClientMessage; // client-message MPV_EVENT_CLIENT_MESSAGE
|
||||
public static event Action VideoReconfig; // video-reconfig MPV_EVENT_VIDEO_RECONFIG
|
||||
public static event Action AudioReconfig; // audio-reconfig MPV_EVENT_AUDIO_RECONFIG
|
||||
public static event Action MetadataUpdate; // MPV_EVENT_METADATA_UPDATE
|
||||
public static event Action Seek; // seek MPV_EVENT_SEEK
|
||||
public static event Action PlaybackRestart; // playback-restart MPV_EVENT_PLAYBACK_RESTART
|
||||
// MPV_EVENT_PROPERTY_CHANGE
|
||||
public static event Action ChapterChange; // MPV_EVENT_CHAPTER_CHANGE
|
||||
public static event Action QueueOverflow; // MPV_EVENT_QUEUE_OVERFLOW
|
||||
public static event Action Hook; // MPV_EVENT_HOOK
|
||||
|
||||
public static IntPtr MpvHandle;
|
||||
public static IntPtr MpvWindowHandle;
|
||||
public static Addon Addon;
|
||||
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions = new List<KeyValuePair<string, Action<bool>>>();
|
||||
public static Size VideoSize = new Size(1920, 1080);
|
||||
public static string mpvConfFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
||||
public static string InputConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf";
|
||||
public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf";
|
||||
public static List<PyScript> PyScripts { get; } = new List<PyScript>();
|
||||
public static bool IsShutdownComplete { get; set; }
|
||||
|
||||
private static Dictionary<string, string> _mpvConv;
|
||||
|
||||
public static Dictionary<string, string> mpvConv {
|
||||
get {
|
||||
if (_mpvConv == null)
|
||||
{
|
||||
_mpvConv = new Dictionary<string, string>();
|
||||
|
||||
if (File.Exists(mpvConfPath))
|
||||
{
|
||||
foreach (var i in File.ReadAllLines(mpvConfPath))
|
||||
{
|
||||
if (i.Contains("=") && ! i.StartsWith("#"))
|
||||
{
|
||||
_mpvConv[i.Left("=").Trim()] = i.Right("=").Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _mpvConv;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
LoadLibrary("mpv-1.dll");
|
||||
MpvHandle = mpv_create();
|
||||
SetIntProp("input-ar-delay", 500);
|
||||
SetIntProp("input-ar-rate", 20);
|
||||
SetIntProp("volume", 50);
|
||||
SetStringProp("hwdec", "yes");
|
||||
SetStringProp("vo", "direct3d");
|
||||
SetStringProp("input-default-bindings", "yes");
|
||||
SetStringProp("osd-playing-msg", "'${filename}'");
|
||||
SetStringProp("screenshot-directory", "~~desktop/");
|
||||
SetStringProp("keep-open", "yes");
|
||||
SetStringProp("keep-open-pause", "no");
|
||||
SetStringProp("osc", "yes");
|
||||
SetStringProp("config", "yes");
|
||||
SetStringProp("wid", MainForm.Hwnd.ToString());
|
||||
SetStringProp("force-window", "yes");
|
||||
mpv_initialize(MpvHandle);
|
||||
ProcessCommandLine();
|
||||
Task.Run(() => { LoadScripts(); });
|
||||
Task.Run(() => { Addon = new Addon(); });
|
||||
Task.Run(() => { EventLoop(); });
|
||||
}
|
||||
|
||||
public static void LoadScripts()
|
||||
{
|
||||
string[] jsLua = { ".lua", ".js" };
|
||||
string[] startupScripts = Directory.GetFiles(Application.StartupPath + "\\Scripts");
|
||||
|
||||
foreach (var scriptPath in startupScripts)
|
||||
if (jsLua.Contains(Path.GetExtension(scriptPath).ToLower()))
|
||||
mp.Command("load-script", $"{scriptPath}");
|
||||
|
||||
foreach (var scriptPath in startupScripts)
|
||||
if (Path.GetExtension(scriptPath) == ".py")
|
||||
PyScripts.Add(new PyScript(File.ReadAllText(scriptPath)));
|
||||
|
||||
foreach(var scriptPath in Directory.GetFiles(mp.mpvConfFolderPath + "scripts", "*.py"))
|
||||
PyScripts.Add(new PyScript(File.ReadAllText(scriptPath)));
|
||||
}
|
||||
|
||||
public static void EventLoop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr ptr = mpv_wait_event(MpvHandle, -1);
|
||||
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
||||
|
||||
if (MpvWindowHandle == IntPtr.Zero)
|
||||
MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||
|
||||
switch (evt.event_id)
|
||||
{
|
||||
case mpv_event_id.MPV_EVENT_SHUTDOWN:
|
||||
Shutdown?.Invoke();
|
||||
IsShutdownComplete = true;
|
||||
return;
|
||||
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
||||
LogMessage?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
||||
GetPropertyReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SET_PROPERTY_REPLY:
|
||||
SetPropertyReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_COMMAND_REPLY:
|
||||
CommandReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_START_FILE:
|
||||
StartFile?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_END_FILE:
|
||||
var end_fileData = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
||||
EndFile?.Invoke((EndFileEventMode)end_fileData.reason);
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||
FileLoaded?.Invoke();
|
||||
LoadFolder();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||
TracksChanged?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TRACK_SWITCHED:
|
||||
TrackSwitched?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_IDLE:
|
||||
Idle?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PAUSE:
|
||||
Pause?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_UNPAUSE:
|
||||
Unpause?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TICK:
|
||||
Tick?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SCRIPT_INPUT_DISPATCH:
|
||||
ScriptInputDispatch?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
||||
if (ClientMessage != null)
|
||||
{
|
||||
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
||||
var args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
|
||||
|
||||
if (args != null && args.Length > 1 && args[0] == "mpv.net")
|
||||
foreach (var i in mpvnet.Command.Commands)
|
||||
if (args[1] == i.Name)
|
||||
try
|
||||
{
|
||||
i.Action(args.Skip(2).ToArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MsgError(ex.GetType().Name + "\r\n\r\n" + ex.ToString());
|
||||
}
|
||||
ClientMessage?.Invoke(args);
|
||||
}
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
||||
VideoReconfig?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_AUDIO_RECONFIG:
|
||||
AudioReconfig?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_METADATA_UPDATE:
|
||||
MetadataUpdate?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SEEK:
|
||||
Seek?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||
var event_propertyData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||
|
||||
if (event_propertyData.format == mpv_format.MPV_FORMAT_FLAG)
|
||||
foreach (var i in BoolPropChangeActions)
|
||||
if (i.Key== event_propertyData.name)
|
||||
i.Value.Invoke(Marshal.PtrToStructure<int>(event_propertyData.data) == 1);
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||
PlaybackRestart?.Invoke();
|
||||
Size s = new Size(GetIntProp("dwidth", false), GetIntProp("dheight", false));
|
||||
|
||||
if (VideoSize != s && s != Size.Empty)
|
||||
{
|
||||
VideoSize = s;
|
||||
VideoSizeChanged?.Invoke();
|
||||
}
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_CHAPTER_CHANGE:
|
||||
ChapterChange?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_QUEUE_OVERFLOW:
|
||||
QueueOverflow?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_HOOK:
|
||||
Hook?.Invoke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventObject
|
||||
{
|
||||
public PyRT.PythonFunction PythonFunction { get; set; }
|
||||
public EventInfo EventInfo { get; set; }
|
||||
public Delegate Delegate { get; set; }
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction);
|
||||
}
|
||||
|
||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
|
||||
public void InvokeStrings(string[] arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
}
|
||||
|
||||
private static List<EventObject> EventObjects = new List<EventObject>();
|
||||
|
||||
public static void register_event(string name, PyRT.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||
{
|
||||
if (eventInfo.Name.ToLower() == name.Replace("-", ""))
|
||||
{
|
||||
EventObject eventObject = new EventObject();
|
||||
EventObjects.Add(eventObject);
|
||||
eventObject.PythonFunction = pyFunc;
|
||||
MethodInfo mi;
|
||||
|
||||
if (eventInfo.EventHandlerType == typeof(Action))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.Invoke));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeEndFileEventMode));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeStrings));
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
eventObject.EventInfo = eventInfo;
|
||||
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventObject, mi);
|
||||
eventObject.Delegate = handler;
|
||||
eventInfo.AddEventHandler(eventObject, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregister_event(PyRT.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventObjects in EventObjects)
|
||||
if (eventObjects.PythonFunction == pyFunc)
|
||||
eventObjects.EventInfo.RemoveEventHandler(eventObjects, eventObjects.Delegate);
|
||||
}
|
||||
|
||||
public static void commandv(params string[] args)
|
||||
{
|
||||
Command(args);
|
||||
}
|
||||
|
||||
public static void Command(params string[] args)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
IntPtr[] byteArrayPointers;
|
||||
var mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out byteArrayPointers);
|
||||
int err = mpv_command(MpvHandle, mainPtr);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{(mpv_error)err}");
|
||||
|
||||
foreach (var ptr in byteArrayPointers)
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
|
||||
Marshal.FreeHGlobal(mainPtr);
|
||||
}
|
||||
|
||||
public static void CommandString(string command, bool throwException = true)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
int err = mpv_command_string(MpvHandle, command);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{(mpv_error)err}\r\n\r\n" + command);
|
||||
}
|
||||
|
||||
public static void SetStringProp(string name, string value, bool throwException = true)
|
||||
{
|
||||
var bytes = GetUtf8Bytes(value);
|
||||
int err = mpv_set_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static string GetStringProp(string name)
|
||||
{
|
||||
var lpBuffer = IntPtr.Zero;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref lpBuffer);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
|
||||
var ret = StringFromNativeUtf8(lpBuffer);
|
||||
mpv_free(lpBuffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int GetIntProp(string name, bool throwException = true)
|
||||
{
|
||||
var lpBuffer = IntPtr.Zero;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref lpBuffer);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
return lpBuffer.ToInt32();
|
||||
}
|
||||
|
||||
public static double get_property_number(string name)
|
||||
{
|
||||
return GetDoubleProp(name);
|
||||
}
|
||||
|
||||
public static double GetDoubleProp(string name, bool throwException = true)
|
||||
{
|
||||
double val = 0;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
public static void SetIntProp(string name, int value)
|
||||
{
|
||||
Int64 val = value;
|
||||
int err = mpv_set_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static void ObserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
||||
}
|
||||
|
||||
public static void UnobserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
foreach (var i in BoolPropChangeActions.ToArray())
|
||||
if (i.Value == action)
|
||||
BoolPropChangeActions.Remove(i);
|
||||
|
||||
int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode());
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static void ProcessCommandLine()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||
|
||||
foreach (string i in args)
|
||||
if (!i.StartsWith("--") && File.Exists(i))
|
||||
mp.Command("loadfile", i, "append");
|
||||
|
||||
mp.SetStringProp("playlist-pos", "0", false);
|
||||
|
||||
foreach (string i in args)
|
||||
{
|
||||
if (i.StartsWith("--"))
|
||||
{
|
||||
if (i.Contains("="))
|
||||
{
|
||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
||||
string right = i.Substring(left.Length + 3);
|
||||
mp.SetStringProp(left, right);
|
||||
}
|
||||
else
|
||||
mp.SetStringProp(i.Substring(2), "yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFiles(string[] files)
|
||||
{
|
||||
int count = mp.GetIntProp("playlist-count");
|
||||
|
||||
foreach (string file in files)
|
||||
mp.Command("loadfile", file, "append");
|
||||
|
||||
mp.SetIntProp("playlist-pos", count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
mp.Command("playlist-remove", "0");
|
||||
|
||||
mp.LoadFolder();
|
||||
}
|
||||
|
||||
private static bool WasFolderLoaded;
|
||||
|
||||
public static void LoadFolder()
|
||||
{
|
||||
if (WasFolderLoaded)
|
||||
return;
|
||||
|
||||
if (GetIntProp("playlist-count") == 1)
|
||||
{
|
||||
string[] types = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' ');
|
||||
string path = GetStringProp("path");
|
||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||
files = files.Where((file) => types.Contains(file.Ext())).ToList();
|
||||
files.Sort(new StringLogicalComparer());
|
||||
int index = files.IndexOf(path);
|
||||
files.Remove(path);
|
||||
|
||||
foreach (string i in files)
|
||||
Command("loadfile", i, "append");
|
||||
|
||||
if (index > 0)
|
||||
Command("playlist-move", "0", (index + 1).ToString());
|
||||
}
|
||||
|
||||
WasFolderLoaded = true;
|
||||
}
|
||||
|
||||
public static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||
{
|
||||
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
||||
byteArrayPointers = new IntPtr[numberOfStrings];
|
||||
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
||||
|
||||
for (int index = 0; index < arr.Length; index++)
|
||||
{
|
||||
var bytes = GetUtf8Bytes(arr[index]);
|
||||
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
||||
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
||||
byteArrayPointers[index] = unmanagedPointer;
|
||||
}
|
||||
|
||||
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
||||
return rootPointer;
|
||||
}
|
||||
|
||||
public static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr pUnmanagedStringArray, int StringCount)
|
||||
{
|
||||
IntPtr[] pIntPtrArray = new IntPtr[StringCount];
|
||||
string[] ManagedStringArray = new string[StringCount];
|
||||
Marshal.Copy(pUnmanagedStringArray, pIntPtrArray, 0, StringCount);
|
||||
|
||||
for (int i = 0; i < StringCount; i++)
|
||||
ManagedStringArray[i] = StringFromNativeUtf8(pIntPtrArray[i]);
|
||||
|
||||
return ManagedStringArray;
|
||||
}
|
||||
|
||||
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
||||
{
|
||||
int len = 0;
|
||||
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
||||
byte[] buffer = new byte[len];
|
||||
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
||||
return Encoding.UTF8.GetString(buffer);
|
||||
}
|
||||
|
||||
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||
}
|
||||
|
||||
public enum EndFileEventMode
|
||||
{
|
||||
Eof,
|
||||
Stop,
|
||||
Quit,
|
||||
Error,
|
||||
Redirect,
|
||||
Unknown
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
@@ -94,6 +94,29 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IKVM.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPython, Version=2.7.9.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IronPython.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPython.Modules, Version=2.7.9.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IronPython.Modules.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPythonAddon">
|
||||
<HintPath>IronPython\IronPythonAddon.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Dynamic, Version=1.2.2.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\Microsoft.Dynamic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Scripting, Version=1.2.2.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\Microsoft.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -105,6 +128,11 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Addon.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
<Compile Include="MediaInfo.cs" />
|
||||
<Compile Include="Menu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PyScript.cs" />
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
<Compile Include="libmpv.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
@@ -114,7 +142,7 @@
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Misc.cs" />
|
||||
<Compile Include="mpv.cs" />
|
||||
<Compile Include="mp.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Native.cs" />
|
||||
<Compile Include="NativeHelp.cs" />
|
||||
@@ -123,6 +151,7 @@
|
||||
<Compile Include="UI.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
@@ -153,12 +182,6 @@
|
||||
<Content Include="screenshot.jpg" />
|
||||
<None Include="Resources\input_conf.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\vbnet\vbnet.vbproj">
|
||||
<Project>{af1b21c5-28fc-4d47-ad0b-54f6a38391a6}</Project>
|
||||
<Name>vbnet</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
Before Width: | Height: | Size: 497 KiB After Width: | Height: | Size: 497 KiB |
@@ -1,59 +0,0 @@
|
||||
#this file defines the shortcut keys and the context menu
|
||||
|
||||
#key command key caption menu path/caption
|
||||
|
||||
o script-message mpv.net open-files #menu: O; Open Files
|
||||
|
||||
Space cycle pause #menu: Space ; Play/Pause
|
||||
s stop #menu: S ; Stop
|
||||
|
||||
F11 playlist-prev #menu: F11 ; Navigate | Previous
|
||||
F12 playlist-next #menu: F12 ; Navigate | Next
|
||||
|
||||
Ctrl++ add video-zoom 0.1 #menu: Ctrl++ ; Pan && Scan | Increase Size
|
||||
Ctrl+- add video-zoom -0.1 #menu: Ctrl+- ; Pan && Scan | Decrease Size
|
||||
|
||||
Enter cycle pause #menu: Enter ; Cycle Fullscreen
|
||||
KP7 cycle audio #menu: Numpad 7 ; Cycle Audio
|
||||
KP8 cycle sub #menu: Numpad 8 ; Cycle Subtitle
|
||||
|
||||
+ add volume 10 #menu: + ; Volume | Up
|
||||
- add volume -10 #menu: - ; Volume | Down
|
||||
Axis_Up add volume 10 #wheel up
|
||||
Axis_Down add volume -10 #wheel down
|
||||
_ ignore #menu: _ ; Volume | -
|
||||
m cycle mute #menu: M ; Volume | Mute
|
||||
|
||||
KP6 add audio-delay 0.100 #menu: Numpad 6 ; Audio | Delay +0.1
|
||||
KP9 add audio-delay -0.100 #menu: Numpad 9 ; Audio | Delay -0.1
|
||||
|
||||
Right no-osd seek 10 #menu: Right ; Seek | 7 sec forward
|
||||
Left no-osd seek -10 #menu: Left ; Seek | 7 sec backward
|
||||
_ ignore #menu: _ ; Seek | -
|
||||
Up no-osd seek 40 #menu: Up ; Seek | 1 min forward
|
||||
Down no-osd seek -40 #menu: Down ; Seek | 1 min backward
|
||||
_ ignore #menu: _ ; Seek | -
|
||||
Ctrl+Right no-osd seek 300 #menu: Ctrl+Right ; Seek | 5 min forward
|
||||
Ctrl+Left no-osd seek -300 #menu: Ctrl+Left ; Seek | 5 min backward
|
||||
|
||||
KP0 script-message rate-file 0 #menu: Numpad 0 ; Addons | Rating | 0stars
|
||||
KP1 script-message rate-file 1 #menu: Numpad 1 ; Addons | Rating | 1stars
|
||||
KP2 script-message rate-file 2 #menu: Numpad 2 ; Addons | Rating | 2stars
|
||||
KP3 script-message rate-file 3 #menu: Numpad 3 ; Addons | Rating | 3stars
|
||||
KP4 script-message rate-file 4 #menu: Numpad 4 ; Addons | Rating | 4stars
|
||||
KP5 script-message rate-file 5 #menu: Numpad 5 ; Addons | Rating | 5stars
|
||||
|
||||
_ script-message mpv.net set-setting hwdec yes #menu: _ ; Settings | Hardware Decoding | Enable Hardware Decoding
|
||||
_ script-message mpv.net set-setting hwdec no #menu: _ ; Settings | Hardware Decoding | Disable Hardware Decoding
|
||||
|
||||
p script-message mpv.net show-prefs #menu: P ; Settings | Show Preferences
|
||||
k script-message mpv.net show-keys #menu: K ; Settings | Show Keys
|
||||
|
||||
i script-message mpv.net show-info #menu: I ; Tools | Info
|
||||
c script-message mpv.net open-config-folder #menu: _ ; Tools | Config Folder
|
||||
h script-message mpv.net history #menu: H ; Tools | History
|
||||
l ab-loop #menu: L ; Tools | AB Loop
|
||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: _ ; Tools | mpv Manual
|
||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: _ ; Tools | mpv Default Keys
|
||||
Esc quit #menu: Escape ; Exit
|
||||
Q quit-watch-later #menu: Shift+Q; Exit Watch Later
|
||||
@@ -1,630 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
// public static string Multiply(this string instance, int multiplier)
|
||||
// {
|
||||
// StringBuilder sb = new StringBuilder(multiplier * instance.Length);
|
||||
|
||||
// for (var i = 0; i <= multiplier - 1; i++)
|
||||
// {
|
||||
// sb.Append(instance);
|
||||
// }
|
||||
|
||||
// return sb.ToString();
|
||||
// }
|
||||
|
||||
// public static bool IsValidFileName(string instance)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return false;
|
||||
|
||||
// string chars = "\"*/:<>?\\|";
|
||||
|
||||
// foreach (var i in instance)
|
||||
// {
|
||||
// if (chars.Contains(i.ToString()))
|
||||
// return false;
|
||||
|
||||
// if (Convert.ToInt32(i) < 32)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string FileName(string instance)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return "";
|
||||
// dynamic index = instance.LastIndexOf(Path.DirectorySeparatorChar);
|
||||
// if (index > -1)
|
||||
// return instance.Substring(index + 1);
|
||||
// return instance;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Upper(string instance)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return "";
|
||||
// return instance.ToUpperInvariant;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Lower(string instance)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return "";
|
||||
// return instance.ToLowerInvariant;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string ChangeExt(string instance, string value)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return "";
|
||||
// if (string.IsNullOrEmpty(value))
|
||||
// return instance;
|
||||
// if (!value.StartsWith("."))
|
||||
// value = "." + value;
|
||||
// return instance.DirAndBase + value.ToLower;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Escape(string instance)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(instance))
|
||||
// return "";
|
||||
|
||||
// dynamic chars = " ()".ToCharArray;
|
||||
|
||||
// foreach (void i_loopVariable in chars)
|
||||
// {
|
||||
// i = i_loopVariable;
|
||||
// if (instance.Contains(i))
|
||||
// return "\"" + instance + "\"";
|
||||
// }
|
||||
|
||||
// return instance;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Parent(string instance)
|
||||
// {
|
||||
// return DirPath.GetParent(instance);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string ExistingParent(string instance)
|
||||
// {
|
||||
// dynamic ret = instance.Parent;
|
||||
// if (!Directory.Exists(ret))
|
||||
// ret = ret.Parent;
|
||||
// else
|
||||
// return ret;
|
||||
// if (!Directory.Exists(ret))
|
||||
// ret = ret.Parent;
|
||||
// else
|
||||
// return ret;
|
||||
// if (!Directory.Exists(ret))
|
||||
// ret = ret.Parent;
|
||||
// else
|
||||
// return ret;
|
||||
// if (!Directory.Exists(ret))
|
||||
// ret = ret.Parent;
|
||||
// else
|
||||
// return ret;
|
||||
// if (!Directory.Exists(ret))
|
||||
// ret = ret.Parent;
|
||||
// else
|
||||
// return ret;
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
public static string ExtFull(this string filepath)
|
||||
{
|
||||
return Ext(filepath, true);
|
||||
}
|
||||
|
||||
public static string Ext(this string filepath)
|
||||
{
|
||||
return Ext(filepath, false);
|
||||
}
|
||||
|
||||
public static string Ext(this string filepath, bool dot)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filepath))
|
||||
return "";
|
||||
|
||||
var chars = filepath.ToCharArray();
|
||||
|
||||
for (var x = filepath.Length - 1; x >= 0; x += -1)
|
||||
{
|
||||
if (chars[x] == Path.DirectorySeparatorChar)
|
||||
return "";
|
||||
|
||||
if (chars[x] == '.')
|
||||
return filepath.Substring(x + (dot ? 0 : 1)).ToLower();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// [Extension()]
|
||||
// public static string Base(string instance)
|
||||
// {
|
||||
// return FilePath.GetBase(instance);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Dir(string instance)
|
||||
// {
|
||||
// return FilePath.GetDir(instance);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string DirName(string instance)
|
||||
// {
|
||||
// return DirPath.GetName(instance);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string DirAndBase(string instance)
|
||||
// {
|
||||
// return FilePath.GetDirAndBase(instance);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static bool ContainsAll(string instance, IEnumerable<string> all)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(instance))
|
||||
// return all.All(arg => instance.Contains(arg));
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static bool ContainsAny(string instance, IEnumerable<string> any)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(instance))
|
||||
// return any.Any(arg => instance.Contains(arg));
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string ToTitleCase(string value)
|
||||
// {
|
||||
// //TextInfo.ToTitleCase won't work on all upper strings
|
||||
// return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value.ToLower);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static bool IsInt(string value)
|
||||
// {
|
||||
// return int.TryParse(value, null);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static int ToInt(string value, int defaultValue = 0)
|
||||
// {
|
||||
// if (!int.TryParse(value, null))
|
||||
// return defaultValue;
|
||||
// return Convert.ToInt32(value);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static bool IsSingle(string value)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(value))
|
||||
// {
|
||||
// if (value.Contains(","))
|
||||
// value = value.Replace(",", ".");
|
||||
|
||||
// return float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, null);
|
||||
// }
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static float ToSingle(string value, float defaultValue = 0)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(value))
|
||||
// {
|
||||
// if (value.Contains(","))
|
||||
// value = value.Replace(",", ".");
|
||||
|
||||
// float ret = 0;
|
||||
|
||||
// if (float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, ret))
|
||||
// {
|
||||
// return ret;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return defaultValue;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static bool IsDouble(string value)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(value))
|
||||
// {
|
||||
// if (value.Contains(","))
|
||||
// value = value.Replace(",", ".");
|
||||
|
||||
// return double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, null);
|
||||
// }
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static double ToDouble(string value, float defaultValue = 0)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(value))
|
||||
// {
|
||||
// if (value.Contains(","))
|
||||
// value = value.Replace(",", ".");
|
||||
|
||||
// double ret = 0;
|
||||
|
||||
// if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, ret))
|
||||
// {
|
||||
// return ret;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return defaultValue;
|
||||
// }
|
||||
|
||||
public static string Left(this string value, int index)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || index < 0)
|
||||
return "";
|
||||
|
||||
if (index > value.Length)
|
||||
return value;
|
||||
|
||||
return value.Substring(0, index);
|
||||
}
|
||||
|
||||
public static string Left(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(0, value.IndexOf(start));
|
||||
}
|
||||
|
||||
public static string LeftLast(this string value, string start)
|
||||
{
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(0, value.LastIndexOf(start));
|
||||
}
|
||||
|
||||
public static string Right(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(value.IndexOf(start) + start.Length);
|
||||
}
|
||||
|
||||
public static string RightLast(this string value, string start)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(start))
|
||||
return "";
|
||||
|
||||
if (!value.Contains(start))
|
||||
return "";
|
||||
|
||||
return value.Substring(value.LastIndexOf(start) + start.Length);
|
||||
}
|
||||
|
||||
// [Extension()]
|
||||
// public static bool EqualIgnoreCase(string a, string b)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b))
|
||||
// return false;
|
||||
// return string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string Shorten(string value, int maxLength)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(value) || value.Length <= maxLength)
|
||||
// {
|
||||
// return value;
|
||||
// }
|
||||
|
||||
// return value.Substring(0, maxLength);
|
||||
// }
|
||||
|
||||
public static string[] SplitNoEmpty(this string value, params string[] delimiters)
|
||||
{
|
||||
return value.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public static string[] SplitKeepEmpty(this string value, params string[] delimiters)
|
||||
{
|
||||
return value.Split(delimiters, StringSplitOptions.None);
|
||||
}
|
||||
|
||||
public static string[] SplitNoEmptyAndWhiteSpace(this string value, params string[] delimiters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return null;
|
||||
|
||||
var a = SplitNoEmpty(value, delimiters);
|
||||
|
||||
for (var i = 0; i <= a.Length - 1; i++)
|
||||
a[i] = a[i].Trim();
|
||||
|
||||
var l = a.ToList();
|
||||
|
||||
while (l.Contains(""))
|
||||
l.Remove("");
|
||||
|
||||
return l.ToArray();
|
||||
}
|
||||
|
||||
public static string[] SplitLinesNoEmpty(this string value)
|
||||
{
|
||||
return SplitNoEmpty(value, Environment.NewLine);
|
||||
}
|
||||
|
||||
// [Extension()]
|
||||
// public static string RemoveChars(string value, string chars)
|
||||
// {
|
||||
// dynamic ret = value;
|
||||
|
||||
// foreach (void i_loopVariable in value)
|
||||
// {
|
||||
// i = i_loopVariable;
|
||||
// if (chars.IndexOf(i) >= 0)
|
||||
// {
|
||||
// ret = ret.Replace(i, "");
|
||||
// }
|
||||
// }
|
||||
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string DeleteRight(string value, int count)
|
||||
// {
|
||||
// return Strings.Left(value, value.Length - count);
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static string ReplaceUnicode(string value)
|
||||
// {
|
||||
// if (value.Contains(Convert.ToChar(0x2212)))
|
||||
// {
|
||||
// value = value.Replace(Convert.ToChar(0x2212), '-');
|
||||
// }
|
||||
|
||||
// return value;
|
||||
// }
|
||||
|
||||
// [Extension()]
|
||||
// public static void ToClipboard(string value)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(value))
|
||||
// {
|
||||
// Clipboard.SetText(value);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Clipboard.Clear();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
public class DirPath : PathBase
|
||||
{
|
||||
|
||||
// public static string TrimTrailingSeparator(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
|
||||
// if (path.EndsWith(Separator) && !(path.Length <= 3))
|
||||
// {
|
||||
// return path.TrimEnd(Separator);
|
||||
// }
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string FixSeperator(string path)
|
||||
// {
|
||||
// if (path.Contains("\\") && Separator != "\\")
|
||||
// {
|
||||
// path = path.Replace("\\", Separator);
|
||||
// }
|
||||
|
||||
// if (path.Contains("/") && Separator != "/")
|
||||
// {
|
||||
// path = path.Replace("/", Separator);
|
||||
// }
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetParent(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
// dynamic temp = TrimTrailingSeparator(path);
|
||||
// if (temp.Contains(Separator))
|
||||
// path = temp.LeftLast(Separator) + Separator;
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetName(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
// path = TrimTrailingSeparator(path);
|
||||
// return path.RightLast(Separator);
|
||||
// }
|
||||
|
||||
// public static bool IsFixedDrive(string path)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(path))
|
||||
// return new DriveInfo(path).DriveType == DriveType.Fixed;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public class FilePath : PathBase
|
||||
{
|
||||
|
||||
|
||||
// private string Value;
|
||||
// public FilePath(string path)
|
||||
// {
|
||||
// Value = path;
|
||||
// }
|
||||
|
||||
// public static string GetDir(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
// if (path.Contains("\\"))
|
||||
// path = path.LeftLast("\\") + "\\";
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetDirAndBase(string path)
|
||||
// {
|
||||
// return GetDir(path) + GetBase(path);
|
||||
// }
|
||||
|
||||
// public static string GetName(string path)
|
||||
// {
|
||||
// if ((path != null))
|
||||
// {
|
||||
// dynamic index = path.LastIndexOf(IO.Path.DirectorySeparatorChar);
|
||||
|
||||
// if (index > -1)
|
||||
// {
|
||||
// return path.Substring(index + 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetDirNoSep(string path)
|
||||
// {
|
||||
// path = GetDir(path);
|
||||
// if (path.EndsWith(Separator))
|
||||
// path = TrimSep(path);
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetBase(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
// dynamic ret = path;
|
||||
// if (ret.Contains(Separator))
|
||||
// ret = ret.RightLast(Separator);
|
||||
// if (ret.Contains("."))
|
||||
// ret = ret.LeftLast(".");
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// public static string TrimSep(string path)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(path))
|
||||
// return "";
|
||||
|
||||
// if (path.EndsWith(Separator) && !path.EndsWith(":" + Separator))
|
||||
// {
|
||||
// return path.TrimEnd(Separator);
|
||||
// }
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
// public static string GetDirNameOnly(string path)
|
||||
// {
|
||||
// return FilePath.GetDirNoSep(path).RightLast("\\");
|
||||
// }
|
||||
}
|
||||
|
||||
public class PathBase
|
||||
{
|
||||
//public static char Separator {
|
||||
// get { return Path.DirectorySeparatorChar; }
|
||||
//}
|
||||
|
||||
// public static bool IsSameBase(string a, string b)
|
||||
// {
|
||||
// return FilePath.GetBase(a).EqualIgnoreCase(FilePath.GetBase(b));
|
||||
// }
|
||||
|
||||
// public static bool IsSameDir(string a, string b)
|
||||
// {
|
||||
// return FilePath.GetDir(a).EqualIgnoreCase(FilePath.GetDir(b));
|
||||
// }
|
||||
|
||||
// public static bool IsValidFileSystemName(string name)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(name))
|
||||
// return false;
|
||||
// dynamic chars = "\"*/:<>?\\|^".ToCharArray;
|
||||
|
||||
// foreach (void i_loopVariable in name.ToCharArray)
|
||||
// {
|
||||
// i = i_loopVariable;
|
||||
// if (chars.Contains(i))
|
||||
// return false;
|
||||
// if (Convert.ToInt32(i) < 32)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// public static string RemoveIllegalCharsFromName(string name)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(name))
|
||||
// return "";
|
||||
|
||||
// dynamic chars = "\"*/:<>?\\|^".ToCharArray;
|
||||
|
||||
// foreach (void i_loopVariable in name.ToCharArray)
|
||||
// {
|
||||
// i = i_loopVariable;
|
||||
// if (chars.Contains(i))
|
||||
// {
|
||||
// name = name.Replace(i, "_");
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (x = 1; x <= 31; x++)
|
||||
// {
|
||||
// if (name.Contains(Convert.ToChar(x)))
|
||||
// {
|
||||
// name = name.Replace(Convert.ToChar(x), '_');
|
||||
// }
|
||||
// }
|
||||
|
||||
// return name;
|
||||
}
|
||||
}
|
||||
348
mpvnet/mpv.cs
348
mpvnet/mpv.cs
@@ -1,348 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using static mpvnet.libmpv;
|
||||
using static mpvnet.Native;
|
||||
|
||||
using vbnet;
|
||||
using static vbnet.UI.MainModule;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
||||
|
||||
public class mpv
|
||||
{
|
||||
public static event Action<string[]> ClientMessage;
|
||||
public static event Action Shutdown;
|
||||
public static event Action AfterShutdown;
|
||||
public static event Action PlaybackRestart;
|
||||
public static event Action VideoSizeChanged;
|
||||
|
||||
public static IntPtr MpvHandle;
|
||||
public static IntPtr MpvWindowHandle;
|
||||
public static Addon Addon;
|
||||
public static List<Action<bool>> BoolPropChangeActions = new List<Action<bool>>();
|
||||
public static Size VideoSize = new Size(1920, 1080);
|
||||
public static string InputConfPath = Folder.AppDataRoaming + "mpv\\input.conf";
|
||||
public static string mpvConfPath = Folder.AppDataRoaming + "mpv\\mpv.conf";
|
||||
public static StringPairList BindingList = new StringPairList();
|
||||
|
||||
private static Dictionary<string, string> _mpvConv;
|
||||
|
||||
public static Dictionary<string, string> mpvConv {
|
||||
get {
|
||||
if (_mpvConv == null)
|
||||
{
|
||||
_mpvConv = new Dictionary<string, string>();
|
||||
|
||||
if (File.Exists(mpvConfPath))
|
||||
{
|
||||
foreach (var i in File.ReadAllLines(mpvConfPath))
|
||||
{
|
||||
if (i.Contains("=") && ! i.StartsWith("#"))
|
||||
{
|
||||
_mpvConv[i.Left("=").Trim()] = i.Right("=").Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _mpvConv;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
LoadLibrary("mpv-1.dll");
|
||||
MpvHandle = mpv_create();
|
||||
SetIntProp("input-ar-delay", 500);
|
||||
SetIntProp("input-ar-rate", 20);
|
||||
SetIntProp("volume", 50);
|
||||
SetStringProp("hwdec", "yes");
|
||||
SetStringProp("input-default-bindings", "yes");
|
||||
SetStringProp("osd-playing-msg", "'${filename}'");
|
||||
SetStringProp("screenshot-directory", "~~desktop/");
|
||||
SetStringProp("keep-open", "yes");
|
||||
SetStringProp("keep-open-pause", "no");
|
||||
SetStringProp("osc", "yes");
|
||||
SetStringProp("config", "yes");
|
||||
SetStringProp("wid", MainForm.Hwnd.ToString());
|
||||
SetStringProp("force-window", "yes");
|
||||
mpv_initialize(MpvHandle);
|
||||
ProcessCommandLine();
|
||||
Task.Run(() => { Addon = new Addon(); });
|
||||
Task.Run(() => { EventLoop(); });
|
||||
}
|
||||
|
||||
public static void EventLoop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr ptr = mpv_wait_event(MpvHandle, -1);
|
||||
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
||||
Debug.WriteLine(evt.event_id);
|
||||
|
||||
if (MpvWindowHandle == IntPtr.Zero)
|
||||
MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||
|
||||
switch (evt.event_id)
|
||||
{
|
||||
case mpv_event_id.MPV_EVENT_SHUTDOWN:
|
||||
Shutdown?.Invoke();
|
||||
AfterShutdown?.Invoke();
|
||||
return;
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||
LoadFolder();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||
PlaybackRestart?.Invoke();
|
||||
|
||||
Size s = new Size(GetIntProp("dwidth", false), GetIntProp("dheight", false));
|
||||
|
||||
if (VideoSize != s && s != Size.Empty)
|
||||
{
|
||||
VideoSize = s;
|
||||
VideoSizeChanged?.Invoke();
|
||||
}
|
||||
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
||||
if (ClientMessage != null)
|
||||
{
|
||||
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
||||
var args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
|
||||
|
||||
if (args != null && args.Length > 1 && args[0] == "mpv.net")
|
||||
foreach (var i in mpvnet.Command.Commands)
|
||||
if (args[1] == i.Name)
|
||||
try
|
||||
{
|
||||
i.Action(args.Skip(2).ToArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MsgError(ex.GetType().Name, ex.ToString());
|
||||
}
|
||||
|
||||
ClientMessage?.Invoke(args);
|
||||
}
|
||||
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||
var eventData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||
|
||||
if (eventData.format == mpv_format.MPV_FORMAT_FLAG)
|
||||
foreach (var action in BoolPropChangeActions)
|
||||
action.Invoke(Marshal.PtrToStructure<int>(eventData.data) == 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Command(params string[] args)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
IntPtr[] byteArrayPointers;
|
||||
var mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out byteArrayPointers);
|
||||
int err = mpv_command(MpvHandle, mainPtr);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{(mpv_error)err}");
|
||||
|
||||
foreach (var ptr in byteArrayPointers)
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
|
||||
Marshal.FreeHGlobal(mainPtr);
|
||||
}
|
||||
|
||||
public static void CommandString(string command, bool throwException = true)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
int err = mpv_command_string(MpvHandle, command);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{(mpv_error)err}" + BR2 + command);
|
||||
}
|
||||
|
||||
public static void SetStringProp(string name, string value, bool throwException = true)
|
||||
{
|
||||
var bytes = GetUtf8Bytes(value);
|
||||
int err = mpv_set_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static string GetStringProp(string name)
|
||||
{
|
||||
var lpBuffer = IntPtr.Zero;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref lpBuffer);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
|
||||
var ret = StringFromNativeUtf8(lpBuffer);
|
||||
mpv_free(lpBuffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int GetIntProp(string name, bool throwException = true)
|
||||
{
|
||||
var lpBuffer = IntPtr.Zero;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref lpBuffer);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
return lpBuffer.ToInt32();
|
||||
}
|
||||
|
||||
public static void SetIntProp(string name, int value)
|
||||
{
|
||||
Int64 val = value;
|
||||
int err = mpv_set_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static void ObserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
BoolPropChangeActions.Add(action);
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static void UnobserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
BoolPropChangeActions.Remove(action);
|
||||
int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode());
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
}
|
||||
|
||||
public static void ProcessCommandLine()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||
|
||||
foreach (string i in args)
|
||||
if (!i.StartsWith("--") && File.Exists(i))
|
||||
mpv.Command("loadfile", i, "append");
|
||||
|
||||
mpv.SetStringProp("playlist-pos", "0", false);
|
||||
|
||||
foreach (string i in args)
|
||||
{
|
||||
if (i.StartsWith("--"))
|
||||
{
|
||||
if (i.Contains("="))
|
||||
{
|
||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
||||
string right = i.Substring(left.Length + 3);
|
||||
mpv.SetStringProp(left, right);
|
||||
}
|
||||
else
|
||||
mpv.SetStringProp(i.Substring(2), "yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFiles(string[] files)
|
||||
{
|
||||
int count = mpv.GetIntProp("playlist-count");
|
||||
|
||||
foreach (string file in files)
|
||||
mpv.Command("loadfile", file, "append");
|
||||
|
||||
mpv.SetIntProp("playlist-pos", count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
mpv.Command("playlist-remove", "0");
|
||||
|
||||
mpv.LoadFolder();
|
||||
}
|
||||
|
||||
private static bool WasFolderLoaded;
|
||||
|
||||
public static void LoadFolder()
|
||||
{
|
||||
if (WasFolderLoaded)
|
||||
return;
|
||||
|
||||
if (GetIntProp("playlist-count") == 1)
|
||||
{
|
||||
string[] types = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' ');
|
||||
string path = GetStringProp("path");
|
||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||
files = files.Where((file) => types.Contains(file.Ext())).ToList();
|
||||
files.Sort(new StringLogicalComparer());
|
||||
int index = files.IndexOf(path);
|
||||
files.Remove(path);
|
||||
|
||||
foreach (string i in files)
|
||||
Command("loadfile", i, "append");
|
||||
|
||||
if (index > 0)
|
||||
Command("playlist-move", "0", (index + 1).ToString());
|
||||
}
|
||||
|
||||
WasFolderLoaded = true;
|
||||
}
|
||||
|
||||
public static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||
{
|
||||
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
||||
byteArrayPointers = new IntPtr[numberOfStrings];
|
||||
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
||||
|
||||
for (int index = 0; index < arr.Length; index++)
|
||||
{
|
||||
var bytes = GetUtf8Bytes(arr[index]);
|
||||
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
||||
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
||||
byteArrayPointers[index] = unmanagedPointer;
|
||||
}
|
||||
|
||||
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
||||
return rootPointer;
|
||||
}
|
||||
|
||||
public static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr pUnmanagedStringArray, int StringCount)
|
||||
{
|
||||
IntPtr[] pIntPtrArray = new IntPtr[StringCount];
|
||||
string[] ManagedStringArray = new string[StringCount];
|
||||
Marshal.Copy(pUnmanagedStringArray, pIntPtrArray, 0, StringCount);
|
||||
|
||||
for (int i = 0; i < StringCount; i++)
|
||||
ManagedStringArray[i] = StringFromNativeUtf8(pIntPtrArray[i]);
|
||||
|
||||
return ManagedStringArray;
|
||||
}
|
||||
|
||||
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
||||
{
|
||||
int len = 0;
|
||||
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
||||
byte[] buffer = new byte[len];
|
||||
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
||||
return Encoding.UTF8.GetString(buffer);
|
||||
}
|
||||
|
||||
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||
}
|
||||
}
|
||||
10
release.ps1
Normal file
10
release.ps1
Normal file
@@ -0,0 +1,10 @@
|
||||
$scriptDir = Split-Path -Path $PSCommandPath -Parent
|
||||
$exePath = $scriptDir + "\mpv.net\bin\Debug\mpvnet.exe"
|
||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
||||
$targetDir = $desktopDir + "\mpv.net-" + $version
|
||||
Copy-Item $scriptDir\mpv.net\bin\Debug $targetDir -recurse
|
||||
$addonDir = $targetDir + "\Addons"
|
||||
$7zPath = "C:\Program Files\7-Zip\7z.exe"
|
||||
$args = "a -t7z -mx9 $targetDir.7z -r $targetDir\*"
|
||||
Start-Process -FilePath $7zPath -ArgumentList $args
|
||||
@@ -1,8 +0,0 @@
|
||||
using namespace System.Diagnostics
|
||||
$exePath = "C:\Users\frank\Desktop\Projekte\mpvnet\mpvnet\bin\Debug\mpvnet.exe"
|
||||
$version = [FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||
$targetDir = "C:\Users\Frank\Desktop\mpv.net-" + $version
|
||||
Copy-Item C:\Users\frank\Desktop\Projekte\mpvnet\mpvnet\bin\Debug $targetDir -recurse
|
||||
$addonDir = $targetDir + "\Addons"
|
||||
remove-item $addonDir -Recurse -Include *vbnet.pdb, *mpvnet.exe, *mpvnet.exe.config, *mpvnet.pdb, *vbnet.dll
|
||||
D:\Projekte\VS\VB\util\bin\util.exe -pack $targetDir
|
||||
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
@@ -1,790 +0,0 @@
|
||||
Imports System.Drawing.Drawing2D
|
||||
Imports System.Globalization
|
||||
Imports System.IO
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.CompilerServices
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Text
|
||||
Imports Microsoft.Win32
|
||||
Imports VB6 = Microsoft.VisualBasic
|
||||
|
||||
Imports vbnet.UI
|
||||
|
||||
Module StringExtensions
|
||||
<Extension>
|
||||
Public Function Multiply(instance As String, multiplier As Integer) As String
|
||||
Dim sb As New StringBuilder(multiplier * instance.Length)
|
||||
|
||||
For i = 0 To multiplier - 1
|
||||
sb.Append(instance)
|
||||
Next
|
||||
|
||||
Return sb.ToString()
|
||||
End Function
|
||||
|
||||
<Extension>
|
||||
Function IsValidFileName(instance As String) As Boolean
|
||||
If instance = "" Then Return False
|
||||
Dim chars = """*/:<>?\|"
|
||||
|
||||
For Each i In instance
|
||||
If chars.Contains(i) Then Return False
|
||||
If Convert.ToInt32(i) < 32 Then Return False
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
<Extension>
|
||||
Function IsANSICompatible(instance As String) As Boolean
|
||||
If instance = "" Then Return True
|
||||
Dim bytes = Encoding.Convert(Encoding.Unicode, Encoding.Default, Encoding.Unicode.GetBytes(instance))
|
||||
Return instance = Encoding.Unicode.GetString(Encoding.Convert(Encoding.Default, Encoding.Unicode, bytes))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function FileName(instance As String) As String
|
||||
If instance = "" Then Return ""
|
||||
Dim index = instance.LastIndexOf(Path.DirectorySeparatorChar)
|
||||
If index > -1 Then Return instance.Substring(index + 1)
|
||||
Return instance
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Upper(instance As String) As String
|
||||
If instance = "" Then Return ""
|
||||
Return instance.ToUpperInvariant
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Lower(instance As String) As String
|
||||
If instance = "" Then Return ""
|
||||
Return instance.ToLowerInvariant
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ChangeExt(instance As String, value As String) As String
|
||||
If instance = "" Then Return ""
|
||||
If value = "" Then Return instance
|
||||
If Not value.StartsWith(".") Then value = "." + value
|
||||
Return instance.DirAndBase + value.ToLower
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Escape(instance As String) As String
|
||||
If instance = "" Then Return ""
|
||||
|
||||
Dim chars = " ()".ToCharArray
|
||||
|
||||
For Each i In chars
|
||||
If instance.Contains(i) Then Return """" + instance + """"
|
||||
Next
|
||||
|
||||
Return instance
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Parent(instance As String) As String
|
||||
Return DirPath.GetParent(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ExistingParent(instance As String) As String
|
||||
Dim ret = instance.Parent
|
||||
If Not Directory.Exists(ret) Then ret = ret.Parent Else Return ret
|
||||
If Not Directory.Exists(ret) Then ret = ret.Parent Else Return ret
|
||||
If Not Directory.Exists(ret) Then ret = ret.Parent Else Return ret
|
||||
If Not Directory.Exists(ret) Then ret = ret.Parent Else Return ret
|
||||
If Not Directory.Exists(ret) Then ret = ret.Parent Else Return ret
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Ext(instance As String) As String
|
||||
Return FilePath.GetExt(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ExtFull(instance As String) As String
|
||||
Return FilePath.GetExtFull(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Base(instance As String) As String
|
||||
Return FilePath.GetBase(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Dir(instance As String) As String
|
||||
Return FilePath.GetDir(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function DirName(instance As String) As String
|
||||
Return DirPath.GetName(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function DirAndBase(instance As String) As String
|
||||
Return FilePath.GetDirAndBase(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ContainsAll(instance As String, all As IEnumerable(Of String)) As Boolean
|
||||
If instance <> "" Then Return all.All(Function(arg) instance.Contains(arg))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ContainsAny(instance As String, any As IEnumerable(Of String)) As Boolean
|
||||
If instance <> "" Then Return any.Any(Function(arg) instance.Contains(arg))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function EqualsAny(instance As String, ParamArray values As String()) As Boolean
|
||||
If instance = "" OrElse values.NothingOrEmpty Then Return False
|
||||
Return values.Contains(instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function FixDir(instance As String) As String
|
||||
If instance = "" Then Return ""
|
||||
|
||||
While instance.EndsWith(DirPath.Separator + DirPath.Separator)
|
||||
instance = instance.Substring(0, instance.Length - 1)
|
||||
End While
|
||||
|
||||
If instance.EndsWith(DirPath.Separator) Then Return instance
|
||||
Return instance + DirPath.Separator
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function FixBreak(value As String) As String
|
||||
value = value.Replace(VB6.ChrW(13) + VB6.ChrW(10), VB6.ChrW(10))
|
||||
value = value.Replace(VB6.ChrW(13), VB6.ChrW(10))
|
||||
Return value.Replace(VB6.ChrW(10), VB6.ChrW(13) + VB6.ChrW(10))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ContainsUnicode(value As String) As Boolean
|
||||
If value = "" Then Return False
|
||||
|
||||
For Each i In value
|
||||
If Convert.ToInt32(i) > 255 Then Return True
|
||||
Next
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ToTitleCase(value As String) As String
|
||||
'TextInfo.ToTitleCase won't work on all upper strings
|
||||
Return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value.ToLower)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function IsInt(value As String) As Boolean
|
||||
Return Integer.TryParse(value, Nothing)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ToInt(value As String, Optional defaultValue As Integer = 0) As Integer
|
||||
If Not Integer.TryParse(value, Nothing) Then Return defaultValue
|
||||
Return CInt(value)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function IsSingle(value As String) As Boolean
|
||||
If value <> "" Then
|
||||
If value.Contains(",") Then value = value.Replace(",", ".")
|
||||
|
||||
Return Single.TryParse(value,
|
||||
NumberStyles.Float Or NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
Nothing)
|
||||
End If
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ToSingle(value As String, Optional defaultValue As Single = 0) As Single
|
||||
If value <> "" Then
|
||||
If value.Contains(",") Then value = value.Replace(",", ".")
|
||||
|
||||
Dim ret As Single
|
||||
|
||||
If Single.TryParse(value,
|
||||
NumberStyles.Float Or NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
ret) Then
|
||||
Return ret
|
||||
End If
|
||||
End If
|
||||
|
||||
Return defaultValue
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function IsDouble(value As String) As Boolean
|
||||
If value <> "" Then
|
||||
If value.Contains(",") Then value = value.Replace(",", ".")
|
||||
|
||||
Return Double.TryParse(value,
|
||||
NumberStyles.Float Or NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
Nothing)
|
||||
End If
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ToDouble(value As String, Optional defaultValue As Single = 0) As Double
|
||||
If value <> "" Then
|
||||
If value.Contains(",") Then value = value.Replace(",", ".")
|
||||
|
||||
Dim ret As Double
|
||||
|
||||
If Double.TryParse(value,
|
||||
NumberStyles.Float Or NumberStyles.AllowThousands,
|
||||
CultureInfo.InvariantCulture,
|
||||
ret) Then
|
||||
Return ret
|
||||
End If
|
||||
End If
|
||||
|
||||
Return defaultValue
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function FormatColumn(value As String, delimiter As String) As String
|
||||
If value = "" Then Return ""
|
||||
Dim lines = value.SplitKeepEmpty(BR)
|
||||
Dim leftSides As New List(Of String)
|
||||
|
||||
For Each i In lines
|
||||
Dim pos = i.IndexOf(delimiter)
|
||||
|
||||
If pos > 0 Then
|
||||
leftSides.Add(i.Substring(0, pos).Trim)
|
||||
Else
|
||||
leftSides.Add(i)
|
||||
End If
|
||||
Next
|
||||
|
||||
Dim highest = Aggregate i In leftSides Into Max(i.Length)
|
||||
Dim ret As New List(Of String)
|
||||
|
||||
For i = 0 To lines.Length - 1
|
||||
Dim line = lines(i)
|
||||
|
||||
If line.Contains(delimiter) Then
|
||||
ret.Add(leftSides(i).PadRight(highest) + " " + delimiter + " " + line.Substring(line.IndexOf(delimiter) + 1).Trim)
|
||||
Else
|
||||
ret.Add(leftSides(i))
|
||||
End If
|
||||
Next
|
||||
|
||||
Return ret.Join(BR)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub WriteANSIFile(instance As String, path As String)
|
||||
WriteFile(instance, path, Encoding.Default)
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub WriteUTF8File(instance As String, path As String)
|
||||
WriteFile(instance, path, Encoding.UTF8)
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub WriteFile(value As String, path As String, encoding As Encoding)
|
||||
Try
|
||||
File.WriteAllText(path, value, encoding)
|
||||
Catch ex As Exception
|
||||
MsgException(ex)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Function Left(value As String, index As Integer) As String
|
||||
If value = "" OrElse index < 0 Then Return ""
|
||||
If index > value.Length Then Return value
|
||||
Return value.Substring(0, index)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Left(value As String, start As String) As String
|
||||
If value = "" OrElse start = "" Then Return ""
|
||||
If Not value.Contains(start) Then Return ""
|
||||
Return value.Substring(0, value.IndexOf(start))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function LeftLast(value As String, start As String) As String
|
||||
If Not value.Contains(start) Then Return ""
|
||||
Return value.Substring(0, value.LastIndexOf(start))
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Right(value As String, start As String) As String
|
||||
If value = "" OrElse start = "" Then Return ""
|
||||
If Not value.Contains(start) Then Return ""
|
||||
Return value.Substring(value.IndexOf(start) + start.Length)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function RightLast(value As String, start As String) As String
|
||||
If value = "" OrElse start = "" Then Return ""
|
||||
If Not value.Contains(start) Then Return ""
|
||||
Return value.Substring(value.LastIndexOf(start) + start.Length)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function EqualIgnoreCase(a As String, b As String) As Boolean
|
||||
If a = "" OrElse b = "" Then Return False
|
||||
Return String.Compare(a, b, StringComparison.OrdinalIgnoreCase) = 0
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Shorten(value As String, maxLength As Integer) As String
|
||||
If value = "" OrElse value.Length <= maxLength Then
|
||||
Return value
|
||||
End If
|
||||
|
||||
Return value.Substring(0, maxLength)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function SplitNoEmpty(value As String, ParamArray delimiters As String()) As String()
|
||||
Return value.Split(delimiters, StringSplitOptions.RemoveEmptyEntries)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function SplitKeepEmpty(value As String, ParamArray delimiters As String()) As String()
|
||||
Return value.Split(delimiters, StringSplitOptions.None)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function SplitNoEmptyAndWhiteSpace(value As String, ParamArray delimiters As String()) As String()
|
||||
If value = "" Then Return {}
|
||||
|
||||
Dim a = SplitNoEmpty(value, delimiters)
|
||||
|
||||
For i = 0 To a.Length - 1
|
||||
a(i) = a(i).Trim
|
||||
Next
|
||||
|
||||
Dim l = a.ToList
|
||||
|
||||
While l.Contains("")
|
||||
l.Remove("")
|
||||
End While
|
||||
|
||||
Return l.ToArray
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function SplitLinesNoEmpty(value As String) As String()
|
||||
Return SplitNoEmpty(value, Environment.NewLine)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function RemoveChars(value As String, chars As String) As String
|
||||
Dim ret = value
|
||||
|
||||
For Each i In value
|
||||
If chars.IndexOf(i) >= 0 Then
|
||||
ret = ret.Replace(i, "")
|
||||
End If
|
||||
Next
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function DeleteRight(value As String, count As Integer) As String
|
||||
Return Left(value, value.Length - count)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ReplaceUnicode(value As String) As String
|
||||
If value.Contains(Convert.ToChar(&H2212)) Then
|
||||
value = value.Replace(Convert.ToChar(&H2212), "-"c)
|
||||
End If
|
||||
|
||||
Return value
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function SHA512Hash(value As String) As String
|
||||
Dim crypt = SHA512CryptoServiceProvider.Create()
|
||||
Dim hash = crypt.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value))
|
||||
Dim sb As New StringBuilder()
|
||||
|
||||
For Each i In hash
|
||||
sb.Append(i.ToString("x2"))
|
||||
Next
|
||||
|
||||
Return sb.ToString()
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub ToClipboard(value As String)
|
||||
If value <> "" Then
|
||||
Clipboard.SetText(value)
|
||||
Else
|
||||
Clipboard.Clear()
|
||||
End If
|
||||
End Sub
|
||||
End Module
|
||||
|
||||
Module MiscExtensions
|
||||
<Extension()>
|
||||
Function ToInvariantString(instance As Double, format As String) As String
|
||||
Dim ret = instance.ToString(format, CultureInfo.InvariantCulture)
|
||||
|
||||
If (ret.Contains(".") OrElse ret.Contains(",")) AndAlso ret.EndsWith("0") Then
|
||||
ret = ret.TrimEnd("0"c)
|
||||
End If
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ToInvariantString(instance As IConvertible) As String
|
||||
If Not instance Is Nothing Then Return instance.ToString(CultureInfo.InvariantCulture)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ContainsAny(Of T)(instance As IEnumerable(Of T), ParamArray values As T()) As Boolean
|
||||
Return instance.Where(Function(arg) values.Contains(arg)).Count > 0
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Sort(Of T)(instance As IEnumerable(Of T)) As IEnumerable(Of T)
|
||||
Dim ret = instance.ToArray
|
||||
Array.Sort(Of T)(ret)
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function Join(instance As IEnumerable(Of String),
|
||||
delimiter As String,
|
||||
Optional removeEmpty As Boolean = False) As String
|
||||
|
||||
If instance Is Nothing Then Return Nothing
|
||||
Dim containsEmpty As Boolean
|
||||
|
||||
For Each item In instance
|
||||
If item = "" Then
|
||||
containsEmpty = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If containsEmpty AndAlso removeEmpty Then instance = instance.Where(Function(arg) arg <> "")
|
||||
Return String.Join(delimiter, instance)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetAttribute(Of T)(mi As MemberInfo) As T
|
||||
Dim attributes = mi.GetCustomAttributes(True)
|
||||
|
||||
If Not attributes.NothingOrEmpty Then
|
||||
If attributes.Length = 1 Then
|
||||
If TypeOf attributes(0) Is T Then
|
||||
Return DirectCast(attributes(0), T)
|
||||
End If
|
||||
Else
|
||||
For Each i In attributes
|
||||
If TypeOf i Is T Then
|
||||
Return DirectCast(i, T)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function IsDigit(c As Char) As Boolean
|
||||
Return Char.IsDigit(c)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function EnsureRange(value As Integer, min As Integer, max As Integer) As Integer
|
||||
If value < min Then
|
||||
value = min
|
||||
ElseIf value > max Then
|
||||
value = max
|
||||
End If
|
||||
|
||||
Return value
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function NeutralCulture(ci As CultureInfo) As CultureInfo
|
||||
If ci.IsNeutralCulture Then Return ci Else Return ci.Parent
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function NothingOrEmpty(strings As IEnumerable(Of String)) As Boolean
|
||||
If strings Is Nothing OrElse strings.Count = 0 Then Return True
|
||||
|
||||
For Each i In strings
|
||||
If i = "" Then Return True
|
||||
Next
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function NothingOrEmpty(objects As IEnumerable(Of Object)) As Boolean
|
||||
If objects Is Nothing OrElse objects.Count = 0 Then Return True
|
||||
|
||||
For Each i In objects
|
||||
If i Is Nothing Then Return True
|
||||
Next
|
||||
End Function
|
||||
End Module
|
||||
|
||||
Module RegistryKeyExtensions
|
||||
Private Function GetValue(Of T)(rootKey As RegistryKey, key As String, name As String) As T
|
||||
Using k = rootKey.OpenSubKey(key)
|
||||
If Not k Is Nothing Then
|
||||
Dim r = k.GetValue(name)
|
||||
|
||||
If Not r Is Nothing Then
|
||||
Try
|
||||
Return CType(r, T)
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End If
|
||||
End If
|
||||
End Using
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetString(rootKey As RegistryKey, subKey As String, name As String) As String
|
||||
Return GetValue(Of String)(rootKey, subKey, name)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetInt(rootKey As RegistryKey, subKey As String, name As String) As Integer
|
||||
Return GetValue(Of Integer)(rootKey, subKey, name)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetBoolean(rootKey As RegistryKey, subKey As String, name As String) As Boolean
|
||||
Return GetValue(Of Boolean)(rootKey, subKey, name)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetValueNames(rootKey As RegistryKey, subKeyName As String) As IEnumerable(Of String)
|
||||
Using k = rootKey.OpenSubKey(subKeyName)
|
||||
If Not k Is Nothing Then
|
||||
Return k.GetValueNames
|
||||
End If
|
||||
End Using
|
||||
|
||||
Return {}
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub GetSubKeys(rootKey As RegistryKey, keys As List(Of RegistryKey))
|
||||
If Not rootKey Is Nothing Then
|
||||
keys.Add(rootKey)
|
||||
|
||||
For Each i In rootKey.GetSubKeyNames
|
||||
GetSubKeys(rootKey.OpenSubKey(i), keys)
|
||||
Next
|
||||
End If
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub Write(rootKey As RegistryKey, subKey As String, valueName As String, valueValue As Object)
|
||||
Dim k = rootKey.OpenSubKey(subKey, True)
|
||||
|
||||
If k Is Nothing Then
|
||||
k = rootKey.CreateSubKey(subKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
|
||||
End If
|
||||
|
||||
k.SetValue(valueName, valueValue)
|
||||
k.Close()
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub DeleteValue(rootKey As RegistryKey, key As String, valueName As String)
|
||||
Using k = rootKey.OpenSubKey(key, True)
|
||||
If Not k Is Nothing Then
|
||||
k.DeleteValue(valueName, False)
|
||||
End If
|
||||
End Using
|
||||
End Sub
|
||||
End Module
|
||||
|
||||
Module ControlExtension
|
||||
<Extension()>
|
||||
Sub ScaleClientSize(instance As Control, width As Single, height As Single)
|
||||
instance.ClientSize = New Size(CInt(instance.Font.Height * width), CInt(instance.Font.Height * height))
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub SetFontStyle(instance As Control, style As FontStyle)
|
||||
instance.Font = New Font(instance.Font.FontFamily, instance.Font.Size, style)
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub AddClickAction(instance As Control, action As Action)
|
||||
AddHandler instance.Click, Sub() action()
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Function ClientMousePos(instance As Control) As Point
|
||||
Return instance.PointToClient(Control.MousePosition)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function GetMaxTextSpace(instance As Control, ParamArray values As String()) As String
|
||||
Dim ret As String
|
||||
|
||||
For x = 4 To 2 Step -1
|
||||
ret = values.Join("".PadRight(x))
|
||||
Dim testWidth = TextRenderer.MeasureText(ret, instance.Font).Width
|
||||
If testWidth < instance.Width - 2 OrElse x = 2 Then Return ret
|
||||
Next
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
End Module
|
||||
|
||||
Module UIExtensions
|
||||
<Extension()>
|
||||
Sub ClearAndDisplose(instance As ToolStripItemCollection)
|
||||
For Each i In instance.OfType(Of IDisposable).ToArray
|
||||
i.Dispose()
|
||||
Next
|
||||
|
||||
instance.Clear()
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Function ResizeToSmallIconSize(img As Image) As Image
|
||||
If Not img Is Nothing AndAlso img.Size <> SystemInformation.SmallIconSize Then
|
||||
Dim s = SystemInformation.SmallIconSize
|
||||
Dim r As New Bitmap(s.Width, s.Height)
|
||||
|
||||
Using g = Graphics.FromImage(DirectCast(r, Image))
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality
|
||||
g.DrawImage(img, 0, 0, s.Width, s.Height)
|
||||
End Using
|
||||
|
||||
Return r
|
||||
End If
|
||||
|
||||
Return img
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function ResizeImage(image As Image, ByVal height As Integer) As Image
|
||||
Dim percentHeight = height / image.Height
|
||||
Dim ret = New Bitmap(CInt(image.Width * percentHeight), CInt(height))
|
||||
|
||||
Using g = Graphics.FromImage(ret)
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic
|
||||
g.DrawImage(image, 0, 0, ret.Width, ret.Height)
|
||||
End Using
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub SetSelectedPath(d As FolderBrowserDialog, path As String)
|
||||
If Not Directory.Exists(path) Then path = path.ExistingParent
|
||||
If Directory.Exists(path) Then d.SelectedPath = path
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub SetInitDir(d As FileDialog, ParamArray paths As String())
|
||||
For Each i In paths
|
||||
If Not Directory.Exists(i) Then i = i.ExistingParent
|
||||
|
||||
If Directory.Exists(i) Then
|
||||
d.InitialDirectory = i
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub SetFilter(d As FileDialog, values As IEnumerable(Of String))
|
||||
d.Filter = GetFilter(values)
|
||||
End Sub
|
||||
|
||||
Function GetFilter(values As IEnumerable(Of String)) As String
|
||||
Return "*." + values.Join(";*.") + "|*." + values.Join(";*.") + "|All Files|*.*"
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub SendMessageCue(tb As TextBox, value As String, hideWhenFocused As Boolean)
|
||||
Dim wParam = If(hideWhenFocused, 0, 1)
|
||||
Native.SendMessage(tb.Handle, Native.EM_SETCUEBANNER, wParam, value)
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub SendMessageCue(c As ComboBox, value As String)
|
||||
Native.SendMessage(c.Handle, Native.CB_SETCUEBANNER, 1, value)
|
||||
End Sub
|
||||
|
||||
Function GetPropertyValue(obj As String, propertyName As String) As Object
|
||||
obj.GetType.GetProperty(propertyName).GetValue(obj)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub RemoveSelection(dgv As DataGridView)
|
||||
For Each i As DataGridViewRow In dgv.SelectedRows
|
||||
dgv.Rows.Remove(i)
|
||||
Next
|
||||
|
||||
If dgv.SelectedRows.Count = 0 AndAlso dgv.RowCount > 0 Then
|
||||
dgv.Rows(dgv.RowCount - 1).Selected = True
|
||||
End If
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Function CanMoveUp(dgv As DataGridView) As Boolean
|
||||
Return dgv.SelectedRows.Count > 0 AndAlso dgv.SelectedRows(0).Index > 0
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Function CanMoveDown(dgv As DataGridView) As Boolean
|
||||
Return dgv.SelectedRows.Count > 0 AndAlso dgv.SelectedRows(0).Index < dgv.RowCount - 1
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub MoveSelectionUp(dgv As DataGridView)
|
||||
If CanMoveUp(dgv) Then
|
||||
Dim bs = DirectCast(dgv.DataSource, BindingSource)
|
||||
Dim pos = bs.Position
|
||||
bs.RaiseListChangedEvents = False
|
||||
Dim current = bs.Current
|
||||
bs.Remove(current)
|
||||
pos -= 1
|
||||
bs.Insert(pos, current)
|
||||
bs.Position = pos
|
||||
bs.RaiseListChangedEvents = True
|
||||
bs.ResetBindings(False)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
<Extension()>
|
||||
Sub MoveSelectionDown(dgv As DataGridView)
|
||||
If CanMoveDown(dgv) Then
|
||||
Dim bs = DirectCast(dgv.DataSource, BindingSource)
|
||||
Dim pos = bs.Position
|
||||
bs.RaiseListChangedEvents = False
|
||||
Dim current = bs.Current
|
||||
bs.Remove(current)
|
||||
pos += 1
|
||||
bs.Insert(pos, current)
|
||||
bs.Position = pos
|
||||
bs.RaiseListChangedEvents = True
|
||||
bs.ResetBindings(False)
|
||||
End If
|
||||
End Sub
|
||||
End Module
|
||||
@@ -1,141 +0,0 @@
|
||||
Public Structure HSLColor
|
||||
Public Sub New(color As Color)
|
||||
SetRGB(color.R, color.G, color.B)
|
||||
End Sub
|
||||
|
||||
Public Sub New(h As Integer, s As Integer, l As Integer)
|
||||
Hue = h
|
||||
Saturation = s
|
||||
Luminosity = l
|
||||
End Sub
|
||||
|
||||
Private HueValue As Double
|
||||
|
||||
Property Hue As Integer
|
||||
Get
|
||||
Return CInt(HueValue * 240)
|
||||
End Get
|
||||
Set(value As Integer)
|
||||
HueValue = CheckRange(value / 240)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private SaturationValue As Double
|
||||
|
||||
Property Saturation As Integer
|
||||
Get
|
||||
Return CInt(SaturationValue * 240)
|
||||
End Get
|
||||
Set(value As Integer)
|
||||
SaturationValue = CheckRange(value / 240)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private LuminosityValue As Double
|
||||
|
||||
Property Luminosity As Integer
|
||||
Get
|
||||
Return CInt(LuminosityValue * 240)
|
||||
End Get
|
||||
Set(value As Integer)
|
||||
LuminosityValue = CheckRange(value / 240)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private Function CheckRange(value As Double) As Double
|
||||
If value < 0 Then
|
||||
value = 0
|
||||
ElseIf value > 1 Then
|
||||
value = 1
|
||||
End If
|
||||
|
||||
Return value
|
||||
End Function
|
||||
|
||||
Function ToColorAddLuminosity(luminosity As Integer) As Color
|
||||
Me.Luminosity += luminosity
|
||||
Return ToColor()
|
||||
End Function
|
||||
|
||||
Function ToColorSetLuminosity(luminosity As Integer) As Color
|
||||
Me.Luminosity = luminosity
|
||||
Return ToColor()
|
||||
End Function
|
||||
|
||||
Function ToColor() As Color
|
||||
Dim r, g, b As Double
|
||||
|
||||
If LuminosityValue <> 0 Then
|
||||
If SaturationValue = 0 Then
|
||||
b = LuminosityValue
|
||||
g = LuminosityValue
|
||||
r = LuminosityValue
|
||||
Else
|
||||
Dim temp2 = GetTemp2(Me)
|
||||
Dim temp1 = 2.0 * LuminosityValue - temp2
|
||||
|
||||
r = GetColorComponent(temp1, temp2, HueValue + 1.0 / 3.0)
|
||||
g = GetColorComponent(temp1, temp2, HueValue)
|
||||
b = GetColorComponent(temp1, temp2, HueValue - 1.0 / 3.0)
|
||||
End If
|
||||
End If
|
||||
|
||||
Return Color.FromArgb(CInt(255 * r), CInt(255 * g), CInt(255 * b))
|
||||
End Function
|
||||
|
||||
Private Shared Function GetColorComponent(temp1 As Double,
|
||||
temp2 As Double,
|
||||
temp3 As Double) As Double
|
||||
temp3 = MoveIntoRange(temp3)
|
||||
|
||||
If temp3 < 1 / 6 Then
|
||||
Return temp1 + (temp2 - temp1) * 6.0 * temp3
|
||||
ElseIf temp3 < 0.5 Then
|
||||
Return temp2
|
||||
ElseIf temp3 < 2 / 3 Then
|
||||
Return temp1 + ((temp2 - temp1) * ((2 / 3) - temp3) * 6)
|
||||
Else
|
||||
Return temp1
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Shared Function MoveIntoRange(temp3 As Double) As Double
|
||||
If temp3 < 0 Then
|
||||
temp3 += 1
|
||||
ElseIf temp3 > 1 Then
|
||||
temp3 -= 1
|
||||
End If
|
||||
|
||||
Return temp3
|
||||
End Function
|
||||
|
||||
Private Shared Function GetTemp2(hslColor As HSLColor) As Double
|
||||
Dim temp2 As Double
|
||||
|
||||
If hslColor.LuminosityValue < 0.5 Then
|
||||
temp2 = hslColor.LuminosityValue * (1.0 + hslColor.SaturationValue)
|
||||
Else
|
||||
temp2 = hslColor.LuminosityValue + hslColor.SaturationValue - (hslColor.LuminosityValue * hslColor.SaturationValue)
|
||||
End If
|
||||
|
||||
Return temp2
|
||||
End Function
|
||||
|
||||
Public Shared Function Convert(c As Color) As HSLColor
|
||||
Dim r As New HSLColor()
|
||||
|
||||
r.HueValue = c.GetHue() / 360.0
|
||||
r.LuminosityValue = c.GetBrightness()
|
||||
r.SaturationValue = c.GetSaturation()
|
||||
|
||||
Return r
|
||||
End Function
|
||||
|
||||
Public Sub SetRGB(red As Integer, green As Integer, blue As Integer)
|
||||
Dim hc = HSLColor.Convert(Color.FromArgb(red, green, blue))
|
||||
|
||||
HueValue = hc.HueValue
|
||||
SaturationValue = hc.SaturationValue
|
||||
LuminosityValue = hc.LuminosityValue
|
||||
End Sub
|
||||
End Structure
|
||||
@@ -1,133 +0,0 @@
|
||||
Namespace UI
|
||||
Public Module MainModule
|
||||
Public ReadOnly BR As String = Environment.NewLine
|
||||
Public ReadOnly BR2 As String = Environment.NewLine + Environment.NewLine
|
||||
|
||||
Sub MsgInfo(text As String, Optional content As String = Nothing)
|
||||
Msg(text, content, MsgIcon.Info, TaskDialogButtons.Ok)
|
||||
End Sub
|
||||
|
||||
Sub MsgError(text As String, Optional content As String = Nothing)
|
||||
If text = "" Then text = content
|
||||
If text = "" Then Exit Sub
|
||||
|
||||
Using td As New TaskDialog(Of String)
|
||||
td.AllowCancel = False
|
||||
|
||||
If content = "" Then
|
||||
If text.Length < 80 Then
|
||||
td.MainInstruction = text
|
||||
Else
|
||||
td.Content = text
|
||||
End If
|
||||
Else
|
||||
td.MainInstruction = text
|
||||
td.Content = content
|
||||
End If
|
||||
|
||||
td.MainIcon = TaskDialogIcon.Error
|
||||
td.Footer = "[copymsg: Copy Message]"
|
||||
td.Show()
|
||||
End Using
|
||||
End Sub
|
||||
|
||||
Sub MsgWarn(text As String, Optional content As String = Nothing)
|
||||
Msg(text, content, MsgIcon.Warning, TaskDialogButtons.Ok)
|
||||
End Sub
|
||||
|
||||
Function MsgOK(text As String) As Boolean
|
||||
Return Msg(text, Nothing, MsgIcon.Question, TaskDialogButtons.OkCancel) = DialogResult.OK
|
||||
End Function
|
||||
|
||||
Function MsgQuestion(text As String,
|
||||
Optional buttons As TaskDialogButtons = TaskDialogButtons.OkCancel) As DialogResult
|
||||
Return Msg(text, Nothing, MsgIcon.Question, buttons)
|
||||
End Function
|
||||
|
||||
Function MsgQuestion(heading As String,
|
||||
content As String,
|
||||
Optional buttons As TaskDialogButtons = TaskDialogButtons.OkCancel) As DialogResult
|
||||
Return Msg(heading, content, MsgIcon.Question, buttons)
|
||||
End Function
|
||||
|
||||
Function Msg(mainInstruction As String,
|
||||
content As String,
|
||||
icon As MsgIcon,
|
||||
buttons As TaskDialogButtons,
|
||||
Optional defaultButton As DialogResult = DialogResult.None) As DialogResult
|
||||
|
||||
Try
|
||||
If mainInstruction Is Nothing Then mainInstruction = ""
|
||||
|
||||
Using td As New TaskDialog(Of DialogResult)
|
||||
td.AllowCancel = False
|
||||
td.DefaultButton = defaultButton
|
||||
|
||||
If content Is Nothing Then
|
||||
If mainInstruction.Length < 80 Then
|
||||
td.MainInstruction = mainInstruction
|
||||
Else
|
||||
td.Content = mainInstruction
|
||||
End If
|
||||
Else
|
||||
td.MainInstruction = mainInstruction
|
||||
td.Content = content
|
||||
End If
|
||||
|
||||
Select Case icon
|
||||
Case MsgIcon.Error
|
||||
td.MainIcon = TaskDialogIcon.Error
|
||||
Case MsgIcon.Warning
|
||||
td.MainIcon = TaskDialogIcon.Warning
|
||||
Case MsgIcon.Info
|
||||
td.MainIcon = TaskDialogIcon.Info
|
||||
End Select
|
||||
|
||||
If buttons = TaskDialogButtons.OkCancel Then
|
||||
td.AddButton("OK", DialogResult.OK)
|
||||
td.AddButton("Cancel", DialogResult.Cancel) 'don't use system language
|
||||
Else
|
||||
td.CommonButtons = buttons
|
||||
End If
|
||||
|
||||
Return td.Show()
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
MsgBox(mainInstruction + content, MessageBoxIcon.Error)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Sub MsgException(e As Exception, Optional msg As String = Nothing, Optional timeout As Integer = 0)
|
||||
Try
|
||||
Using td As New TaskDialog(Of String)
|
||||
If msg = "" Then
|
||||
td.MainInstruction = e.GetType.Name + $" ({Application.ProductVersion})"
|
||||
Else
|
||||
td.MainInstruction = msg
|
||||
End If
|
||||
|
||||
td.Timeout = timeout
|
||||
td.Content = e.Message
|
||||
td.MainIcon = TaskDialogIcon.Error
|
||||
td.ExpandedInformation = e.ToString
|
||||
td.Footer = "[copymsg: Copy Message]"
|
||||
td.Show()
|
||||
End Using
|
||||
Catch
|
||||
MsgBox(e.GetType.Name + BR2 + e.Message + BR2 + e.ToString, MessageBoxIcon.Error)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Sub MsgBox(text As String, icon As MessageBoxIcon)
|
||||
MessageBox.Show(text, Application.ProductName, MessageBoxButtons.OK, icon)
|
||||
End Sub
|
||||
End Module
|
||||
|
||||
Public Enum MsgIcon
|
||||
None = MessageBoxIcon.None
|
||||
Info = MessageBoxIcon.Information
|
||||
[Error] = MessageBoxIcon.Error
|
||||
Warning = MessageBoxIcon.Warning
|
||||
Question = MessageBoxIcon.Question
|
||||
End Enum
|
||||
End Namespace
|
||||
@@ -1,93 +0,0 @@
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
Public Class MediaInfo
|
||||
Implements IDisposable
|
||||
|
||||
Private Handle As IntPtr
|
||||
Shared Loaded As Boolean
|
||||
|
||||
Sub New(sourcepath As String)
|
||||
If Not Loaded Then
|
||||
If LoadLibrary("MediaInfo.dll") = IntPtr.Zero Then Throw New Exception("Failed to load MediaInfo.dll.")
|
||||
Loaded = True
|
||||
End If
|
||||
|
||||
Handle = MediaInfo_New()
|
||||
MediaInfo_Open(Handle, sourcepath)
|
||||
End Sub
|
||||
|
||||
Public Function GetInfo(streamKind As StreamKind, parameter As String) As String
|
||||
Return Marshal.PtrToStringUni(MediaInfo_Get(Handle, streamKind, 0, parameter, InfoKind.Text, InfoKind.Name))
|
||||
End Function
|
||||
|
||||
#Region "IDisposable"
|
||||
|
||||
Private Disposed As Boolean
|
||||
|
||||
Sub Dispose() Implements IDisposable.Dispose
|
||||
If Not Disposed Then
|
||||
Disposed = True
|
||||
MediaInfo_Close(Handle)
|
||||
MediaInfo_Delete(Handle)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub Finalize()
|
||||
Dispose()
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "native"
|
||||
|
||||
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode)>
|
||||
Private Shared Function LoadLibrary(path As String) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("MediaInfo.dll")>
|
||||
Private Shared Function MediaInfo_New() As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("MediaInfo.dll")>
|
||||
Private Shared Sub MediaInfo_Delete(Handle As IntPtr)
|
||||
End Sub
|
||||
|
||||
<DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)>
|
||||
Private Shared Function MediaInfo_Open(Handle As IntPtr, FileName As String) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("MediaInfo.dll")>
|
||||
Private Shared Function MediaInfo_Close(Handle As IntPtr) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)>
|
||||
Private Shared Function MediaInfo_Get(Handle As IntPtr,
|
||||
StreamKind As StreamKind,
|
||||
StreamNumber As Integer, Parameter As String,
|
||||
KindOfInfo As InfoKind,
|
||||
KindOfSearch As InfoKind) As IntPtr
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
Public Enum StreamKind
|
||||
General
|
||||
Video
|
||||
Audio
|
||||
Text
|
||||
Chapters
|
||||
Image
|
||||
End Enum
|
||||
|
||||
Public Enum InfoKind
|
||||
Name
|
||||
Text
|
||||
Measure
|
||||
Options
|
||||
NameText
|
||||
MeasureText
|
||||
Info
|
||||
HowTo
|
||||
End Enum
|
||||
403
vbnet/Menu.vb
403
vbnet/Menu.vb
@@ -1,403 +0,0 @@
|
||||
Imports System.ComponentModel
|
||||
|
||||
Namespace UI
|
||||
Public Class MenuItemEx
|
||||
Inherits ToolStripMenuItem
|
||||
|
||||
Shared Property UseTooltips As Boolean
|
||||
|
||||
Sub New()
|
||||
End Sub
|
||||
|
||||
Sub New(text As String)
|
||||
MyBase.New(text)
|
||||
End Sub
|
||||
|
||||
Public Overrides Function GetPreferredSize(constrainingSize As Size) As Size
|
||||
Dim ret = MyBase.GetPreferredSize(constrainingSize)
|
||||
ret.Height = CInt(Font.Height * 1.4)
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Sub SetImage(symbol As Symbol)
|
||||
SetImage(symbol, Me)
|
||||
End Sub
|
||||
|
||||
Shared Async Sub SetImage(symbol As Symbol, mi As ToolStripMenuItem)
|
||||
If symbol = Symbol.None Then
|
||||
mi.Image = Nothing
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Dim img = Await ImageHelp.GetSymbolImageAsync(symbol)
|
||||
|
||||
Try
|
||||
If Not mi.IsDisposed Then
|
||||
mi.ImageScaling = ToolStripItemImageScaling.None
|
||||
mi.Image = img
|
||||
End If
|
||||
Catch
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Private Function ShouldSerializeHelpText() As Boolean
|
||||
Return HelpValue <> ""
|
||||
End Function
|
||||
|
||||
Private HelpValue As String
|
||||
|
||||
Property Help() As String
|
||||
Get
|
||||
Return HelpValue
|
||||
End Get
|
||||
Set(Value As String)
|
||||
HelpValue = Value
|
||||
|
||||
If UseTooltips Then
|
||||
If HelpValue <> "" Then
|
||||
If HelpValue.Length < 80 Then
|
||||
ToolTipText = HelpValue.TrimEnd("."c)
|
||||
Else
|
||||
ToolTipText = "Right-click for help"
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
|
||||
If e.Button = MouseButtons.Right AndAlso Help <> "" Then
|
||||
CloseAll(Me)
|
||||
ShowHelp(Text, Help)
|
||||
End If
|
||||
|
||||
MyBase.OnMouseDown(e)
|
||||
End Sub
|
||||
|
||||
Sub ShowHelp(title As String, content As String)
|
||||
If title <> "" Then title = title.TrimEnd("."c, ":"c)
|
||||
MsgInfo(title, content)
|
||||
End Sub
|
||||
|
||||
Sub CloseAll(item As Object)
|
||||
If TypeOf item Is ToolStripItem Then
|
||||
Dim d = DirectCast(item, ToolStripItem)
|
||||
CloseAll(d.Owner)
|
||||
End If
|
||||
|
||||
If TypeOf item Is ToolStripDropDown Then
|
||||
Dim d = DirectCast(item, ToolStripDropDown)
|
||||
d.Close()
|
||||
CloseAll(d.OwnerItem)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnClick(e As EventArgs)
|
||||
Application.DoEvents()
|
||||
MyBase.OnClick(e)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class ActionMenuItem
|
||||
Inherits MenuItemEx
|
||||
|
||||
Private Action As Action
|
||||
|
||||
Property EnabledFunc As Func(Of Boolean)
|
||||
Property VisibleFunc As Func(Of Boolean)
|
||||
|
||||
Property Form As Form
|
||||
|
||||
Sub New()
|
||||
End Sub
|
||||
|
||||
Sub New(text As String, a As Action)
|
||||
Me.New(text, a, Nothing)
|
||||
End Sub
|
||||
|
||||
Sub New(text As String,
|
||||
action As Action,
|
||||
Optional tooltip As String = Nothing,
|
||||
Optional enabled As Boolean = True)
|
||||
|
||||
Me.Text = text
|
||||
Me.Action = action
|
||||
Me.Help = tooltip
|
||||
Me.Enabled = enabled
|
||||
End Sub
|
||||
|
||||
Private ShortcutValue As Keys
|
||||
|
||||
Property Shortcut As Keys
|
||||
Get
|
||||
Return ShortcutValue
|
||||
End Get
|
||||
Set(value As Keys)
|
||||
ShortcutValue = value
|
||||
ShortcutKeyDisplayString = KeysHelp.GetKeyString(value) + " "
|
||||
AddHandler Form.KeyDown, AddressOf KeyDown
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Sub KeyDown(sender As Object, e As KeyEventArgs)
|
||||
If Enabled AndAlso e.KeyData = Shortcut AndAlso
|
||||
If(EnabledFunc Is Nothing, True, EnabledFunc.Invoke) AndAlso
|
||||
If(VisibleFunc Is Nothing, True, VisibleFunc.Invoke) Then
|
||||
|
||||
PerformClick()
|
||||
e.Handled = True
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Sub Opening(sender As Object, e As CancelEventArgs)
|
||||
If Not EnabledFunc Is Nothing Then Enabled = EnabledFunc.Invoke
|
||||
If Not VisibleFunc Is Nothing Then Visible = VisibleFunc.Invoke
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnClick(e As EventArgs)
|
||||
Application.DoEvents()
|
||||
If Not Action Is Nothing Then Action()
|
||||
MyBase.OnClick(e)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub Dispose(disposing As Boolean)
|
||||
MyBase.Dispose(disposing)
|
||||
If Not Form Is Nothing Then RemoveHandler Form.KeyDown, AddressOf KeyDown
|
||||
Action = Nothing
|
||||
EnabledFunc = Nothing
|
||||
VisibleFunc = Nothing
|
||||
Form = Nothing
|
||||
End Sub
|
||||
|
||||
Shared Function Add(Of T)(items As ToolStripItemCollection,
|
||||
path As String,
|
||||
action As Action(Of T),
|
||||
value As T,
|
||||
Optional help As String = Nothing) As ActionMenuItem
|
||||
|
||||
Return Add(items, path, Sub() action(value), help)
|
||||
End Function
|
||||
|
||||
Shared Function Add(items As ToolStripItemCollection,
|
||||
path As String) As ActionMenuItem
|
||||
|
||||
Return Add(items, path, Nothing)
|
||||
End Function
|
||||
|
||||
Shared Function Add(items As ToolStripItemCollection,
|
||||
path As String,
|
||||
action As Action) As ActionMenuItem
|
||||
|
||||
Return Add(items, path, action, Symbol.None, Nothing)
|
||||
End Function
|
||||
|
||||
Shared Function Add(items As ToolStripItemCollection,
|
||||
path As String,
|
||||
action As Action,
|
||||
tip As String) As ActionMenuItem
|
||||
|
||||
Return Add(items, path, action, Symbol.None, tip)
|
||||
End Function
|
||||
|
||||
Shared Function Add(items As ToolStripItemCollection,
|
||||
path As String,
|
||||
action As Action,
|
||||
symbol As Symbol,
|
||||
Optional tip As String = Nothing) As ActionMenuItem
|
||||
|
||||
Dim a = path.SplitNoEmpty(" | ")
|
||||
Dim l = items
|
||||
|
||||
For x = 0 To a.Length - 1
|
||||
Dim found = False
|
||||
|
||||
For Each i In l.OfType(Of ToolStripMenuItem)()
|
||||
If x < a.Length - 1 Then
|
||||
If i.Text = a(x) Then
|
||||
found = True
|
||||
l = i.DropDownItems
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
|
||||
If Not found Then
|
||||
If x = a.Length - 1 Then
|
||||
If a(x) = "-" Then
|
||||
l.Add(New ToolStripSeparator)
|
||||
Else
|
||||
Dim item As New ActionMenuItem(a(x), action, tip)
|
||||
item.SetImage(symbol)
|
||||
l.Add(item)
|
||||
l = item.DropDownItems
|
||||
Return item
|
||||
End If
|
||||
Else
|
||||
Dim item As New ActionMenuItem()
|
||||
item.Text = a(x)
|
||||
l.Add(item)
|
||||
l = item.DropDownItems
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class ContextMenuStripEx
|
||||
Inherits ContextMenuStrip
|
||||
|
||||
Private FormValue As Form
|
||||
|
||||
Sub New()
|
||||
End Sub
|
||||
|
||||
Sub New(container As IContainer)
|
||||
MyBase.New(container)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnOpening(e As CancelEventArgs)
|
||||
MyBase.OnOpening(e)
|
||||
MenuHelp.SetRenderer(Me)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnHandleCreated(e As EventArgs)
|
||||
MyBase.OnHandleCreated(e)
|
||||
Font = New Font("Segoe UI", 9)
|
||||
End Sub
|
||||
|
||||
<DefaultValue(GetType(Form), Nothing)>
|
||||
Property Form As Form
|
||||
Get
|
||||
Return FormValue
|
||||
End Get
|
||||
Set(value As Form)
|
||||
AddHandler value.Disposed, Sub() Dispose()
|
||||
FormValue = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Function Add(path As String) As ActionMenuItem
|
||||
Return Add(path, Nothing)
|
||||
End Function
|
||||
|
||||
Function Add(path As String,
|
||||
action As Action) As ActionMenuItem
|
||||
|
||||
Return Add(path, action, Nothing)
|
||||
End Function
|
||||
|
||||
Function Add(path As String,
|
||||
action As Action,
|
||||
help As String) As ActionMenuItem
|
||||
|
||||
Return Add(path, action, help, True)
|
||||
End Function
|
||||
|
||||
Function Add(path As String,
|
||||
action As Action,
|
||||
help As String,
|
||||
enabled As Boolean) As ActionMenuItem
|
||||
|
||||
Dim ret = ActionMenuItem.Add(Items, path, action)
|
||||
If ret Is Nothing Then Exit Function
|
||||
|
||||
ret.Form = Form
|
||||
ret.Help = help
|
||||
ret.Enabled = enabled
|
||||
|
||||
AddHandler Opening, AddressOf ret.Opening
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Function Add(path As String,
|
||||
action As Action,
|
||||
shortcut As Keys,
|
||||
enabledFunc As Func(Of Boolean),
|
||||
Optional help As String = Nothing) As ActionMenuItem
|
||||
|
||||
Dim ret = ActionMenuItem.Add(Items, path, action)
|
||||
|
||||
ret.Form = Form
|
||||
ret.Shortcut = shortcut
|
||||
ret.EnabledFunc = enabledFunc
|
||||
ret.Help = help
|
||||
|
||||
AddHandler Opening, AddressOf ret.Opening
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Function GetTips() As StringPairList
|
||||
Dim ret As New StringPairList
|
||||
|
||||
For Each i In GetItems.OfType(Of ActionMenuItem)()
|
||||
If i.Help <> "" Then
|
||||
Dim pair As New StringPair
|
||||
|
||||
If i.Text.EndsWith("...") Then
|
||||
pair.Name = i.Text.TrimEnd("."c)
|
||||
Else
|
||||
pair.Name = i.Text
|
||||
End If
|
||||
|
||||
pair.Value = i.Help
|
||||
ret.Add(pair)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Function GetKeys() As StringPairList
|
||||
Dim ret As New StringPairList
|
||||
|
||||
For Each i In GetItems.OfType(Of ActionMenuItem)()
|
||||
If i.ShortcutKeyDisplayString <> "" Then
|
||||
Dim sp As New StringPair
|
||||
|
||||
If i.Text.EndsWith("...") Then
|
||||
sp.Name = i.Text.TrimEnd("."c)
|
||||
Else
|
||||
sp.Name = i.Text
|
||||
End If
|
||||
|
||||
sp.Value = i.ShortcutKeyDisplayString
|
||||
ret.Add(sp)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Function GetItems() As List(Of ToolStripItem)
|
||||
Dim ret As New List(Of ToolStripItem)
|
||||
AddItemsRecursive(Items, ret)
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Shared Sub AddItemsRecursive(searchList As ToolStripItemCollection, returnList As List(Of ToolStripItem))
|
||||
For Each i As ToolStripItem In searchList
|
||||
returnList.Add(i)
|
||||
|
||||
If TypeOf i Is ToolStripDropDownItem Then
|
||||
AddItemsRecursive(DirectCast(i, ToolStripDropDownItem).DropDownItems, returnList)
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class MenuHelp
|
||||
Shared Sub SetRenderer(ms As ToolStrip)
|
||||
ms.Renderer = New ToolStripRendererEx(ToolStripRenderModeEx.SystemAuto)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Enum ToolStripRenderModeEx
|
||||
SystemAuto
|
||||
SystemDefault
|
||||
Win7Auto
|
||||
Win7Default
|
||||
Win10Auto
|
||||
Win10Default
|
||||
End Enum
|
||||
End Namespace
|
||||
465
vbnet/Misc.vb
465
vbnet/Misc.vb
@@ -1,465 +0,0 @@
|
||||
Imports System.ComponentModel
|
||||
Imports System.IO
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Security.Permissions
|
||||
Imports System.Text
|
||||
|
||||
Imports vbnet.UI
|
||||
|
||||
Public Class OSVersion
|
||||
Shared Property Windows7 As Single = 6.1
|
||||
Shared Property Windows8 As Single = 6.2
|
||||
Shared Property Windows10 As Single = 10.0
|
||||
|
||||
Shared ReadOnly Property Current As Single
|
||||
Get
|
||||
Return CSng(Environment.OSVersion.Version.Major + Environment.OSVersion.Version.Minor / 10)
|
||||
End Get
|
||||
End Property
|
||||
End Class
|
||||
|
||||
Public Class ProcessHelp
|
||||
Shared Sub Start(cmd As String, Optional args As String = Nothing)
|
||||
Try
|
||||
Process.Start(cmd, args)
|
||||
Catch ex As Exception
|
||||
If cmd Like "http*://*" Then
|
||||
MsgError("Failed to open URL with browser." + BR2 + cmd, ex.Message)
|
||||
ElseIf File.Exists(cmd) Then
|
||||
MsgError("Failed to launch file." + BR2 + cmd, ex.Message)
|
||||
ElseIf Directory.Exists(cmd) Then
|
||||
MsgError("Failed to launch directory." + BR2 + cmd, ex.Message)
|
||||
Else
|
||||
MsgException(ex, "Failed to execute command:" + BR2 + cmd + BR2 + "Arguments:" + BR2 + args)
|
||||
End If
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class KeysHelp
|
||||
Private Shared Converter As TypeConverter = TypeDescriptor.GetConverter(GetType(Keys))
|
||||
Private Shared KeysTexts As Dictionary(Of Keys, String)
|
||||
|
||||
Shared Sub New()
|
||||
KeysTexts = New Dictionary(Of Keys, String)
|
||||
KeysTexts(Keys.Add) = "+ (Numpad)"
|
||||
KeysTexts(Keys.Back) = "Back"
|
||||
KeysTexts(Keys.Decimal) = "Decimal"
|
||||
KeysTexts(Keys.Delete) = "Delete"
|
||||
KeysTexts(Keys.Divide) = "Divide"
|
||||
KeysTexts(Keys.Down) = "Down"
|
||||
KeysTexts(Keys.End) = "End"
|
||||
KeysTexts(Keys.Enter) = "Enter"
|
||||
KeysTexts(Keys.Escape) = "Escape"
|
||||
KeysTexts(Keys.Home) = "Home"
|
||||
KeysTexts(Keys.Insert) = "Insert"
|
||||
KeysTexts(Keys.Left) = "Left"
|
||||
KeysTexts(Keys.Multiply) = "Multiply"
|
||||
KeysTexts(Keys.Next) = "Page Down"
|
||||
KeysTexts(Keys.Prior) = "Page Up"
|
||||
KeysTexts(Keys.Right) = "Right"
|
||||
KeysTexts(Keys.Space) = "Space"
|
||||
KeysTexts(Keys.Subtract) = "- (Numpad)"
|
||||
KeysTexts(Keys.Up) = "Up"
|
||||
KeysTexts(Keys.Control) = "Control"
|
||||
KeysTexts(Keys.Alt) = "Alt"
|
||||
KeysTexts(Keys.Shift) = "Shift"
|
||||
|
||||
KeysTexts(Keys.D0) = "0"
|
||||
KeysTexts(Keys.D1) = "1"
|
||||
KeysTexts(Keys.D2) = "2"
|
||||
KeysTexts(Keys.D3) = "3"
|
||||
KeysTexts(Keys.D4) = "4"
|
||||
KeysTexts(Keys.D5) = "5"
|
||||
KeysTexts(Keys.D6) = "6"
|
||||
KeysTexts(Keys.D7) = "7"
|
||||
KeysTexts(Keys.D8) = "8"
|
||||
KeysTexts(Keys.D9) = "9"
|
||||
|
||||
KeysTexts(Keys.NumPad0) = "0 (Numpad)"
|
||||
KeysTexts(Keys.NumPad1) = "1 (Numpad)"
|
||||
KeysTexts(Keys.NumPad2) = "2 (Numpad)"
|
||||
KeysTexts(Keys.NumPad3) = "3 (Numpad)"
|
||||
KeysTexts(Keys.NumPad4) = "4 (Numpad)"
|
||||
KeysTexts(Keys.NumPad5) = "5 (Numpad)"
|
||||
KeysTexts(Keys.NumPad6) = "6 (Numpad)"
|
||||
KeysTexts(Keys.NumPad7) = "7 (Numpad)"
|
||||
KeysTexts(Keys.NumPad8) = "8 (Numpad)"
|
||||
KeysTexts(Keys.NumPad9) = "9 (Numpad)"
|
||||
End Sub
|
||||
|
||||
Shared Function GetKeyString(k As Keys) As String
|
||||
If k = Keys.None Then Return ""
|
||||
|
||||
Dim s = ""
|
||||
|
||||
If (k And Keys.Control) = Keys.Control Then
|
||||
k = k Xor Keys.Control
|
||||
s += "Ctrl+"
|
||||
End If
|
||||
|
||||
If (k And Keys.Alt) = Keys.Alt Then
|
||||
k = k Xor Keys.Alt
|
||||
s += "Alt+"
|
||||
End If
|
||||
|
||||
If (k And Keys.Shift) = Keys.Shift Then
|
||||
k = k Xor Keys.Shift
|
||||
s += "Shift+"
|
||||
End If
|
||||
|
||||
If KeysTexts.ContainsKey(k) Then
|
||||
s += KeysTexts(k)
|
||||
Else
|
||||
Dim value = MapVirtualKey(CInt(k), 2) 'MAPVK_VK_TO_CHAR
|
||||
|
||||
If value = 0 OrElse (value And 1 << 31) = 1 << 31 Then
|
||||
s += k.ToString
|
||||
Else
|
||||
s += Convert.ToChar(value)
|
||||
End If
|
||||
End If
|
||||
|
||||
Return s
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function MapVirtualKey(wCode As Integer, wMapType As Integer) As Integer
|
||||
End Function
|
||||
End Class
|
||||
|
||||
<Serializable>
|
||||
Public Class StringPair
|
||||
Implements IComparable(Of StringPair)
|
||||
|
||||
Property Name As String
|
||||
Property Value As String
|
||||
|
||||
Sub New()
|
||||
End Sub
|
||||
|
||||
Sub New(name As String, text As String)
|
||||
Me.Name = name
|
||||
Me.Value = text
|
||||
End Sub
|
||||
|
||||
Function CompareTo(other As StringPair) As Integer Implements System.IComparable(Of StringPair).CompareTo
|
||||
Return Name.CompareTo(other.Name)
|
||||
End Function
|
||||
End Class
|
||||
|
||||
<Serializable()>
|
||||
Public Class StringPairList
|
||||
Inherits List(Of StringPair)
|
||||
|
||||
Sub New()
|
||||
End Sub
|
||||
|
||||
Sub New(list As IEnumerable(Of StringPair))
|
||||
AddRange(list)
|
||||
End Sub
|
||||
|
||||
Overloads Sub Add(name As String, text As String)
|
||||
Add(New StringPair(name, text))
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class Folder
|
||||
|
||||
#Region "System"
|
||||
|
||||
Shared ReadOnly Property Desktop() As String
|
||||
Get
|
||||
Return Environment.GetFolderPath(Environment.SpecialFolder.Desktop).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Startup() As String
|
||||
Get
|
||||
Return Application.StartupPath.FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Current() As String
|
||||
Get
|
||||
Return Environment.CurrentDirectory.FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Temp() As String
|
||||
Get
|
||||
Return Path.GetTempPath.FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property System() As String
|
||||
Get
|
||||
Return Environment.SystemDirectory.FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Programs() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.ProgramFiles).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Home() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.UserProfile).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property AppDataCommon() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.CommonApplicationData).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property AppDataLocal() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.LocalApplicationData).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property AppDataRoaming() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.ApplicationData).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared ReadOnly Property Windows() As String
|
||||
Get
|
||||
Return GetFolderPath(Environment.SpecialFolder.Windows).FixDir
|
||||
End Get
|
||||
End Property
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "StaxRip"
|
||||
|
||||
Shared ReadOnly Property Apps As String
|
||||
Get
|
||||
Return Folder.Startup + "Apps\"
|
||||
End Get
|
||||
End Property
|
||||
|
||||
#End Region
|
||||
|
||||
<DllImport("shfolder.dll", CharSet:=CharSet.Unicode)>
|
||||
Private Shared Function SHGetFolderPath(hwndOwner As IntPtr, nFolder As Integer, hToken As IntPtr, dwFlags As Integer, lpszPath As StringBuilder) As Integer
|
||||
End Function
|
||||
|
||||
Private Shared Function GetFolderPath(folder As Environment.SpecialFolder) As String
|
||||
Dim sb As New StringBuilder(260)
|
||||
SHGetFolderPath(IntPtr.Zero, CInt(folder), IntPtr.Zero, 0, sb)
|
||||
Dim ret = sb.ToString.FixDir '.NET fails on 'D:'
|
||||
Call New FileIOPermission(FileIOPermissionAccess.PathDiscovery, ret).Demand()
|
||||
Return ret
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class PathBase
|
||||
Shared ReadOnly Property Separator() As Char
|
||||
Get
|
||||
Return Path.DirectorySeparatorChar
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Shared Function IsSameBase(a As String, b As String) As Boolean
|
||||
Return FilePath.GetBase(a).EqualIgnoreCase(FilePath.GetBase(b))
|
||||
End Function
|
||||
|
||||
Shared Function IsSameDir(a As String, b As String) As Boolean
|
||||
Return FilePath.GetDir(a).EqualIgnoreCase(FilePath.GetDir(b))
|
||||
End Function
|
||||
|
||||
Shared Function IsValidFileSystemName(name As String) As Boolean
|
||||
If name = "" Then Return False
|
||||
Dim chars = """*/:<>?\|^".ToCharArray
|
||||
|
||||
For Each i In name.ToCharArray
|
||||
If chars.Contains(i) Then Return False
|
||||
If Convert.ToInt32(i) < 32 Then Return False
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Shared Function RemoveIllegalCharsFromName(name As String) As String
|
||||
If name = "" Then Return ""
|
||||
|
||||
Dim chars = """*/:<>?\|^".ToCharArray
|
||||
|
||||
For Each i In name.ToCharArray
|
||||
If chars.Contains(i) Then
|
||||
name = name.Replace(i, "_")
|
||||
End If
|
||||
Next
|
||||
|
||||
For x = 1 To 31
|
||||
If name.Contains(Convert.ToChar(x)) Then
|
||||
name = name.Replace(Convert.ToChar(x), "_"c)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return name
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class DirPath
|
||||
Inherits PathBase
|
||||
|
||||
Shared Function TrimTrailingSeparator(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
|
||||
If path.EndsWith(Separator) AndAlso Not path.Length <= 3 Then
|
||||
Return path.TrimEnd(Separator)
|
||||
End If
|
||||
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function FixSeperator(path As String) As String
|
||||
If path.Contains("\") AndAlso Separator <> "\" Then
|
||||
path = path.Replace("\", Separator)
|
||||
End If
|
||||
|
||||
If path.Contains("/") AndAlso Separator <> "/" Then
|
||||
path = path.Replace("/", Separator)
|
||||
End If
|
||||
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetParent(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
Dim temp = TrimTrailingSeparator(path)
|
||||
If temp.Contains(Separator) Then path = temp.LeftLast(Separator) + Separator
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetName(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
path = TrimTrailingSeparator(path)
|
||||
Return path.RightLast(Separator)
|
||||
End Function
|
||||
|
||||
Shared Function IsInSysDir(path As String) As Boolean
|
||||
If path = "" Then Return False
|
||||
If Not path.EndsWith("\") Then path += "\"
|
||||
Return path.ToUpper.Contains(Folder.Programs.ToUpper)
|
||||
End Function
|
||||
|
||||
Shared Function IsFixedDrive(path As String) As Boolean
|
||||
Try
|
||||
If path <> "" Then Return New DriveInfo(path).DriveType = DriveType.Fixed
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class FilePath
|
||||
Inherits PathBase
|
||||
|
||||
Private Value As String
|
||||
|
||||
Sub New(path As String)
|
||||
Value = path
|
||||
End Sub
|
||||
|
||||
Shared Function GetDir(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
If path.Contains("\") Then path = path.LeftLast("\") + "\"
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetDirAndBase(path As String) As String
|
||||
Return GetDir(path) + GetBase(path)
|
||||
End Function
|
||||
|
||||
Shared Function GetName(path As String) As String
|
||||
If Not path Is Nothing Then
|
||||
Dim index = path.LastIndexOf(IO.Path.DirectorySeparatorChar)
|
||||
|
||||
If index > -1 Then
|
||||
Return path.Substring(index + 1)
|
||||
End If
|
||||
End If
|
||||
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetExtFull(filepath As String) As String
|
||||
Return GetExt(filepath, True)
|
||||
End Function
|
||||
|
||||
Shared Function GetExt(filepath As String) As String
|
||||
Return GetExt(filepath, False)
|
||||
End Function
|
||||
|
||||
Shared Function GetExt(filepath As String, dot As Boolean) As String
|
||||
If filepath = "" Then Return ""
|
||||
Dim chars = filepath.ToCharArray
|
||||
|
||||
For x = filepath.Length - 1 To 0 Step -1
|
||||
If chars(x) = Separator Then Return ""
|
||||
If chars(x) = "."c Then Return filepath.Substring(x + If(dot, 0, 1)).ToLower
|
||||
Next
|
||||
|
||||
Return ""
|
||||
End Function
|
||||
|
||||
Shared Function GetDirNoSep(path As String) As String
|
||||
path = GetDir(path)
|
||||
If path.EndsWith(Separator) Then path = TrimSep(path)
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetBase(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
Dim ret = path
|
||||
If ret.Contains(Separator) Then ret = ret.RightLast(Separator)
|
||||
If ret.Contains(".") Then ret = ret.LeftLast(".")
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
Shared Function TrimSep(path As String) As String
|
||||
If path = "" Then Return ""
|
||||
|
||||
If path.EndsWith(Separator) AndAlso Not path.EndsWith(":" + Separator) Then
|
||||
Return path.TrimEnd(Separator)
|
||||
End If
|
||||
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function GetDirNameOnly(path As String) As String
|
||||
Return FilePath.GetDirNoSep(path).RightLast("\")
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Class OS
|
||||
Shared Function GetTextEditor() As String
|
||||
Dim ret = GetAssociatedApplication(".txt")
|
||||
If ret <> "" Then Return ret
|
||||
Return "notepad.exe"
|
||||
End Function
|
||||
|
||||
Shared Function GetAssociatedApplication(ext As String) As String
|
||||
Dim c = 0UI
|
||||
|
||||
'ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
|
||||
If 1 = Native.AssocQueryString(&H40, 2, ext, Nothing, Nothing, c) Then
|
||||
If c > 0 Then
|
||||
Dim sb As New StringBuilder(CInt(c))
|
||||
|
||||
'ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
|
||||
If 0 = Native.AssocQueryString(&H40, 2, ext, Nothing, sb, c) Then
|
||||
Dim ret = sb.ToString
|
||||
If File.Exists(ret) Then Return ret
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Function
|
||||
End Class
|
||||
13
vbnet/My Project/Application.Designer.vb
generated
13
vbnet/My Project/Application.Designer.vb
generated
@@ -1,13 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<MySubMain>false</MySubMain>
|
||||
<SingleInstance>false</SingleInstance>
|
||||
<ShutdownMode>0</ShutdownMode>
|
||||
<EnableVisualStyles>true</EnableVisualStyles>
|
||||
<AuthenticationMode>0</AuthenticationMode>
|
||||
<ApplicationType>1</ApplicationType>
|
||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||
</MyApplicationData>
|
||||
@@ -1,35 +0,0 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
' General Information about an assembly is controlled through the following
|
||||
' set of attributes. Change these attribute values to modify the information
|
||||
' associated with an assembly.
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("vbnet")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("vbnet")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2017")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
<Assembly: Guid("82111131-50ca-475d-afda-bafda7e5bf69")>
|
||||
|
||||
' Version information for an assembly consists of the following four values:
|
||||
'
|
||||
' Major Version
|
||||
' Minor Version
|
||||
' Build Number
|
||||
' Revision
|
||||
'
|
||||
' You can specify all the values or you can default the Build and Revision Numbers
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.0.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.0.0.0")>
|
||||
63
vbnet/My Project/Resources.Designer.vb
generated
63
vbnet/My Project/Resources.Designer.vb
generated
@@ -1,63 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
'class via a tool like ResGen or Visual Studio.
|
||||
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
'with the /str option, or rebuild your VS project.
|
||||
'''<summary>
|
||||
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' Returns the cached ResourceManager instance used by this class.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("vbnet.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Overrides the current thread's CurrentUICulture property for all
|
||||
''' resource lookups using this strongly typed resource class.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
73
vbnet/My Project/Settings.Designer.vb
generated
73
vbnet/My Project/Settings.Designer.vb
generated
@@ -1,73 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0"), _
|
||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Partial Friend NotInheritable Class MySettings
|
||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||
|
||||
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||
|
||||
#Region "My.Settings Auto-Save Functionality"
|
||||
#If _MyType = "WindowsForms" Then
|
||||
Private Shared addedHandler As Boolean
|
||||
|
||||
Private Shared addedHandlerLockObject As New Object
|
||||
|
||||
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||
If My.Application.SaveMySettingsOnExit Then
|
||||
My.Settings.Save()
|
||||
End If
|
||||
End Sub
|
||||
#End If
|
||||
#End Region
|
||||
|
||||
Public Shared ReadOnly Property [Default]() As MySettings
|
||||
Get
|
||||
|
||||
#If _MyType = "WindowsForms" Then
|
||||
If Not addedHandler Then
|
||||
SyncLock addedHandlerLockObject
|
||||
If Not addedHandler Then
|
||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||
addedHandler = True
|
||||
End If
|
||||
End SyncLock
|
||||
End If
|
||||
#End If
|
||||
Return defaultInstance
|
||||
End Get
|
||||
End Property
|
||||
End Class
|
||||
End Namespace
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||
Friend Module MySettingsProperty
|
||||
|
||||
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||
Friend ReadOnly Property Settings() As Global.vbnet.My.MySettings
|
||||
Get
|
||||
Return Global.vbnet.My.MySettings.Default
|
||||
End Get
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
278
vbnet/Native.vb
278
vbnet/Native.vb
@@ -1,278 +0,0 @@
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
|
||||
Public Class Native
|
||||
Public Delegate Function CallbackHandler(handle As IntPtr, parameter As Integer) As Boolean
|
||||
|
||||
<DllImport("gdi32.dll")>
|
||||
Public Shared Function ExcludeClipRect(hdc As IntPtr, nLeftRect As Integer, nTopRect As Integer, nRightRect As Integer, nBottomRect As Integer) As Integer
|
||||
End Function
|
||||
|
||||
#Region "Constants"
|
||||
|
||||
Friend Const EM_SETCUEBANNER As Integer = &H1501
|
||||
Friend Const CB_SETCUEBANNER As Integer = &H1703
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "Function"
|
||||
|
||||
#Region "user32.dll"
|
||||
<DllImport("user32.dll", SetLastError:=True)>
|
||||
Shared Function SetWindowPos(hWnd As IntPtr,
|
||||
hWndInsertAfter As IntPtr,
|
||||
X As Integer,
|
||||
Y As Integer,
|
||||
cx As Integer,
|
||||
cy As Integer,
|
||||
uFlags As UInteger) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function GetWindowLong(hWnd As IntPtr, nIndex As Integer) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function RegisterWindowMessage(id As String) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function MapVirtualKey(wCode As Integer, wMapType As Integer) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function GetForegroundWindow() As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", SetLastError:=True)>
|
||||
Shared Function GetWindowThreadProcessId(hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function SetForegroundWindow(handle As IntPtr) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function GetWindowModuleFileName(hwnd As IntPtr,
|
||||
lpszFileName As StringBuilder,
|
||||
cchFileNameMax As UInteger) As UInteger
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function SendMessage(handle As IntPtr,
|
||||
message As Int32,
|
||||
wParam As IntPtr,
|
||||
lParam As IntPtr) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SendMessage(hWnd As IntPtr,
|
||||
Msg As Int32,
|
||||
wParam As IntPtr,
|
||||
lParam As String) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SendMessage(hWnd As IntPtr,
|
||||
Msg As Int32,
|
||||
wParam As Integer,
|
||||
lParam As Integer) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SendMessage(hWnd As IntPtr,
|
||||
Msg As Int32,
|
||||
wParam As Integer,
|
||||
lParam As String) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SendMessage(hWnd As IntPtr,
|
||||
Msg As Int32,
|
||||
ByRef wParam As IntPtr,
|
||||
lParam As StringBuilder) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function SendMessageTimeout(windowHandle As IntPtr,
|
||||
msg As Integer,
|
||||
wParam As IntPtr,
|
||||
lParam As IntPtr,
|
||||
flags As Integer,
|
||||
timeout As Integer,
|
||||
ByRef result As IntPtr) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function PostMessage(hwnd As IntPtr,
|
||||
wMsg As Integer,
|
||||
wParam As IntPtr,
|
||||
lParam As IntPtr) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Sub ReleaseCapture()
|
||||
End Sub
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "kernel32.dll"
|
||||
|
||||
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function LoadLibrary(path As String) As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("kernel32.dll", SetLastError:=True)>
|
||||
Shared Function FreeLibrary(hModule As IntPtr) As Boolean
|
||||
End Function
|
||||
|
||||
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
|
||||
Shared Function FormatMessage(dwFlags As Integer,
|
||||
lpSource As IntPtr,
|
||||
dwMessageId As Integer,
|
||||
dwLanguageId As Integer,
|
||||
ByRef lpBuffer As String,
|
||||
nSize As Integer,
|
||||
Arguments As IntPtr) As Integer
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
<DllImport("uxtheme.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SetWindowTheme(hWnd As IntPtr,
|
||||
pszSubAppName As String,
|
||||
pszSubIdList As String) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("Shlwapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
|
||||
Shared Function AssocQueryString(
|
||||
flags As UInteger,
|
||||
str As UInteger,
|
||||
pszAssoc As String,
|
||||
pszExtra As String,
|
||||
pszOut As StringBuilder,
|
||||
ByRef pcchOut As UInteger) As UInteger
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "Structures"
|
||||
|
||||
Public Structure RECT
|
||||
Public Left As Integer
|
||||
Public Top As Integer
|
||||
Public Right As Integer
|
||||
Public Bottom As Integer
|
||||
|
||||
Sub New(r As Rectangle)
|
||||
Left = r.Left
|
||||
Top = r.Top
|
||||
Right = r.Right
|
||||
Bottom = r.Bottom
|
||||
End Sub
|
||||
|
||||
Public Sub New(left As Integer, top As Integer, right As Integer, bottom As Integer)
|
||||
Me.Left = left
|
||||
Me.Top = top
|
||||
Me.Right = right
|
||||
Me.Bottom = bottom
|
||||
End Sub
|
||||
|
||||
Function ToRectangle() As Rectangle
|
||||
Return Rectangle.FromLTRB(Left, Top, Right, Bottom)
|
||||
End Function
|
||||
End Structure
|
||||
|
||||
Public Structure SHFILEINFO
|
||||
Public hIcon As IntPtr
|
||||
Public iIcon As Integer
|
||||
Public dwAttributes As Integer
|
||||
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
|
||||
Public szDisplayName As String
|
||||
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
|
||||
Public szTypeName As String
|
||||
End Structure
|
||||
|
||||
Public Structure NMHDR
|
||||
Public hwndFrom As Integer
|
||||
Public idFrom As Integer
|
||||
Public code As Integer
|
||||
End Structure
|
||||
|
||||
Public Structure NCCALCSIZE_PARAMS
|
||||
Public rgrc0, rgrc1, rgrc2 As RECT
|
||||
Public lppos As IntPtr
|
||||
End Structure
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
Public Class Taskbar
|
||||
Private Taskbar As ITaskbarList3 = DirectCast(New TaskBarCommunication(), ITaskbarList3)
|
||||
|
||||
Property Handle As IntPtr
|
||||
|
||||
Public Sub New(handle As IntPtr)
|
||||
Me.Handle = handle
|
||||
End Sub
|
||||
|
||||
<ComImportAttribute>
|
||||
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)>
|
||||
<GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")>
|
||||
Private Interface ITaskbarList3
|
||||
'ITaskbarList
|
||||
<PreserveSig> Sub HrInit()
|
||||
<PreserveSig> Sub AddTab(hwnd As IntPtr)
|
||||
<PreserveSig> Sub DeleteTab(hwnd As IntPtr)
|
||||
<PreserveSig> Sub ActivateTab(hwnd As IntPtr)
|
||||
<PreserveSig> Sub SetActiveAlt(hwnd As IntPtr)
|
||||
'ITaskbarList2
|
||||
<PreserveSig> Sub MarkFullscreenWindow(hwnd As IntPtr, <MarshalAs(UnmanagedType.Bool)> fFullscreen As Boolean)
|
||||
'ITaskbarList3
|
||||
<PreserveSig> Sub SetProgressValue(hwnd As IntPtr, ullCompleted As UInt64, ullTotal As UInt64)
|
||||
<PreserveSig> Sub SetProgressState(hwnd As IntPtr, state As TaskbarStates)
|
||||
End Interface
|
||||
|
||||
<ComImportAttribute>
|
||||
<ClassInterfaceAttribute(ClassInterfaceType.None)>
|
||||
<GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")>
|
||||
Private Class TaskBarCommunication
|
||||
End Class
|
||||
|
||||
Public Sub SetState(taskbarState As TaskbarStates)
|
||||
Taskbar.SetProgressState(Handle, taskbarState)
|
||||
End Sub
|
||||
|
||||
Public Sub SetValue(progressValue As Double, progressMax As Double)
|
||||
Taskbar.SetProgressValue(Handle, CULng(Math.Truncate(progressValue)), CULng(Math.Truncate(progressMax)))
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Enum TaskbarStates
|
||||
NoProgress = 0
|
||||
Indeterminate = &H1
|
||||
Normal = &H2
|
||||
[Error] = &H4
|
||||
Paused = &H8
|
||||
End Enum
|
||||
@@ -1,551 +0,0 @@
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
Imports System.Text.RegularExpressions
|
||||
|
||||
Namespace UI
|
||||
Public Delegate Function PFTASKDIALOGCALLBACK(hwnd As IntPtr,
|
||||
msg As UInteger,
|
||||
wParam As IntPtr,
|
||||
lParam As IntPtr,
|
||||
lpRefData As IntPtr) As Integer
|
||||
Public Class TaskDialog(Of T)
|
||||
Inherits TaskDialog
|
||||
Implements IDisposable
|
||||
|
||||
Private IdValueDic As New Dictionary(Of Integer, T)
|
||||
Private IdTextDic As New Dictionary(Of Integer, String)
|
||||
Private CommandLinkShieldList As New List(Of Integer)
|
||||
Private ButtonArray As IntPtr, RadioButtonArray As IntPtr
|
||||
Private Buttons As New List(Of TASKDIALOG_BUTTON)
|
||||
Private RadioButtons As New List(Of TASKDIALOG_BUTTON)
|
||||
|
||||
Private Config As TASKDIALOGCONFIG
|
||||
|
||||
Sub New()
|
||||
Config = New TASKDIALOGCONFIG()
|
||||
|
||||
Config.cbSize = CUInt(Marshal.SizeOf(Config))
|
||||
Config.hwndParent = GetHandle()
|
||||
Config.hInstance = IntPtr.Zero
|
||||
Config.dwFlags = Flags.TDF_ALLOW_DIALOG_CANCELLATION
|
||||
Config.dwCommonButtons = TaskDialogButtons.None
|
||||
Config.MainIcon = New TASKDIALOGCONFIG_ICON_UNION(0)
|
||||
Config.FooterIcon = New TASKDIALOGCONFIG_ICON_UNION(0)
|
||||
Config.cxWidth = 0
|
||||
|
||||
Config.cButtons = 0
|
||||
Config.cRadioButtons = 0
|
||||
Config.pButtons = IntPtr.Zero
|
||||
Config.pRadioButtons = IntPtr.Zero
|
||||
Config.nDefaultButton = 0
|
||||
Config.nDefaultRadioButton = 0
|
||||
|
||||
Config.pszWindowTitle = Application.ProductName
|
||||
Config.pszMainInstruction = ""
|
||||
Config.pszContent = ""
|
||||
Config.pszVerificationText = Nothing
|
||||
Config.pszExpandedInformation = Nothing
|
||||
Config.pszExpandedControlText = Nothing
|
||||
Config.pszCollapsedControlText = Nothing
|
||||
Config.pszFooter = Nothing
|
||||
|
||||
Config.pfCallback = New PFTASKDIALOGCALLBACK(AddressOf DialogProc)
|
||||
End Sub
|
||||
|
||||
Function GetHandle() As IntPtr
|
||||
Dim r As New StringBuilder(260)
|
||||
Dim h = GetForegroundWindow()
|
||||
GetWindowModuleFileName(h, r, 260)
|
||||
If r.ToString.Replace(".vshost", "").Base = Application.ExecutablePath.Base Then Return h
|
||||
End Function
|
||||
|
||||
#Region "Constants"
|
||||
Const TDE_CONTENT As Integer = 0
|
||||
Const TDE_EXPANDED_INFORMATION As Integer = 1
|
||||
Const TDE_FOOTER As Integer = 2
|
||||
Const TDE_MAIN_INSTRUCTION As Integer = 3
|
||||
|
||||
Const TDN_CREATED As Integer = 0
|
||||
Const TDN_NAVIGATED As Integer = 1
|
||||
Const TDN_BUTTON_CLICKED As Integer = 2
|
||||
Const TDN_HYPERLINK_CLICKED As Integer = 3
|
||||
Const TDN_TIMER As Integer = 4
|
||||
Const TDN_DESTROYED As Integer = 5
|
||||
Const TDN_RADIO_BUTTON_CLICKED As Integer = 6
|
||||
Const TDN_DIALOG_CONSTRUCTED As Integer = 7
|
||||
Const TDN_VERIFICATION_CLICKED As Integer = 8
|
||||
Const TDN_HELP As Integer = 9
|
||||
Const TDN_EXPANDO_BUTTON_CLICKED As Integer = 10
|
||||
|
||||
Const TDM_NAVIGATE_PAGE As Integer = &H400 + 101
|
||||
Const TDM_CLICK_BUTTON As Integer = &H400 + 102 'wParam = Button ID
|
||||
Const TDM_SET_MARQUEE_PROGRESS_BAR As Integer = &H400 + 103 'wParam = 0 (nonMarque) wParam != 0 (Marquee)
|
||||
Const TDM_SET_PROGRESS_BAR_STATE As Integer = &H400 + 104 'wParam = new progress state
|
||||
Const TDM_SET_PROGRESS_BAR_RANGE As Integer = &H400 + 105 'lParam = MAKELPARAM(nMinRange, nMaxRange)
|
||||
Const TDM_SET_PROGRESS_BAR_POS As Integer = &H400 + 106 'wParam = new position
|
||||
Const TDM_SET_PROGRESS_BAR_MARQUEE As Integer = &H400 + 107 'wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
|
||||
Const TDM_SET_ELEMENT_TEXT As Integer = &H400 + 108 'wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
|
||||
Const TDM_CLICK_RADIO_BUTTON As Integer = &H400 + 110 'wParam = Radio Button ID
|
||||
Const TDM_ENABLE_BUTTON As Integer = &H400 + 111 'lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
|
||||
Const TDM_ENABLE_RADIO_BUTTON As Integer = &H400 + 112 'lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
|
||||
Const TDM_CLICK_VERIFICATION As Integer = &H400 + 113 'wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
|
||||
Const TDM_UPDATE_ELEMENT_TEXT As Integer = &H400 + 114 'wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
|
||||
Const TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE As Integer = &H400 + 115 'wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required)
|
||||
Const TDM_UPDATE_ICON As Integer = &H400 + 116 'wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise)
|
||||
#End Region
|
||||
|
||||
#Region "Properties"
|
||||
|
||||
Private AllowCancelValue As Boolean
|
||||
|
||||
WriteOnly Property AllowCancel() As Boolean
|
||||
Set(Value As Boolean)
|
||||
If Value Then
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_ALLOW_DIALOG_CANCELLATION
|
||||
ElseIf (Config.dwFlags And Flags.TDF_ALLOW_DIALOG_CANCELLATION) = Flags.TDF_ALLOW_DIALOG_CANCELLATION Then
|
||||
Config.dwFlags = Config.dwFlags Xor Flags.TDF_ALLOW_DIALOG_CANCELLATION
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property MainInstruction() As String
|
||||
Get
|
||||
Return Config.pszMainInstruction
|
||||
End Get
|
||||
Set(Value As String)
|
||||
Config.pszMainInstruction = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property Content() As String
|
||||
Get
|
||||
Return Config.pszContent
|
||||
End Get
|
||||
Set(Value As String)
|
||||
Config.pszContent = ExpandWikiMarkup(Value)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property ExpandedInformation() As String
|
||||
Get
|
||||
Return Config.pszExpandedInformation
|
||||
End Get
|
||||
Set(Value As String)
|
||||
Config.pszExpandedInformation = ExpandWikiMarkup(Value)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property VerificationText() As String
|
||||
Get
|
||||
Return Config.pszVerificationText
|
||||
End Get
|
||||
Set(Value As String)
|
||||
Config.pszVerificationText = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property DefaultButton() As DialogResult
|
||||
Get
|
||||
Return CType(Config.nDefaultButton, DialogResult)
|
||||
End Get
|
||||
Set(Value As DialogResult)
|
||||
Config.nDefaultButton = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property Footer() As String
|
||||
Get
|
||||
Return Config.pszFooter
|
||||
End Get
|
||||
Set(Value As String)
|
||||
Config.pszFooter = ExpandWikiMarkup(Value)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
WriteOnly Property MainIcon() As TaskDialogIcon
|
||||
Set(Value As TaskDialogIcon)
|
||||
Config.MainIcon = New TASKDIALOGCONFIG_ICON_UNION(Value)
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private SelectedIDValue As Integer = -1
|
||||
|
||||
Property SelectedID As Integer
|
||||
Get
|
||||
Return SelectedIDValue
|
||||
End Get
|
||||
Set(value As Integer)
|
||||
For Each i In IdValueDic
|
||||
If i.Key = value Then SelectedIDValue = value
|
||||
Next
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private SelectedValueValue As T
|
||||
|
||||
Property SelectedValue() As T
|
||||
Get
|
||||
If IdValueDic.ContainsKey(SelectedID) Then Return IdValueDic(SelectedID)
|
||||
Return SelectedValueValue
|
||||
End Get
|
||||
Set(value As T)
|
||||
SelectedValueValue = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private SelectedTextValue As String
|
||||
|
||||
Property SelectedText() As String
|
||||
Get
|
||||
If IdTextDic.ContainsKey(SelectedID) Then Return IdTextDic(SelectedID)
|
||||
Return SelectedTextValue
|
||||
End Get
|
||||
Set(value As String)
|
||||
SelectedTextValue = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property CheckBoxChecked() As Boolean
|
||||
Get
|
||||
Return (Config.dwFlags And Flags.TDF_VERIFICATION_FLAG_CHECKED) = Flags.TDF_VERIFICATION_FLAG_CHECKED
|
||||
End Get
|
||||
Set(value As Boolean)
|
||||
If value Then
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_VERIFICATION_FLAG_CHECKED
|
||||
ElseIf CheckBoxChecked Then
|
||||
Config.dwFlags = Config.dwFlags Xor Flags.TDF_VERIFICATION_FLAG_CHECKED
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private CommonButtonsValue As TaskDialogButtons
|
||||
|
||||
Property CommonButtons() As TaskDialogButtons
|
||||
Get
|
||||
Return Config.dwCommonButtons
|
||||
End Get
|
||||
Set(Value As TaskDialogButtons)
|
||||
Config.dwCommonButtons = Value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private TimeoutValue As Integer
|
||||
|
||||
Property Timeout As Integer
|
||||
Get
|
||||
Return CInt(TimeoutValue / 1000)
|
||||
End Get
|
||||
Set(Value As Integer)
|
||||
TimeoutValue = Value * 1000
|
||||
|
||||
If Value > 0 Then
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_CALLBACK_TIMER
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
#End Region
|
||||
|
||||
#Region "Methods"
|
||||
|
||||
Sub AddButton(text As String, value As T)
|
||||
Dim id = 1000 + IdValueDic.Count + 1
|
||||
IdValueDic(id) = value
|
||||
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
|
||||
End Sub
|
||||
|
||||
Function ExpandWikiMarkup(value As String) As String
|
||||
If value.Contains("[") Then
|
||||
Dim re As New Regex("\[(\w+?:.*?) (.+?)\]")
|
||||
Dim m = re.Match(value)
|
||||
|
||||
If m.Success Then
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_ENABLE_HYPERLINKS
|
||||
value = re.Replace(value, "<a href=""$1"">$2</a>")
|
||||
End If
|
||||
End If
|
||||
|
||||
Return value
|
||||
End Function
|
||||
|
||||
Sub AddCommandLink(text As String, value As T)
|
||||
Dim id = 1000 + IdValueDic.Count + 1
|
||||
IdValueDic(id) = value
|
||||
IdTextDic(id) = text
|
||||
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_USE_COMMAND_LINKS
|
||||
End Sub
|
||||
|
||||
Sub AddCommandLink(text As String,
|
||||
description As String,
|
||||
value As T,
|
||||
Optional setShield As Boolean = False)
|
||||
|
||||
Dim id = 1000 + IdValueDic.Count + 1
|
||||
IdValueDic(id) = value
|
||||
If setShield Then CommandLinkShieldList.Add(id)
|
||||
If description <> "" Then text = text + BR + description
|
||||
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
|
||||
Config.dwFlags = Config.dwFlags Or Flags.TDF_USE_COMMAND_LINKS
|
||||
End Sub
|
||||
|
||||
Sub AddRadioButton(text As String, value As T)
|
||||
Dim id = 1000 + IdValueDic.Count + 1
|
||||
IdValueDic(id) = value
|
||||
RadioButtons.Add(New TASKDIALOG_BUTTON(id, text))
|
||||
End Sub
|
||||
|
||||
Function Show() As T
|
||||
MarshalDialogControlStructs()
|
||||
Dim isChecked As Boolean
|
||||
Dim hr = TaskDialogIndirect(Config, Nothing, Nothing, isChecked)
|
||||
CheckBoxChecked = isChecked
|
||||
If hr < 0 Then Marshal.ThrowExceptionForHR(hr)
|
||||
If TypeOf SelectedValue Is DialogResult Then SelectedValue = DirectCast(CObj(SelectedID), T)
|
||||
Return SelectedValue
|
||||
End Function
|
||||
|
||||
Private ExitTickCount As Integer
|
||||
|
||||
Private Function DialogProc(hwnd As IntPtr,
|
||||
msg As UInteger,
|
||||
wParam As IntPtr,
|
||||
lParam As IntPtr,
|
||||
lpRefData As IntPtr) As Integer
|
||||
Select Case msg
|
||||
Case TDN_BUTTON_CLICKED, TDN_RADIO_BUTTON_CLICKED
|
||||
If TypeOf SelectedValue Is DialogResult Then
|
||||
SelectedIDValue = wParam.ToInt32
|
||||
Else
|
||||
SelectedID = wParam.ToInt32
|
||||
End If
|
||||
Case TDN_TIMER
|
||||
If ExitTickCount = 0 Then
|
||||
ExitTickCount = Environment.TickCount + Timeout * 1000
|
||||
End If
|
||||
|
||||
If Environment.TickCount > ExitTickCount Then
|
||||
SendMessage(hwnd, TDM_CLICK_BUTTON, DialogResult.OK, 0)
|
||||
End If
|
||||
Case TDN_HYPERLINK_CLICKED
|
||||
Dim url = Marshal.PtrToStringUni(lParam)
|
||||
|
||||
If url.StartsWith("mailto:") OrElse url Like "http*://*" Then
|
||||
ProcessHelp.Start(url)
|
||||
ElseIf url = "copymsg:" Then
|
||||
Clipboard.SetText(MainInstruction + BR2 + Content + BR2 + ExpandedInformation)
|
||||
MsgBox("Message was copied to clipboard.", MessageBoxIcon.Information)
|
||||
End If
|
||||
Case TDN_CREATED
|
||||
For Each i In CommandLinkShieldList
|
||||
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, i, 1)
|
||||
Next
|
||||
End Select
|
||||
|
||||
Return 0
|
||||
End Function
|
||||
|
||||
Private Sub MarshalDialogControlStructs()
|
||||
If Not Buttons Is Nothing AndAlso Buttons.Count > 0 Then
|
||||
ButtonArray = AllocateAndMarshalButtons(Buttons)
|
||||
Config.pButtons = ButtonArray
|
||||
Config.cButtons = CUInt(Buttons.Count)
|
||||
End If
|
||||
|
||||
If Not RadioButtons Is Nothing AndAlso RadioButtons.Count > 0 Then
|
||||
RadioButtonArray = AllocateAndMarshalButtons(RadioButtons)
|
||||
Config.pRadioButtons = RadioButtonArray
|
||||
Config.cRadioButtons = CUInt(RadioButtons.Count)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Shared Function AllocateAndMarshalButtons(structs As List(Of TASKDIALOG_BUTTON)) As IntPtr
|
||||
Dim initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(TASKDIALOG_BUTTON)) * structs.Count)
|
||||
Dim currentPtr = initialPtr
|
||||
|
||||
For Each button In structs
|
||||
Marshal.StructureToPtr(button, currentPtr, False)
|
||||
currentPtr = CType((currentPtr.ToInt64 + Marshal.SizeOf(button)), IntPtr)
|
||||
Next
|
||||
|
||||
Return initialPtr
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
#Region "IDispose Pattern"
|
||||
|
||||
Private disposed As Boolean
|
||||
|
||||
Sub Dispose() Implements IDisposable.Dispose
|
||||
Dispose(True)
|
||||
GC.SuppressFinalize(Me)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub Finalize()
|
||||
Try
|
||||
Dispose(False)
|
||||
Finally
|
||||
MyBase.Finalize()
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Protected Sub Dispose(disposing As Boolean)
|
||||
If Not disposed Then
|
||||
disposed = True
|
||||
|
||||
If ButtonArray <> IntPtr.Zero Then
|
||||
Marshal.FreeHGlobal(ButtonArray)
|
||||
ButtonArray = IntPtr.Zero
|
||||
End If
|
||||
|
||||
If RadioButtonArray <> IntPtr.Zero Then
|
||||
Marshal.FreeHGlobal(RadioButtonArray)
|
||||
RadioButtonArray = IntPtr.Zero
|
||||
End If
|
||||
|
||||
If disposing Then
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
Public Class TaskDialog
|
||||
<DllImport("comctl32", CharSet:=CharSet.Unicode, SetLastError:=True)>
|
||||
Shared Function TaskDialogIndirect(<[In]()> pTaskConfig As TASKDIALOGCONFIG,
|
||||
<Out()> ByRef pnButton As Integer,
|
||||
<Out()> ByRef pnRadioButton As Integer,
|
||||
<MarshalAs(UnmanagedType.Bool)> <Out()> ByRef pVerificationFlagChecked As Boolean) As Integer
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll")>
|
||||
Shared Function GetForegroundWindow() As IntPtr
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function GetWindowModuleFileName(hwnd As IntPtr,
|
||||
lpszFileName As StringBuilder,
|
||||
cchFileNameMax As UInteger) As UInteger
|
||||
End Function
|
||||
|
||||
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
|
||||
Shared Function SendMessage(hWnd As IntPtr,
|
||||
Msg As Int32,
|
||||
wParam As Integer,
|
||||
lParam As Integer) As IntPtr
|
||||
End Function
|
||||
|
||||
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=4)>
|
||||
Public Class TASKDIALOGCONFIG
|
||||
Public cbSize As UInteger
|
||||
Public hwndParent As IntPtr
|
||||
Public hInstance As IntPtr
|
||||
Public dwFlags As Flags
|
||||
Public dwCommonButtons As TaskDialogButtons
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszWindowTitle As String
|
||||
Public MainIcon As TASKDIALOGCONFIG_ICON_UNION
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszMainInstruction As String
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszContent As String
|
||||
Public cButtons As UInteger
|
||||
Public pButtons As IntPtr
|
||||
Public nDefaultButton As Integer
|
||||
Public cRadioButtons As UInteger
|
||||
Public pRadioButtons As IntPtr
|
||||
Public nDefaultRadioButton As Integer
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszVerificationText As String
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszExpandedInformation As String
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszExpandedControlText As String
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszCollapsedControlText As String
|
||||
Public FooterIcon As TASKDIALOGCONFIG_ICON_UNION
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszFooter As String
|
||||
Public pfCallback As PFTASKDIALOGCALLBACK
|
||||
Public lpCallbackData As IntPtr
|
||||
Public cxWidth As UInteger
|
||||
End Class
|
||||
|
||||
'TASKDIALOG_FLAGS
|
||||
Public Enum Flags
|
||||
NONE = 0
|
||||
TDF_ENABLE_HYPERLINKS = &H1
|
||||
TDF_USE_HICON_MAIN = &H2
|
||||
TDF_USE_HICON_FOOTER = &H4
|
||||
TDF_ALLOW_DIALOG_CANCELLATION = &H8
|
||||
TDF_USE_COMMAND_LINKS = &H10
|
||||
TDF_USE_COMMAND_LINKS_NO_ICON = &H20
|
||||
TDF_EXPAND_FOOTER_AREA = &H40
|
||||
TDF_EXPANDED_BY_DEFAULT = &H80
|
||||
TDF_VERIFICATION_FLAG_CHECKED = &H100
|
||||
TDF_SHOW_PROGRESS_BAR = &H200
|
||||
TDF_SHOW_MARQUEE_PROGRESS_BAR = &H400
|
||||
TDF_CALLBACK_TIMER = &H800
|
||||
TDF_POSITION_RELATIVE_TO_WINDOW = &H1000
|
||||
TDF_RTL_LAYOUT = &H2000
|
||||
TDF_NO_DEFAULT_RADIO_BUTTON = &H4000
|
||||
End Enum
|
||||
|
||||
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Unicode)>
|
||||
Public Structure TASKDIALOGCONFIG_ICON_UNION
|
||||
Sub New(i As Integer)
|
||||
spacer = IntPtr.Zero
|
||||
pszIcon = 0
|
||||
hMainIcon = i
|
||||
End Sub
|
||||
|
||||
<FieldOffset(0)>
|
||||
Public hMainIcon As Integer
|
||||
<FieldOffset(0)>
|
||||
Public pszIcon As Integer
|
||||
<FieldOffset(0)>
|
||||
Public spacer As IntPtr
|
||||
End Structure
|
||||
|
||||
<StructLayout(LayoutKind.Sequential,
|
||||
CharSet:=CharSet.Unicode, Pack:=4)>
|
||||
Public Structure TASKDIALOG_BUTTON
|
||||
Sub New(n As Integer, txt As String)
|
||||
nButtonID = n
|
||||
pszButtonText = txt
|
||||
End Sub
|
||||
|
||||
Public nButtonID As Integer
|
||||
<MarshalAs(UnmanagedType.LPWStr)>
|
||||
Public pszButtonText As String
|
||||
End Structure
|
||||
End Class
|
||||
|
||||
Public Enum TaskDialogButtons
|
||||
None = &H0
|
||||
Ok = &H1
|
||||
Yes = &H2
|
||||
No = &H4
|
||||
Cancel = &H8
|
||||
Retry = &H10
|
||||
RetryCancel = Retry Or Cancel
|
||||
Close = &H20
|
||||
OkCancel = Ok Or Cancel
|
||||
YesNo = Yes Or No
|
||||
YesNoCancel = YesNo Or Cancel
|
||||
End Enum
|
||||
|
||||
Public Enum TaskDialogIcon
|
||||
Warning = 65535 'TD_WARNING_ICON
|
||||
[Error] = 65534 'TD_ERROR_ICON
|
||||
Info = 65533 'TD_INFORMATION_ICON
|
||||
Shield = 65532 'TD_SHIELD_ICON
|
||||
SecurityShieldBlue = 65531
|
||||
SecurityWarning = 65530
|
||||
SecurityError = 65529
|
||||
SecuritySuccess = 65528
|
||||
SecurityShieldGray = 65527
|
||||
End Enum
|
||||
End Namespace
|
||||
@@ -1,311 +0,0 @@
|
||||
Imports System.Drawing.Drawing2D
|
||||
Imports System.Drawing.Text
|
||||
Imports Microsoft.Win32
|
||||
|
||||
Namespace UI
|
||||
Public Class ToolStripRendererEx
|
||||
Inherits ToolStripSystemRenderer
|
||||
|
||||
Shared RenderMode As ToolStripRenderModeEx
|
||||
|
||||
Shared Property ColorChecked As Color
|
||||
Shared Property ColorBorder As Color
|
||||
Shared Property ColorTop As Color
|
||||
Shared Property ColorBottom As Color
|
||||
Shared Property ColorBackground As Color
|
||||
|
||||
Shared Property ColorToolStrip1 As Color
|
||||
Shared Property ColorToolStrip2 As Color
|
||||
Shared Property ColorToolStrip3 As Color
|
||||
Shared Property ColorToolStrip4 As Color
|
||||
|
||||
Private TextOffset As Integer
|
||||
|
||||
Sub New(mode As ToolStripRenderModeEx)
|
||||
RenderMode = mode
|
||||
InitColors(mode)
|
||||
End Sub
|
||||
|
||||
Shared Function IsAutoRenderMode() As Boolean
|
||||
Return _
|
||||
RenderMode = ToolStripRenderModeEx.SystemAuto OrElse
|
||||
RenderMode = ToolStripRenderModeEx.Win7Auto OrElse
|
||||
RenderMode = ToolStripRenderModeEx.Win10Auto
|
||||
End Function
|
||||
|
||||
Shared Sub InitColors(renderMode As ToolStripRenderModeEx)
|
||||
If ToolStripRendererEx.IsAutoRenderMode Then
|
||||
Dim argb = CInt(Registry.GetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", 0))
|
||||
If argb = 0 Then argb = Color.LightBlue.ToArgb
|
||||
InitColors(Color.FromArgb(argb))
|
||||
Else
|
||||
ColorBorder = Color.FromArgb(&HFF83ABDC)
|
||||
ColorTop = Color.FromArgb(&HFFE7F0FB)
|
||||
ColorBottom = Color.FromArgb(&HFFCCE1FB)
|
||||
ColorBackground = SystemColors.Control
|
||||
|
||||
ColorToolStrip1 = Color.FromArgb(&HFFFDFEFF)
|
||||
ColorToolStrip2 = Color.FromArgb(&HFFE6F0FA)
|
||||
ColorToolStrip3 = Color.FromArgb(&HFFDCE6F4)
|
||||
ColorToolStrip4 = Color.FromArgb(&HFFDDE9F7)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Shared Sub InitColors(c As Color)
|
||||
ColorBorder = HSLColor.Convert(c).ToColorSetLuminosity(100)
|
||||
ColorChecked = HSLColor.Convert(c).ToColorSetLuminosity(200)
|
||||
ColorBottom = HSLColor.Convert(c).ToColorSetLuminosity(220)
|
||||
ColorBackground = HSLColor.Convert(c).ToColorSetLuminosity(230)
|
||||
ColorTop = HSLColor.Convert(c).ToColorSetLuminosity(240)
|
||||
|
||||
ColorToolStrip1 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 1)))
|
||||
ColorToolStrip2 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.7)))
|
||||
ColorToolStrip3 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.1)))
|
||||
ColorToolStrip4 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.4)))
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderToolStripBorder(e As ToolStripRenderEventArgs)
|
||||
ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, Color.FromArgb(160, 175, 195), ButtonBorderStyle.Solid)
|
||||
End Sub
|
||||
|
||||
Protected Overloads Overrides Sub OnRenderItemText(e As ToolStripItemTextRenderEventArgs)
|
||||
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias
|
||||
|
||||
If TypeOf e.Item Is ToolStripMenuItem AndAlso Not TypeOf e.Item.Owner Is MenuStrip Then
|
||||
Dim r = e.TextRectangle
|
||||
|
||||
Dim dropDown = TryCast(e.ToolStrip, ToolStripDropDownMenu)
|
||||
|
||||
If dropDown Is Nothing OrElse dropDown.ShowImageMargin OrElse dropDown.ShowCheckMargin Then
|
||||
TextOffset = CInt(e.Item.Height * 1.1)
|
||||
Else
|
||||
TextOffset = CInt(e.Item.Height * 0.2)
|
||||
End If
|
||||
|
||||
e.TextRectangle = New Rectangle(TextOffset, CInt((e.Item.Height - r.Height) / 2), r.Width, r.Height)
|
||||
End If
|
||||
|
||||
MyBase.OnRenderItemText(e)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderToolStripBackground(e As ToolStripRenderEventArgs)
|
||||
If Not TypeOf e.ToolStrip Is ToolStripDropDownMenu AndAlso
|
||||
Not e.ToolStrip.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow Then
|
||||
|
||||
Dim r As New Rectangle(-1, -1, e.AffectedBounds.Width, e.AffectedBounds.Height)
|
||||
|
||||
If IsFlat() Then
|
||||
Using b As New SolidBrush(ColorToolStrip2)
|
||||
e.Graphics.FillRectangle(b, r)
|
||||
End Using
|
||||
Else
|
||||
Dim cb As New ColorBlend()
|
||||
cb.Colors = {ColorToolStrip1, ColorToolStrip2, ColorToolStrip3, ColorToolStrip4}
|
||||
cb.Positions = {0.0F, 0.5F, 0.5F, 1.0F}
|
||||
|
||||
Using b As New LinearGradientBrush(r, ColorToolStrip1, ColorToolStrip4, 90)
|
||||
b.InterpolationColors = cb
|
||||
e.Graphics.FillRectangle(b, r)
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderMenuItemBackground(e As ToolStripItemRenderEventArgs)
|
||||
e.Item.ForeColor = Color.Black
|
||||
|
||||
Dim left = 22
|
||||
Dim r = New Rectangle(Point.Empty, e.Item.Size)
|
||||
Dim g = e.Graphics
|
||||
|
||||
If Not TypeOf e.Item.Owner Is MenuStrip Then
|
||||
g.Clear(ColorBackground)
|
||||
End If
|
||||
|
||||
If e.Item.Selected AndAlso e.Item.Enabled Then
|
||||
If TypeOf e.Item.Owner Is MenuStrip Then
|
||||
DrawButton(e)
|
||||
Else
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias
|
||||
|
||||
Dim r2 = New Rectangle(r.X + 2, r.Y, r.Width - 4, r.Height - 1)
|
||||
|
||||
If IsFlat() Then
|
||||
Using pen As New Pen(ColorBorder)
|
||||
g.DrawRectangle(pen, r2)
|
||||
End Using
|
||||
|
||||
r2.Inflate(-1, -1)
|
||||
|
||||
Using b As New SolidBrush(ColorBottom)
|
||||
g.FillRectangle(b, r2)
|
||||
End Using
|
||||
Else
|
||||
Using path = CreateRoundRectangle(r2, 3)
|
||||
Using b As New LinearGradientBrush(r2,
|
||||
ControlPaint.LightLight(ControlPaint.LightLight(ColorTop)),
|
||||
ControlPaint.LightLight(ControlPaint.LightLight(ColorBottom)),
|
||||
90.0F)
|
||||
g.FillPath(b, path)
|
||||
End Using
|
||||
|
||||
Using p As New Pen(ColorBorder)
|
||||
g.DrawPath(p, path)
|
||||
End Using
|
||||
End Using
|
||||
|
||||
r2.Inflate(-1, -1)
|
||||
|
||||
Using path = CreateRoundRectangle(r2, 3)
|
||||
Using b As New LinearGradientBrush(r2, ColorTop, ColorBottom, 90.0F)
|
||||
g.FillPath(b, path)
|
||||
End Using
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Sub DrawButton(e As ToolStripItemRenderEventArgs)
|
||||
Dim g = e.Graphics
|
||||
Dim r = New Rectangle(Point.Empty, e.Item.Size)
|
||||
Dim r2 = New Rectangle(r.X, r.Y, r.Width - 1, r.Height - 1)
|
||||
|
||||
If IsFlat() Then
|
||||
Using pen As New Pen(ColorBorder)
|
||||
g.DrawRectangle(pen, r2)
|
||||
End Using
|
||||
|
||||
r2.Inflate(-1, -1)
|
||||
|
||||
Dim tsb = TryCast(e.Item, ToolStripButton)
|
||||
|
||||
If Not tsb Is Nothing AndAlso tsb.Checked Then
|
||||
Using brush As New SolidBrush(ColorChecked)
|
||||
g.FillRectangle(brush, r2)
|
||||
End Using
|
||||
Else
|
||||
Using brush As New SolidBrush(ColorBottom)
|
||||
g.FillRectangle(brush, r2)
|
||||
End Using
|
||||
End If
|
||||
Else
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias
|
||||
|
||||
Dim c1 = HSLColor.Convert(ColorToolStrip1).ToColorAddLuminosity(15)
|
||||
Dim c2 = HSLColor.Convert(ColorToolStrip2).ToColorAddLuminosity(15)
|
||||
Dim c3 = HSLColor.Convert(ColorToolStrip3).ToColorAddLuminosity(15)
|
||||
Dim c4 = HSLColor.Convert(ColorToolStrip4).ToColorAddLuminosity(15)
|
||||
|
||||
Dim cb As New ColorBlend()
|
||||
|
||||
cb.Colors = {c1, c2, c3, c4}
|
||||
cb.Positions = {0.0F, 0.5F, 0.5F, 1.0F}
|
||||
|
||||
Using path = CreateRoundRectangle(r2, 3)
|
||||
Using b As New LinearGradientBrush(r2, c1, c4, 90)
|
||||
b.InterpolationColors = cb
|
||||
g.FillPath(b, path)
|
||||
End Using
|
||||
|
||||
Using p As New Pen(ColorBorder)
|
||||
g.DrawPath(p, path)
|
||||
End Using
|
||||
End Using
|
||||
|
||||
r2.Inflate(-1, -1)
|
||||
|
||||
c1 = HSLColor.Convert(ColorToolStrip1).ToColorAddLuminosity(5)
|
||||
c2 = HSLColor.Convert(ColorToolStrip2).ToColorAddLuminosity(5)
|
||||
c3 = HSLColor.Convert(ColorToolStrip3).ToColorAddLuminosity(-10)
|
||||
c4 = HSLColor.Convert(ColorToolStrip4).ToColorAddLuminosity(-10)
|
||||
|
||||
cb.Colors = {c1, c2, c3, c4}
|
||||
cb.Positions = {0.0F, 0.5F, 0.5F, 1.0F}
|
||||
|
||||
Using b As New LinearGradientBrush(r2, c1, c4, 90)
|
||||
b.InterpolationColors = cb
|
||||
|
||||
Using path = CreateRoundRectangle(r2, 3)
|
||||
g.FillPath(b, path)
|
||||
End Using
|
||||
End Using
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderDropDownButtonBackground(e As ToolStripItemRenderEventArgs)
|
||||
If e.Item.Selected Then DrawButton(e)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderButtonBackground(e As ToolStripItemRenderEventArgs)
|
||||
Dim button = DirectCast(e.Item, ToolStripButton)
|
||||
If e.Item.Selected OrElse button.Checked Then DrawButton(e)
|
||||
End Sub
|
||||
|
||||
Protected Overloads Overrides Sub OnRenderArrow(e As ToolStripArrowRenderEventArgs)
|
||||
Dim value = If(e.Direction = ArrowDirection.Down, &H36, &H34)
|
||||
Dim s = Convert.ToChar(value).ToString
|
||||
Dim font = New Font("Marlett", e.Item.Font.Size - 2)
|
||||
Dim size = e.Graphics.MeasureString(s, font)
|
||||
Dim x = CInt(e.Item.Width - size.Width)
|
||||
Dim y = CInt((e.Item.Height - size.Height) / 2) + 1
|
||||
e.Graphics.DrawString(s, font, Brushes.Black, x, y)
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub OnRenderItemCheck(e As ToolStripItemImageRenderEventArgs)
|
||||
Dim x = CInt(e.ImageRectangle.Height * 0.2)
|
||||
e.Graphics.DrawImage(e.Image, New Point(x, x))
|
||||
End Sub
|
||||
|
||||
Protected Overloads Overrides Sub OnRenderSeparator(e As ToolStripSeparatorRenderEventArgs)
|
||||
If e.Item.IsOnDropDown Then
|
||||
e.Graphics.Clear(ColorBackground)
|
||||
Dim right = e.Item.Width - CInt(TextOffset / 5)
|
||||
Dim top = e.Item.Height \ 2
|
||||
top -= 1
|
||||
Dim b = e.Item.Bounds
|
||||
|
||||
Using p As New Pen(Color.Gray)
|
||||
e.Graphics.DrawLine(p, New Point(TextOffset, top), New Point(right, top))
|
||||
End Using
|
||||
ElseIf e.Vertical Then
|
||||
Dim b = e.Item.Bounds
|
||||
|
||||
Using p As New Pen(SystemColors.ControlDarkDark)
|
||||
e.Graphics.DrawLine(p, CInt(b.Width / 2), CInt(b.Height * 0.15), CInt(b.Width / 2), CInt(b.Height * 0.85))
|
||||
End Using
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Public Shared Function CreateRoundRectangle(r As Rectangle, radius As Integer) As GraphicsPath
|
||||
Dim path As New GraphicsPath()
|
||||
|
||||
Dim l = r.Left
|
||||
Dim t = r.Top
|
||||
Dim w = r.Width
|
||||
Dim h = r.Height
|
||||
Dim d = radius << 1
|
||||
|
||||
path.AddArc(l, t, d, d, 180, 90)
|
||||
path.AddLine(l + radius, t, l + w - radius, t)
|
||||
path.AddArc(l + w - d, t, d, d, 270, 90)
|
||||
path.AddLine(l + w, t + radius, l + w, t + h - radius)
|
||||
path.AddArc(l + w - d, t + h - d, d, d, 0, 90)
|
||||
path.AddLine(l + w - radius, t + h, l + radius, t + h)
|
||||
path.AddArc(l, t + h - d, d, d, 90, 90)
|
||||
path.AddLine(l, t + h - radius, l, t + radius)
|
||||
path.CloseFigure()
|
||||
|
||||
Return path
|
||||
End Function
|
||||
|
||||
Shared Function IsFlat() As Boolean
|
||||
If RenderMode = ToolStripRenderModeEx.Win10Default Then Return True
|
||||
If RenderMode = ToolStripRenderModeEx.Win10Auto Then Return True
|
||||
|
||||
If (RenderMode = ToolStripRenderModeEx.SystemDefault OrElse
|
||||
RenderMode = ToolStripRenderModeEx.SystemAuto) AndAlso
|
||||
OSVersion.Current >= OSVersion.Windows8 Then Return True
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
2108
vbnet/UI.vb
2108
vbnet/UI.vb
File diff suppressed because it is too large
Load Diff
@@ -1,123 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AF1B21C5-28FC-4D47-AD0B-54F6A38391A6}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>vbnet</RootNamespace>
|
||||
<AssemblyName>vbnet</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<NoWarn>42030,42104,42105,42106,42107,42108,42109,42353,42354,42355</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<NoWarn>42030,42104,42105,42106,42107,42108,42109,42353,42354,42355</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>On</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
<Import Include="System.Drawing" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Windows.Forms" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Extensions.vb" />
|
||||
<Compile Include="HSLColor.vb" />
|
||||
<Compile Include="MainModule.vb" />
|
||||
<Compile Include="MediaInfo.vb" />
|
||||
<Compile Include="Menu.vb">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Misc.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Resources.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Settings.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="Native.vb" />
|
||||
<Compile Include="TaskDialog.vb" />
|
||||
<Compile Include="ToolStripRendererEx.vb" />
|
||||
<Compile Include="UI.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
<None Include="My Project\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<CustomToolNamespace>My</CustomToolNamespace>
|
||||
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
Reference in New Issue
Block a user