Compare commits

...

22 Commits
3.4 ... 3.6.1

Author SHA1 Message Date
Frank Skare
2512c02bff 3.6.1 2019-05-23 00:51:15 +02:00
Frank Skare
351fae8344 - 2019-05-13 03:29:12 +02:00
Frank Skare
30b562a1e1 - 2019-05-13 03:23:33 +02:00
Frank Skare
8a9a017875 - 2019-05-13 03:22:31 +02:00
Frank Skare
fa0b0f496f - 2019-05-13 03:20:44 +02:00
Frank Skare
83b5d9b65c - 2019-05-13 03:19:17 +02:00
Frank Skare
b199d33f7a - 2019-05-13 03:00:41 +02:00
Frank Skare
a7b6f79ee1 - 2019-05-13 02:48:46 +02:00
Frank Skare
fc3c5ee3a7 - 2019-05-13 02:35:31 +02:00
Frank Skare
ed71cb704f - 2019-05-11 02:09:41 +02:00
Frank Skare
a9474b1c22 - 2019-05-11 00:49:38 +02:00
Frank Skare
be3b31f7e6 - 2019-05-09 19:16:48 +02:00
Frank Skare
b2884e2037 - 2019-05-09 12:41:58 +02:00
Frank Skare
3910776b54 - 2019-05-09 12:36:05 +02:00
Frank Skare
b37272db8b - 2019-05-09 12:28:17 +02:00
Frank Skare
08a23430c7 - 2019-05-05 04:02:10 +02:00
Frank Skare
ba41b8026f - 2019-05-04 19:15:18 +02:00
Frank Skare
4aeb00afb5 - 2019-05-04 19:04:18 +02:00
Frank Skare
6e6015b185 - 2019-05-04 15:10:00 +02:00
Frank Skare
68240ac49d - 2019-05-04 15:02:26 +02:00
Frank Skare
bafc481117 - 2019-05-04 14:53:42 +02:00
Frank Skare
9198d610ad - 2019-05-04 14:03:59 +02:00
40 changed files with 1213 additions and 872 deletions

View File

@@ -43,17 +43,18 @@ Table of contents
### Features
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu))
- Searchable config dialog ([Screenshot](#config-editor))
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor))
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette))
- Modern UI with dark mode ([Screenshot](#config-editor))
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu-screenshot))
- Searchable config dialog ([Screenshot](#config-editor-screenshot))
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot))
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
- Modern UI with dark mode ([Screenshot](#config-editor-screenshot))
- Addon/extension API for .NET languages
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
- mpv's OSC, IPC and conf files
- Support of the same [CLI options](https://mpv.io/manual/master/#options) as mpv
- DXVA2 video decoding acceleration
- OpenGL based video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
### Screenshots
@@ -86,6 +87,12 @@ Just press Ctrl+Shift+P and find it easily in the searchable command palette.
![Command Palette](https://raw.githubusercontent.com/stax76/mpv.net/master/img/CommandPalette.png)
#### Media Search Screenshot
Media search feature powered by [Everything](https://www.voidtools.com) to find and play media.
![Media Search](https://raw.githubusercontent.com/stax76/mpv.net/master/img/MediaSearch.png)
### Context Menu
The context menu can be customized via input.conf file located in the config directory:
@@ -102,43 +109,31 @@ input.conf defines mpv's key and mouse bindings and mpv.net uses comments to def
### Settings
mpv.net shares the settings with mpv, settings can be edited in a settings dialog or in a config file called mpv.conf located in the config directory:
mpv.net is able to share the settings with mpv and mpv.net uses the same logic to decide from where the settings are loaded. The default location is:
```Text
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
```
or in a portable setup at:
If a directory named portable_config next to the mpvnet.exe exists, all config will be loaded from this directory only.
```Text
<startup>\portable_config\mpv.conf
```
if it's missing mpv.net generates it with the following defaults:
In case there isn't any config folder mpv.net asks where to create it. If no mpv.conf file exists mpv.net generates it with the following defaults:
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt>
### Scripting
Config files located in the same directory as mpvnet.exe are loaded with lower priority. Some config files are loaded only once, which means that e.g. of 2 input.conf files located in two config directories, only the one from the directory with higher priority will be loaded.
Scripting is supported via Python, C#, Lua, JavaScript and PowerShell
### Scripting
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
### Add-ons
Add-ons are located in the config directory:
```Text
C:\Users\%username%\AppData\Roaming\mpv\Addons\ExampleAddon\ExampleAddon.dll
```
The add-on filename must end with 'Addon.dll'.
Examples:
[RatingAddon.cs](https://github.com/stax76/mpv.net/blob/master/RatingAddon/RatingAddon.cs)
[CSScriptAddon.vb](https://github.com/stax76/mpv.net/blob/master/CSScriptAddon/CSScriptAddon.vb)
[Add-on wiki page](https://github.com/stax76/mpv.net/wiki/Addons)
### Architecture
@@ -162,6 +157,7 @@ Third party components are:
- [MediaInfo](https://mediaarea.net/en/MediaInfo)
- [Tommy (TOML parser)](https://github.com/dezhidki/Tommy)
- [IronPython](https://ironpython.net/)
- [CS-Script](http://www.csscript.net/)
### Support
@@ -201,39 +197,30 @@ mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
### Changelog
### 3.4 (2019-05-03)
### 3.6.1
- there was a bug causing an exception if both the input editor and config editor
is opened, as soon as one is opened, the other can't be opened
### 3.6
- playing files from rar archives caused an exception
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
- the search clear button in the input editor had a render issue in dark mode
- new search feature added to search and play media files, requires
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L29)
### 3.5
- when the main windows gets activated and the clipboard content starts with http
mpv.net will ask to play the URL, previously this was restricted to YouTube URLs
- Python script errors show line and column whenever it is supported by IronPython
- if conf files exist in the startup directory mpv.net will use the startup
directory as config directory instead of creating default conf files in appdata
- renamed commands are handled now by migration code instead of being broken
### 3.4
- new feature added to manage file associations from within the app. It can be found in the menu at: Tools > Manage... [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L149)
- new zip download option added
- new x86 download option added
### 3.3 (2019-05-01)
- dark mode support was added to the command palette and partly to the input editor
- a new icon was designed. [Website](https://mpv-net.github.io/mpv.net-web-site/)
- all windows (main, conf, input, about, command palette) can now be closed
by just pressing the Escape key
- new feature added to open recent files and URLs with the context menu. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L33)
- the info command (i key) now works also for URLs
- CSScriptAddon add-on didn't load cs scripts from \<startup\>\\scripts
- error handling was improved by showing an improved message box that supports a text copy feature, a support link and text heading and text folding
- libmpv was updated
### 3.2 (2019-04-27)
- mpvInputEdit and mpvConfEdit were discontinued and merged into
mpvnet because separate apps were to difficult to work with
- portable mode: in case no config folder exists and the
startup folder has write access mpvnet will ask where
the config folder should be created (portable or appdata)
- there was an issue causing keys not working after a modal window was shown
- there was a crash when no script folder existed in the conf folder
- MediaInfo and youtube-dl were updated
- a new JavaScript example script was added to the wiki and the
script descriptions were improved. [Scripting Page](https://github.com/stax76/mpv.net/wiki/Scripting).
- greatly improved README.md file and [github startpage](https://github.com/stax76/mpv.net)
- About dialog added
- the input editor shows only a closing message if actually a change was made
- the input editor don't show confusing menu separators any longer. [Screenshot](https://github.com/stax76/mpv.net#input-editor)
- new Command Palette feature added. [Screenshot](https://github.com/stax76/mpv.net#command-palette), [Default input binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L141)
- the history feature had a bug causing files to be logged more than once
- new x86 download option added

View File

@@ -28,7 +28,7 @@ Public Class CSScriptAddon
Try
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
Catch ex As Exception
Sys.Msg.ShowException(ex)
Msg.ShowException(ex)
End Try
Next
End Sub

View File

@@ -51,7 +51,7 @@
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
<OutputPath>..\..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
@@ -72,7 +72,7 @@
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
<OutputPath>..\..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
@@ -156,7 +156,7 @@
<Content Include="CSScriptLibrary.dll" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
<Name>mpv.net</Name>
<Private>False</Private>

View File

@@ -32,7 +32,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
<OutputPath>..\..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
@@ -50,7 +50,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
<OutputPath>..\..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
@@ -82,7 +82,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
<Name>mpv.net</Name>
<Private>False</Private>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
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("TestAddon")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestAddon")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("06f854b0-00f9-4b53-94d9-0be65a7c55d8")]
// 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")]

View File

@@ -0,0 +1,27 @@
using System.ComponentModel.Composition;
using mpvnet;
namespace TestAddon
{
[Export(typeof(IAddon))]
public class TestAddon : IAddon
{
// do some init work in constructor
public TestAddon()
{
// Observe changes of the fullscreen property.
// You can find a list of available mpv properties
// in mpv.net's wiki on github or use mpv --list-properties.
// You can test properties in mpv.net in the menu at:
// Tools > Execute mpv command
// where you can enter: show-text ${fullscreen}
mp.observe_property_bool("fullscreen", OnFullscreenChange);
}
void OnFullscreenChange(bool val)
{
mp.commandv("show-text", "fullscreen: " + val.ToString());
}
}
}

View File

@@ -0,0 +1,56 @@
<?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>{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestAddon</RootNamespace>
<AssemblyName>TestAddon</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="TestAddon.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>

BIN
img/MediaSearch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -5,42 +5,70 @@ VisualStudioVersion = 16.0.28729.10
MinimumVisualStudioVersion = 10.0.40219.1
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}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "addons\CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "addons\RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAddon", "addons\TestAddon\TestAddon.csproj", "{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x86
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x86
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.Build.0 = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
{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
{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|x64
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.Build.0 = Debug|x64
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.ActiveCfg = Debug|x86
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.Build.0 = Debug|x86
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.Build.0 = Release|Any CPU
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.ActiveCfg = Release|x64
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|x64
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|x86
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|x86
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
{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
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.ActiveCfg = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.Build.0 = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.ActiveCfg = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.Build.0 = Debug|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.Build.0 = Release|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.ActiveCfg = Release|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.Build.0 = Release|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.ActiveCfg = Release|Any CPU
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -5,8 +5,6 @@ using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Windows.Forms;
using Sys;
namespace mpvnet
{
public class Addon

View File

@@ -7,8 +7,6 @@ using System.Reflection;
using System.Windows.Forms;
using System.Windows.Interop;
using Sys;
namespace mpvnet
{
public class Command
@@ -28,7 +26,7 @@ namespace mpvnet
Type type = typeof(Command);
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
foreach (var i in methods)
foreach (MethodInfo i in methods)
{
ParameterInfo[] parameters = i.GetParameters();
@@ -93,6 +91,15 @@ namespace mpvnet
}));
}
public static void show_media_search(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
var w = new EverythingWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_history(string[] args)
{
var fp = mp.MpvConfFolder + "history.txt";

View File

@@ -10,8 +10,6 @@ using System.ComponentModel;
using System.Globalization;
using System.Diagnostics;
using Sys;
namespace mpvnet
{
public partial class MainForm : Form
@@ -309,55 +307,32 @@ namespace mpvnet
public void BuildMenu()
{
string content = File.ReadAllText(mp.InputConfPath);
List<string> lines = null;
Dictionary<string, string> commandInputDic = new Dictionary<string, string>();
var items = CommandItem.GetItems(content);
if (content.Contains("#menu:"))
lines = content.Split("\r\n".ToCharArray()).ToList();
else
if (!content.Contains("#menu:"))
{
lines = Properties.Resources.inputConf.Split("\r\n".ToCharArray()).ToList();
foreach (string i in content.Split("\r\n".ToCharArray()))
{
string line = i.Trim();
if (line.StartsWith("#") || !line.Contains(" ")) continue;
string input = line.Substring(0, line.IndexOf(" ")).Trim();
string command = line.Substring(line.IndexOf(" ") + 1).Trim();
commandInputDic[command] = input;
}
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
foreach (CommandItem item in items)
foreach (CommandItem defaultItem in defaultItems)
if (item.Command == defaultItem.Command)
defaultItem.Input = item.Input;
items = defaultItems;
}
foreach (string line in lines)
foreach (CommandItem item in items)
{
if (!line.Contains("#menu:")) continue;
string left = line.Substring(0, line.IndexOf("#menu:")).Trim();
if (left.StartsWith("#")) continue;
string command = left.Substring(left.IndexOf(" ") + 1).Trim();
string menu = line.Substring(line.IndexOf("#menu:") + "#menu:".Length).Trim();
string input = left.Substring(0, left.IndexOf(" "));
if (input == "_") input = "";
if (menu.Contains(";")) input = menu.Substring(0, menu.IndexOf(";")).Trim();
string path = menu.Substring(menu.IndexOf(";") + 1).Trim().Replace("&", "&&");
if (path == "" || command == "") continue;
if (commandInputDic.Count > 0)
if (commandInputDic.ContainsKey(command))
input = commandInputDic[command];
else
input = "";
if (string.IsNullOrEmpty(item.Path))
continue;
string path = item.Path.Replace("&", "&&");
MenuItem menuItem = ContextMenu.Add(path, () => {
try {
mp.command_string(command);
}
catch (Exception ex) {
mp.command_string(item.Command);
} catch (Exception ex) {
Msg.ShowException(ex);
}
});
if (menuItem != null)
menuItem.ShortcutKeyDisplayString = input + " ";
menuItem.ShortcutKeyDisplayString = item.Input + " ";
}
}
@@ -366,7 +341,12 @@ namespace mpvnet
private void Mp_FileLoaded()
{
string path = mp.get_property_string("path");
BeginInvoke(new Action(() => { Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion; }));
BeginInvoke(new Action(() => {
if (File.Exists(path) || path.StartsWith("http"))
Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion;
else
Text = "mpv.net " + Application.ProductVersion;
}));
if (RecentFiles.Contains(path)) RecentFiles.Remove(path);
RecentFiles.Insert(0, path);
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
@@ -568,7 +548,7 @@ namespace mpvnet
BuildMenu();
ContextMenuStrip = ContextMenu;
IgnoreDpiChanged = false;
CheckYouTube();
CheckURL();
}
protected override void OnFormClosed(FormClosedEventArgs e)
@@ -588,18 +568,18 @@ namespace mpvnet
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
CheckYouTube();
CheckURL();
}
void CheckYouTube()
void CheckURL()
{
string clipboard = Clipboard.GetText();
if (clipboard.StartsWith("https://www.youtube.com/watch?") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastYouTubeURL") != clipboard && Visible)
if (clipboard.StartsWith("http") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastURL") != clipboard && Visible)
{
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastYouTubeURL", clipboard);
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastURL", clipboard);
if (Msg.ShowQuestion("Play YouTube URL?", clipboard) == MsgResult.OK)
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
mp.LoadFiles(clipboard);
}
}

View File

@@ -17,16 +17,13 @@ namespace mpvnet
{
public class App
{
public static string[] VideoTypes { get; } = "mpg avi vob mp4 mkv avs 264 mov wmv flv h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts webm m4v".Split(" ".ToCharArray());
public static string[] AudioTypes { get; } = "mp2 mp3 ac3 wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 ogg mka aac opus flac mpa".Split(" ".ToCharArray());
public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(" ".ToCharArray());
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(" ".ToCharArray());
public static bool IsDarkMode {
get {
string darkMode = MainForm.Instance.MpvNetDarkMode;
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
if (value is null) value = 1;
bool isDarkTheme = (int)value == 0;
return (darkMode == "system" && isDarkTheme) || darkMode == "always";
return (darkMode == "system" && Sys.IsDarkTheme) || darkMode == "always";
}
}
}
@@ -175,7 +172,6 @@ namespace mpvnet
public int ID { get; set; }
}
[Serializable]
public class CommandItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
@@ -202,46 +198,70 @@ namespace mpvnet
}
}
public static ObservableCollection<CommandItem> GetItems(string content)
{
var items = new ObservableCollection<CommandItem>();
if (!string.IsNullOrEmpty(content))
{
foreach (string line in content.Split('\r', '\n'))
{
string val = line.Trim();
if (val.StartsWith("#")) continue;
if (!val.Contains(" ")) continue;
CommandItem item = new CommandItem();
item.Input = val.Substring(0, val.IndexOf(" "));
if (item.Input == "_") item.Input = "";
val = val.Substring(val.IndexOf(" ") + 1);
if (val.Contains("#menu:"))
{
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
val = val.Substring(0, val.IndexOf("#menu:"));
if (item.Path.Contains(";"))
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
}
item.Command = val.Trim();
if (item.Command == "")
continue;
if (item.Command.ToLower() == "ignore")
item.Command = "";
MigrateCommands(item);
items.Add(item);
}
}
return items;
}
private static ObservableCollection<CommandItem> _Items;
public static ObservableCollection<CommandItem> Items {
get {
if (_Items is null)
{
_Items = new ObservableCollection<CommandItem>();
if (File.Exists(mp.InputConfPath))
{
foreach (string line in File.ReadAllLines(mp.InputConfPath))
{
string val = line.Trim();
if (val.StartsWith("#")) continue;
if (!val.Contains(" ")) continue;
CommandItem item = new CommandItem();
item.Input = val.Substring(0, val.IndexOf(" ")).Replace("_", "");
val = val.Substring(val.IndexOf(" ") + 1);
if (val.Contains("#menu:"))
{
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
val = val.Substring(0, val.IndexOf("#menu:"));
if (item.Path.Contains(";"))
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
}
item.Command = val.Trim();
if (item.Command == "")
continue;
if (item.Command.ToLower() == "ignore")
item.Command = "";
_Items.Add(item);
}
}
}
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
return _Items;
}
}
public static void MigrateCommands(CommandItem item)
{
switch (item.Command)
{
case "script-message mpv.net show-prefs":
item.Command = "script-message mpv.net show-conf-editor";
break;
case "script-message mpv.net show-keys":
item.Command = "script-message mpv.net show-input-editor";
break;
case "script-message mpv.net history":
item.Command = "script-message mpv.net show-history";
break;
case "script-message mpv.net open-config-folder":
item.Command = "script-message open-conf-folder";
break;
}
}
}
public class CursorHelp

View File

@@ -5,8 +5,6 @@ using System.Management.Automation.Runspaces;
using System.Reflection;
using System.Threading.Tasks;
using Sys;
namespace mpvnet
{
public class PowerShellScript

View File

@@ -1,8 +1,6 @@
using System;
using System.Windows.Forms;
using Sys;
namespace mpvnet
{
static class Program

View File

@@ -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("3.4.0.0")]
[assembly: AssemblyFileVersion("3.4.0.0")]
[assembly: AssemblyVersion("3.6.1.0")]
[assembly: AssemblyFileVersion("3.6.1.0")]

View File

@@ -1,10 +1,12 @@
using System;
using System.Reflection;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
using Sys;
using PyRT = IronPython.Runtime;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
namespace mpvnet
{
@@ -22,35 +24,36 @@ namespace mpvnet
scope.ImportModule("clr");
engine.Execute("import clr", scope);
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
engine.Execute("import mpvnet", scope);
engine.Execute("from mpvnet import *", scope);
engine.Execute(code, scope);
}
catch (Exception ex)
{
Msg.ShowException(ex);
if (ex is SyntaxErrorException e)
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message);
else
Msg.ShowException(ex);
}
}
}
public class PythonEventObject
{
public PyRT.PythonFunction PythonFunction { get; set; }
public PythonFunction PythonFunction { get; set; }
public EventInfo EventInfo { get; set; }
public Delegate Delegate { get; set; }
public void Invoke()
{
PyRT.Operations.PythonCalls.Call(PythonFunction);
}
public void Invoke() => PythonCalls.Call(PythonFunction);
public void InvokeEndFileEventMode(EndFileEventMode arg)
{
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
PythonCalls.Call(PythonFunction, new[] { arg });
}
public void InvokeStrings(string[] arg)
{
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
PythonCalls.Call(PythonFunction, new[] { arg });
}
}
}

View File

@@ -26,6 +26,7 @@
o script-message mpv.net open-files #menu: Open > Open Files...
u script-message mpv.net open-url #menu: Open > Open URL...
Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search...
_ ignore #menu: Open > -
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
@@ -90,8 +91,8 @@
KP7 script-message mpv.net cycle-audio #menu: Audio > Cycle/Next
_ ignore #menu: Audio > -
KP6 add audio-delay 0.100 #menu: Audio > Delay +0.1
KP9 add audio-delay -0.100 #menu: Audio > Delay -0.1
KP6 add audio-delay 0.1 #menu: Audio > Delay +0.1
KP9 add audio-delay -0.1 #menu: Audio > Delay -0.1
KP8 cycle sub #menu: Subtitle > Cycle/Next
v cycle sub-visibility #menu: Subtitle > Toggle Visibility
@@ -112,7 +113,7 @@
_ ignore #menu: Volume > -
m cycle mute #menu: Volume > Mute
[ multiply speed 0.9 #menu: Speed > -10%
[ multiply speed 1/1.1 #menu: Speed > -10%
] multiply speed 1.1 #menu: Speed > +10%
_ ignore #menu: Speed > -
{ multiply speed 0.5 #menu: Speed > Half
@@ -174,4 +175,6 @@
Wheel_Up add volume 10
Wheel_Down add volume -10
Prev playlist-prev
Next playlist-next
Next playlist-next
MBTN_LEFT_DBL cycle fullscreen

View File

@@ -1,659 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace Sys
{
public class Msg
{
private static string ShownMessages;
public static string SupportURL { get; set; }
public static void Show(string mainInstruction, string content = null)
{
Msg.Show(mainInstruction, content, MsgIcon.Info, MsgButtons.Ok, MsgResult.None);
}
public static void ShowError(string mainInstruction, string content = null)
{
try
{
using (TaskDialog<string> td = new TaskDialog<string>())
{
td.AllowCancel = false;
if (string.IsNullOrEmpty(content))
{
if (mainInstruction.Length < 80)
td.MainInstruction = mainInstruction;
else
td.Content = mainInstruction;
}
else
{
td.MainInstruction = mainInstruction;
td.Content = content;
}
td.MainIcon = MsgIcon.Error;
td.Footer = "[Copy Message](copymsg)";
if (!string.IsNullOrEmpty(Msg.SupportURL))
td.Footer += $" [Contact Support]({SupportURL})";
td.Show();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static void ShowException(Exception e)
{
try
{
using (TaskDialog<string> td = new TaskDialog<string>())
{
td.MainInstruction = e.GetType().Name;
td.Content = e.Message;
td.MainIcon = MsgIcon.Error;
td.ExpandedInformation = e.ToString();
td.Footer = "[Copy Message](copymsg)";
if (!string.IsNullOrEmpty(Msg.SupportURL))
td.Footer += $" [Contact Support]({SupportURL})";
td.Show();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static void ShowWarning(string mainInstruction,
string content = null,
bool onlyOnce = false)
{
if (onlyOnce && Msg.ShownMessages != null &&
Msg.ShownMessages.Contains(mainInstruction + content))
return;
Msg.Show(mainInstruction, content, MsgIcon.Warning, MsgButtons.Ok, MsgResult.None);
if (!onlyOnce) return;
Msg.ShownMessages += mainInstruction + content;
}
public static MsgResult ShowQuestion(string mainInstruction,
MsgButtons buttons = MsgButtons.OkCancel)
{
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
}
public static MsgResult ShowQuestion(string mainInstruction,
string content,
MsgButtons buttons = MsgButtons.OkCancel)
{
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
}
public static MsgResult Show(string mainInstruction,
string content,
MsgIcon icon,
MsgButtons buttons,
MsgResult defaultButton = MsgResult.None)
{
try
{
using (TaskDialog<MsgResult> td = new TaskDialog<MsgResult>())
{
td.AllowCancel = false;
td.DefaultButton = defaultButton;
td.MainIcon = icon;
if (content == null)
{
if (mainInstruction.Length < 80)
td.MainInstruction = mainInstruction;
else
td.Content = mainInstruction;
}
else
{
td.MainInstruction = mainInstruction;
td.Content = content;
}
if (buttons == MsgButtons.OkCancel)
{
td.AddButton("OK", MsgResult.OK);
td.AddButton("Cancel", MsgResult.Cancel);
}
else
td.CommonButtons = buttons;
return td.Show();
}
}
catch (Exception ex)
{
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class TaskDialog<T> : TaskDialogNative, IDisposable
{
private Dictionary<int, T> IdValueDic;
private Dictionary<int, string> IdTextDic;
private List<int> CommandLinkShieldList;
private IntPtr ButtonArray;
private IntPtr RadioButtonArray;
private List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
private List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
private TaskDialogNative.TASKDIALOGCONFIG Config;
const int TDE_CONTENT = 0;
const int TDE_EXPANDED_INFORMATION = 1;
const int TDE_FOOTER = 2;
const int TDE_MAIN_INSTRUCTION = 3;
const int TDN_CREATED = 0;
const int TDN_NAVIGATED = 1;
const int TDN_BUTTON_CLICKED = 2;
const int TDN_HYPERLINK_CLICKED = 3;
const int TDN_TIMER = 4;
const int TDN_DESTROYED = 5;
const int TDN_RADIO_BUTTON_CLICKED = 6;
const int TDN_DIALOG_CONSTRUCTED = 7;
const int TDN_VERIFICATION_CLICKED = 8;
const int TDN_HELP = 9;
const int TDN_EXPANDO_BUTTON_CLICKED = 10;
const int TDM_NAVIGATE_PAGE = 1125;
const int TDM_CLICK_BUTTON = 1126;
const int TDM_SET_MARQUEE_PROGRESS_BAR = 1127;
const int TDM_SET_PROGRESS_BAR_STATE = 1128;
const int TDM_SET_PROGRESS_BAR_RANGE = 1129;
const int TDM_SET_PROGRESS_BAR_POS = 1130;
const int TDM_SET_PROGRESS_BAR_MARQUEE = 1131;
const int TDM_SET_ELEMENT_TEXT = 1132;
const int TDM_CLICK_RADIO_BUTTON = 1134;
const int TDM_ENABLE_BUTTON = 1135;
const int TDM_ENABLE_RADIO_BUTTON = 1136;
const int TDM_CLICK_VERIFICATION = 1137;
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
const int TDM_UPDATE_ICON = 1140;
private T SelectedValueValue;
private string SelectedTextValue;
private int TimeoutValue;
private int ExitTickCount;
private bool disposed;
public TaskDialog()
{
IdValueDic = new Dictionary<int, T>();
IdTextDic = new Dictionary<int, string>();
CommandLinkShieldList = new List<int>();
Buttons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
RadioButtons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
_SelectedID = -1;
Config = new TaskDialogNative.TASKDIALOGCONFIG();
Config.cbSize = (uint)Marshal.SizeOf(Config);
Config.hwndParent = GetHandle();
Config.hInstance = IntPtr.Zero;
Config.dwFlags = TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
Config.dwCommonButtons = MsgButtons.None;
Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
Config.FooterIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
Config.cxWidth = 0U;
Config.cButtons = 0U;
Config.cRadioButtons = 0U;
Config.pButtons = IntPtr.Zero;
Config.pRadioButtons = IntPtr.Zero;
Config.nDefaultButton = 0;
Config.nDefaultRadioButton = 0;
Config.pszWindowTitle = ((AssemblyProductAttribute)Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0]).Product;
Config.pszMainInstruction = "";
Config.pszContent = "";
Config.pfCallback = new PFTASKDIALOGCALLBACK(this.DialogProc);
}
public IntPtr GetHandle()
{
StringBuilder lpszFileName = new StringBuilder(260);
IntPtr foregroundWindow = TaskDialogNative.GetForegroundWindow();
TaskDialogNative.GetWindowModuleFileName(foregroundWindow, lpszFileName, 260U);
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
Path.GetFileName(Assembly.GetEntryAssembly().Location))
return foregroundWindow;
return IntPtr.Zero;
}
public bool AllowCancel {
set {
if (value)
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
else
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
}
}
public string MainInstruction {
get => Config.pszMainInstruction;
set => Config.pszMainInstruction = value;
}
public string Content {
get => Config.pszContent;
set => Config.pszContent = ExpandMarkdownMarkup(value);
}
public string ExpandedInformation {
get => Config.pszExpandedInformation;
set => Config.pszExpandedInformation = ExpandMarkdownMarkup(value);
}
public string VerificationText {
get => Config.pszVerificationText;
set => Config.pszVerificationText = value;
}
public MsgResult DefaultButton {
get => (MsgResult)Config.nDefaultButton;
set => Config.nDefaultButton = (int)value;
}
public string Footer {
get => Config.pszFooter;
set => Config.pszFooter = ExpandMarkdownMarkup(value);
}
public MsgIcon MainIcon {
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
}
private int _SelectedID;
public int SelectedID {
get => _SelectedID;
set {
foreach (var i in IdValueDic)
if (i.Key == value) _SelectedID = value;
}
}
public T SelectedValue {
get {
if (IdValueDic.ContainsKey(SelectedID))
return IdValueDic[SelectedID];
return SelectedValueValue;
}
set => SelectedValueValue = value;
}
public string SelectedText {
get {
if (IdTextDic.ContainsKey(SelectedID))
return IdTextDic[SelectedID];
return SelectedTextValue;
}
set => SelectedTextValue = value;
}
public bool CheckBoxChecked {
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) == TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
set {
if (value)
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
else
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
}
}
public MsgButtons CommonButtons {
get => Config.dwCommonButtons;
set => Config.dwCommonButtons = value;
}
public int Timeout {
get => Convert.ToInt32(TimeoutValue / 1000.0);
set {
TimeoutValue = value * 1000;
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_CALLBACK_TIMER;
}
}
public void AddButton(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
}
public string ExpandMarkdownMarkup(string value)
{
if (value.Contains("["))
{
Regex regex = new Regex(@"\[(.+)\]\((.+)\)");
if (regex.Match(value).Success)
{
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS;
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
}
}
return value;
}
public void AddCommandLink(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value == null ? (T)(object)text : value;
IdTextDic[n] = text;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
}
public void AddCommandLink(string text, string description, T value, bool setShield = false)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
if (setShield) CommandLinkShieldList.Add(n);
if (!string.IsNullOrEmpty(description)) text += "\n" + description;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
}
public void AddRadioButton(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
RadioButtons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
}
public T Show()
{
MarshalDialogControlStructs();
TaskDialogNative.TASKDIALOGCONFIG config = Config;
int errorCode = TaskDialogNative.TaskDialogIndirect(config, out int dummy1, out int dummy2, out bool isChecked);
if (errorCode < 0) Marshal.ThrowExceptionForHR(errorCode);
CheckBoxChecked = isChecked;
if (SelectedValue is MsgResult) SelectedValue = (T)(object)SelectedID;
return SelectedValue;
}
public int DialogProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr lpRefData)
{
switch (msg)
{
case 0: //TDN_CREATED
foreach (var i in CommandLinkShieldList)
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, new IntPtr(i), new IntPtr(1));
break;
case 2: //TDN_BUTTON_CLICKED
case 6: //TDN_RADIO_BUTTON_CLICKED
if (SelectedValue is MsgResult)
_SelectedID = wParam.ToInt32();
else
SelectedID = wParam.ToInt32();
break;
case 3: //TDN_HYPERLINK_CLICKED
string stringUni = Marshal.PtrToStringUni(lParam);
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
Process.Start(stringUni);
if (stringUni == "copymsg")
{
Thread thread = new Thread((ThreadStart)(() => {
Clipboard.SetText(MainInstruction + "\r\n\r\n" + Content + "\r\n\r\n" + ExpandedInformation);
MessageBox.Show("Message was copied to clipboard.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
break;
case 4: //TDN_TIMER
if (ExitTickCount == 0) ExitTickCount = Environment.TickCount + Timeout * 1000;
if (Environment.TickCount > ExitTickCount)
TaskDialogNative.SendMessage(hwnd, 1126, new IntPtr(1), IntPtr.Zero);
break;
}
return 0;
}
public void MarshalDialogControlStructs()
{
if (Buttons != null && Buttons.Count > 0)
{
ButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(Buttons);
Config.pButtons = ButtonArray;
Config.cButtons = (uint)Buttons.Count;
}
if (RadioButtons == null || RadioButtons.Count <= 0) return;
RadioButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(RadioButtons);
Config.pRadioButtons = RadioButtonArray;
Config.cRadioButtons = (uint)RadioButtons.Count;
}
public static IntPtr AllocateAndMarshalButtons(List<TaskDialogNative.TASKDIALOG_BUTTON> structs)
{
var initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TASKDIALOG_BUTTON)) * structs.Count);
var currentPtr = initialPtr;
foreach (var button in structs)
{
Marshal.StructureToPtr(button, currentPtr, false);
currentPtr = (IntPtr)(currentPtr.ToInt64() + Marshal.SizeOf(button));
}
return initialPtr;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~TaskDialog()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposed) return;
disposed = true;
if (ButtonArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(ButtonArray);
ButtonArray = IntPtr.Zero;
}
if (RadioButtonArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(RadioButtonArray);
RadioButtonArray = IntPtr.Zero;
}
}
}
public delegate int PFTASKDIALOGCALLBACK(
IntPtr hwnd,
uint msg,
IntPtr wParam,
IntPtr lParam,
IntPtr lpRefData);
public class TaskDialogNative
{
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int TaskDialogIndirect(
[In] TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
out int pnButton,
out int pnRadioButton,
[MarshalAs(UnmanagedType.Bool)] out bool pVerificationFlagChecked);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern uint GetWindowModuleFileName(
IntPtr hwnd,
StringBuilder lpszFileName,
uint cchFileNameMax);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(
IntPtr handle,
int message,
IntPtr wParam,
IntPtr lParam);
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
public class TASKDIALOGCONFIG
{
public uint cbSize;
public IntPtr hwndParent;
public IntPtr hInstance;
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
public MsgButtons dwCommonButtons;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszWindowTitle;
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszMainInstruction;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszContent;
public uint cButtons;
public IntPtr pButtons;
public int nDefaultButton;
public uint cRadioButtons;
public IntPtr pRadioButtons;
public int nDefaultRadioButton;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszVerificationText;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszExpandedInformation;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszExpandedControlText;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszCollapsedControlText;
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszFooter;
public PFTASKDIALOGCALLBACK pfCallback;
public IntPtr lpCallbackData;
public uint cxWidth;
}
public enum TASKDIALOG_FLAGS
{
NONE = 0,
TDF_ENABLE_HYPERLINKS = 1,
TDF_USE_HICON_MAIN = 2,
TDF_USE_HICON_FOOTER = 4,
TDF_ALLOW_DIALOG_CANCELLATION = 8,
TDF_USE_COMMAND_LINKS = 16,
TDF_USE_COMMAND_LINKS_NO_ICON = 32,
TDF_EXPAND_FOOTER_AREA = 64,
TDF_EXPANDED_BY_DEFAULT = 128,
TDF_VERIFICATION_FLAG_CHECKED = 256,
TDF_SHOW_PROGRESS_BAR = 512,
TDF_SHOW_MARQUEE_PROGRESS_BAR = 1024,
TDF_CALLBACK_TIMER = 2048,
TDF_POSITION_RELATIVE_TO_WINDOW = 4096,
TDF_RTL_LAYOUT = 8192,
TDF_NO_DEFAULT_RADIO_BUTTON = 16384,
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct TASKDIALOGCONFIG_ICON_UNION
{
[FieldOffset(0)]
public int hMainIcon;
[FieldOffset(0)]
public int pszIcon;
[FieldOffset(0)]
public IntPtr spacer;
public TASKDIALOGCONFIG_ICON_UNION(int i)
{
this = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION();
spacer = IntPtr.Zero;
pszIcon = 0;
hMainIcon = i;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
public struct TASKDIALOG_BUTTON
{
public int nButtonID;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszButtonText;
public TASKDIALOG_BUTTON(int n, string txt)
{
this = new TaskDialogNative.TASKDIALOG_BUTTON();
nButtonID = n;
pszButtonText = txt;
}
}
}
public enum MsgButtons
{
None = 0,
Ok = 1,
Yes = 2,
No = 4,
YesNo = 6,
Cancel = 8,
OkCancel = 9,
YesNoCancel = 14,
Retry = 16,
RetryCancel = 24,
Close = 32,
}
public enum MsgResult
{
None,
OK,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No,
}
public enum MsgIcon
{
None = 0,
SecurityShieldGray = 65527,
SecuritySuccess = 65528,
SecurityError = 65529,
SecurityWarning = 65530,
SecurityShieldBlue = 65531,
Shield = 65532,
Info = 65533,
Error = 65534,
Warning = 65535,
}
}

656
mpv.net/TaskDialog.cs Normal file
View File

@@ -0,0 +1,656 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
public class Msg
{
private static string ShownMessages;
public static string SupportURL { get; set; }
public static void Show(string mainInstruction, string content = null)
{
Msg.Show(mainInstruction, content, MsgIcon.Info, MsgButtons.Ok, MsgResult.None);
}
public static void ShowError(string mainInstruction, string content = null)
{
try
{
using (TaskDialog<string> td = new TaskDialog<string>())
{
td.AllowCancel = false;
if (string.IsNullOrEmpty(content))
{
if (mainInstruction.Length < 80)
td.MainInstruction = mainInstruction;
else
td.Content = mainInstruction;
}
else
{
td.MainInstruction = mainInstruction;
td.Content = content;
}
td.MainIcon = MsgIcon.Error;
td.Footer = "[Copy Message](copymsg)";
if (!string.IsNullOrEmpty(Msg.SupportURL))
td.Footer += $" [Contact Support]({SupportURL})";
td.Show();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static void ShowException(Exception e)
{
try
{
using (TaskDialog<string> td = new TaskDialog<string>())
{
td.MainInstruction = e.GetType().Name;
td.Content = e.Message;
td.MainIcon = MsgIcon.Error;
td.ExpandedInformation = e.ToString();
td.Footer = "[Copy Message](copymsg)";
if (!string.IsNullOrEmpty(Msg.SupportURL))
td.Footer += $" [Contact Support]({SupportURL})";
td.Show();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static void ShowWarning(string mainInstruction,
string content = null,
bool onlyOnce = false)
{
if (onlyOnce && Msg.ShownMessages != null &&
Msg.ShownMessages.Contains(mainInstruction + content))
return;
Msg.Show(mainInstruction, content, MsgIcon.Warning, MsgButtons.Ok, MsgResult.None);
if (!onlyOnce) return;
Msg.ShownMessages += mainInstruction + content;
}
public static MsgResult ShowQuestion(string mainInstruction,
MsgButtons buttons = MsgButtons.OkCancel)
{
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
}
public static MsgResult ShowQuestion(string mainInstruction,
string content,
MsgButtons buttons = MsgButtons.OkCancel)
{
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
}
public static MsgResult Show(string mainInstruction,
string content,
MsgIcon icon,
MsgButtons buttons,
MsgResult defaultButton = MsgResult.None)
{
try
{
using (TaskDialog<MsgResult> td = new TaskDialog<MsgResult>())
{
td.AllowCancel = false;
td.DefaultButton = defaultButton;
td.MainIcon = icon;
if (content == null)
{
if (mainInstruction.Length < 80)
td.MainInstruction = mainInstruction;
else
td.Content = mainInstruction;
}
else
{
td.MainInstruction = mainInstruction;
td.Content = content;
}
if (buttons == MsgButtons.OkCancel)
{
td.AddButton("OK", MsgResult.OK);
td.AddButton("Cancel", MsgResult.Cancel);
}
else
td.CommonButtons = buttons;
return td.Show();
}
}
catch (Exception ex)
{
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class TaskDialog<T> : TaskDialogNative, IDisposable
{
private Dictionary<int, T> IdValueDic;
private Dictionary<int, string> IdTextDic;
private List<int> CommandLinkShieldList;
private IntPtr ButtonArray;
private IntPtr RadioButtonArray;
private List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
private List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
private TaskDialogNative.TASKDIALOGCONFIG Config;
const int TDE_CONTENT = 0;
const int TDE_EXPANDED_INFORMATION = 1;
const int TDE_FOOTER = 2;
const int TDE_MAIN_INSTRUCTION = 3;
const int TDN_CREATED = 0;
const int TDN_NAVIGATED = 1;
const int TDN_BUTTON_CLICKED = 2;
const int TDN_HYPERLINK_CLICKED = 3;
const int TDN_TIMER = 4;
const int TDN_DESTROYED = 5;
const int TDN_RADIO_BUTTON_CLICKED = 6;
const int TDN_DIALOG_CONSTRUCTED = 7;
const int TDN_VERIFICATION_CLICKED = 8;
const int TDN_HELP = 9;
const int TDN_EXPANDO_BUTTON_CLICKED = 10;
const int TDM_NAVIGATE_PAGE = 1125;
const int TDM_CLICK_BUTTON = 1126;
const int TDM_SET_MARQUEE_PROGRESS_BAR = 1127;
const int TDM_SET_PROGRESS_BAR_STATE = 1128;
const int TDM_SET_PROGRESS_BAR_RANGE = 1129;
const int TDM_SET_PROGRESS_BAR_POS = 1130;
const int TDM_SET_PROGRESS_BAR_MARQUEE = 1131;
const int TDM_SET_ELEMENT_TEXT = 1132;
const int TDM_CLICK_RADIO_BUTTON = 1134;
const int TDM_ENABLE_BUTTON = 1135;
const int TDM_ENABLE_RADIO_BUTTON = 1136;
const int TDM_CLICK_VERIFICATION = 1137;
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
const int TDM_UPDATE_ICON = 1140;
private T SelectedValueValue;
private string SelectedTextValue;
private int TimeoutValue;
private int ExitTickCount;
private bool disposed;
public TaskDialog()
{
IdValueDic = new Dictionary<int, T>();
IdTextDic = new Dictionary<int, string>();
CommandLinkShieldList = new List<int>();
Buttons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
RadioButtons = new List<TaskDialogNative.TASKDIALOG_BUTTON>();
_SelectedID = -1;
Config = new TaskDialogNative.TASKDIALOGCONFIG();
Config.cbSize = (uint)Marshal.SizeOf(Config);
Config.hwndParent = GetHandle();
Config.hInstance = IntPtr.Zero;
Config.dwFlags = TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
Config.dwCommonButtons = MsgButtons.None;
Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
Config.FooterIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION(0);
Config.cxWidth = 0U;
Config.cButtons = 0U;
Config.cRadioButtons = 0U;
Config.pButtons = IntPtr.Zero;
Config.pRadioButtons = IntPtr.Zero;
Config.nDefaultButton = 0;
Config.nDefaultRadioButton = 0;
Config.pszWindowTitle = ((AssemblyProductAttribute)Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0]).Product;
Config.pszMainInstruction = "";
Config.pszContent = "";
Config.pfCallback = new PFTASKDIALOGCALLBACK(this.DialogProc);
}
public IntPtr GetHandle()
{
StringBuilder lpszFileName = new StringBuilder(260);
IntPtr foregroundWindow = TaskDialogNative.GetForegroundWindow();
TaskDialogNative.GetWindowModuleFileName(foregroundWindow, lpszFileName, 260U);
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
Path.GetFileName(Assembly.GetEntryAssembly().Location))
return foregroundWindow;
return IntPtr.Zero;
}
public bool AllowCancel {
set {
if (value)
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
else
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION;
}
}
public string MainInstruction {
get => Config.pszMainInstruction;
set => Config.pszMainInstruction = value;
}
public string Content {
get => Config.pszContent;
set => Config.pszContent = ExpandMarkdownMarkup(value);
}
public string ExpandedInformation {
get => Config.pszExpandedInformation;
set => Config.pszExpandedInformation = ExpandMarkdownMarkup(value);
}
public string VerificationText {
get => Config.pszVerificationText;
set => Config.pszVerificationText = value;
}
public MsgResult DefaultButton {
get => (MsgResult)Config.nDefaultButton;
set => Config.nDefaultButton = (int)value;
}
public string Footer {
get => Config.pszFooter;
set => Config.pszFooter = ExpandMarkdownMarkup(value);
}
public MsgIcon MainIcon {
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
}
private int _SelectedID;
public int SelectedID {
get => _SelectedID;
set {
foreach (var i in IdValueDic)
if (i.Key == value) _SelectedID = value;
}
}
public T SelectedValue {
get {
if (IdValueDic.ContainsKey(SelectedID))
return IdValueDic[SelectedID];
return SelectedValueValue;
}
set => SelectedValueValue = value;
}
public string SelectedText {
get {
if (IdTextDic.ContainsKey(SelectedID))
return IdTextDic[SelectedID];
return SelectedTextValue;
}
set => SelectedTextValue = value;
}
public bool CheckBoxChecked {
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) == TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
set {
if (value)
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
else
Config.dwFlags ^= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
}
}
public MsgButtons CommonButtons {
get => Config.dwCommonButtons;
set => Config.dwCommonButtons = value;
}
public int Timeout {
get => Convert.ToInt32(TimeoutValue / 1000.0);
set {
TimeoutValue = value * 1000;
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_CALLBACK_TIMER;
}
}
public void AddButton(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
}
public string ExpandMarkdownMarkup(string value)
{
if (value.Contains("["))
{
Regex regex = new Regex(@"\[(.+)\]\((.+)\)");
if (regex.Match(value).Success)
{
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS;
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
}
}
return value;
}
public void AddCommandLink(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value == null ? (T)(object)text : value;
IdTextDic[n] = text;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
}
public void AddCommandLink(string text, string description, T value, bool setShield = false)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
if (setShield) CommandLinkShieldList.Add(n);
if (!string.IsNullOrEmpty(description)) text += "\n" + description;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
}
public void AddRadioButton(string text, T value)
{
int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value;
RadioButtons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
}
public T Show()
{
MarshalDialogControlStructs();
TaskDialogNative.TASKDIALOGCONFIG config = Config;
int errorCode = TaskDialogNative.TaskDialogIndirect(config, out int dummy1, out int dummy2, out bool isChecked);
if (errorCode < 0) Marshal.ThrowExceptionForHR(errorCode);
CheckBoxChecked = isChecked;
if (SelectedValue is MsgResult) SelectedValue = (T)(object)SelectedID;
return SelectedValue;
}
public int DialogProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr lpRefData)
{
switch (msg)
{
case 0: //TDN_CREATED
foreach (var i in CommandLinkShieldList)
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, new IntPtr(i), new IntPtr(1));
break;
case 2: //TDN_BUTTON_CLICKED
case 6: //TDN_RADIO_BUTTON_CLICKED
if (SelectedValue is MsgResult)
_SelectedID = wParam.ToInt32();
else
SelectedID = wParam.ToInt32();
break;
case 3: //TDN_HYPERLINK_CLICKED
string stringUni = Marshal.PtrToStringUni(lParam);
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
Process.Start(stringUni);
if (stringUni == "copymsg")
{
Thread thread = new Thread((ThreadStart)(() => {
Clipboard.SetText(MainInstruction + "\r\n\r\n" + Content + "\r\n\r\n" + ExpandedInformation);
MessageBox.Show("Message was copied to clipboard.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
break;
case 4: //TDN_TIMER
if (ExitTickCount == 0) ExitTickCount = Environment.TickCount + Timeout * 1000;
if (Environment.TickCount > ExitTickCount)
TaskDialogNative.SendMessage(hwnd, 1126, new IntPtr(1), IntPtr.Zero);
break;
}
return 0;
}
public void MarshalDialogControlStructs()
{
if (Buttons != null && Buttons.Count > 0)
{
ButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(Buttons);
Config.pButtons = ButtonArray;
Config.cButtons = (uint)Buttons.Count;
}
if (RadioButtons == null || RadioButtons.Count <= 0) return;
RadioButtonArray = TaskDialog<T>.AllocateAndMarshalButtons(RadioButtons);
Config.pRadioButtons = RadioButtonArray;
Config.cRadioButtons = (uint)RadioButtons.Count;
}
public static IntPtr AllocateAndMarshalButtons(List<TaskDialogNative.TASKDIALOG_BUTTON> structs)
{
var initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TASKDIALOG_BUTTON)) * structs.Count);
var currentPtr = initialPtr;
foreach (var button in structs)
{
Marshal.StructureToPtr(button, currentPtr, false);
currentPtr = (IntPtr)(currentPtr.ToInt64() + Marshal.SizeOf(button));
}
return initialPtr;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~TaskDialog()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposed) return;
disposed = true;
if (ButtonArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(ButtonArray);
ButtonArray = IntPtr.Zero;
}
if (RadioButtonArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(RadioButtonArray);
RadioButtonArray = IntPtr.Zero;
}
}
}
public delegate int PFTASKDIALOGCALLBACK(
IntPtr hwnd,
uint msg,
IntPtr wParam,
IntPtr lParam,
IntPtr lpRefData);
public class TaskDialogNative
{
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int TaskDialogIndirect(
[In] TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
out int pnButton,
out int pnRadioButton,
[MarshalAs(UnmanagedType.Bool)] out bool pVerificationFlagChecked);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern uint GetWindowModuleFileName(
IntPtr hwnd,
StringBuilder lpszFileName,
uint cchFileNameMax);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(
IntPtr handle,
int message,
IntPtr wParam,
IntPtr lParam);
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
public class TASKDIALOGCONFIG
{
public uint cbSize;
public IntPtr hwndParent;
public IntPtr hInstance;
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
public MsgButtons dwCommonButtons;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszWindowTitle;
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszMainInstruction;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszContent;
public uint cButtons;
public IntPtr pButtons;
public int nDefaultButton;
public uint cRadioButtons;
public IntPtr pRadioButtons;
public int nDefaultRadioButton;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszVerificationText;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszExpandedInformation;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszExpandedControlText;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszCollapsedControlText;
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszFooter;
public PFTASKDIALOGCALLBACK pfCallback;
public IntPtr lpCallbackData;
public uint cxWidth;
}
public enum TASKDIALOG_FLAGS
{
NONE = 0,
TDF_ENABLE_HYPERLINKS = 1,
TDF_USE_HICON_MAIN = 2,
TDF_USE_HICON_FOOTER = 4,
TDF_ALLOW_DIALOG_CANCELLATION = 8,
TDF_USE_COMMAND_LINKS = 16,
TDF_USE_COMMAND_LINKS_NO_ICON = 32,
TDF_EXPAND_FOOTER_AREA = 64,
TDF_EXPANDED_BY_DEFAULT = 128,
TDF_VERIFICATION_FLAG_CHECKED = 256,
TDF_SHOW_PROGRESS_BAR = 512,
TDF_SHOW_MARQUEE_PROGRESS_BAR = 1024,
TDF_CALLBACK_TIMER = 2048,
TDF_POSITION_RELATIVE_TO_WINDOW = 4096,
TDF_RTL_LAYOUT = 8192,
TDF_NO_DEFAULT_RADIO_BUTTON = 16384,
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct TASKDIALOGCONFIG_ICON_UNION
{
[FieldOffset(0)]
public int hMainIcon;
[FieldOffset(0)]
public int pszIcon;
[FieldOffset(0)]
public IntPtr spacer;
public TASKDIALOGCONFIG_ICON_UNION(int i)
{
this = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION();
spacer = IntPtr.Zero;
pszIcon = 0;
hMainIcon = i;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
public struct TASKDIALOG_BUTTON
{
public int nButtonID;
[MarshalAs(UnmanagedType.LPWStr)]
public string pszButtonText;
public TASKDIALOG_BUTTON(int n, string txt)
{
this = new TaskDialogNative.TASKDIALOG_BUTTON();
nButtonID = n;
pszButtonText = txt;
}
}
}
public enum MsgButtons
{
None = 0,
Ok = 1,
Yes = 2,
No = 4,
YesNo = 6,
Cancel = 8,
OkCancel = 9,
YesNoCancel = 14,
Retry = 16,
RetryCancel = 24,
Close = 32,
}
public enum MsgResult
{
None,
OK,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No,
}
public enum MsgIcon
{
None = 0,
SecurityShieldGray = 65527,
SecuritySuccess = 65528,
SecurityError = 65529,
SecurityWarning = 65530,
SecurityShieldBlue = 65531,
Shield = 65532,
Info = 65533,
Error = 65534,
Warning = 65535,
}

View File

@@ -1,6 +1,8 @@
using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;

View File

@@ -9,7 +9,6 @@ using System.Windows.Input;
using System.Windows.Media;
using DynamicGUI;
using Sys;
namespace mpvnet
{
@@ -115,7 +114,7 @@ namespace mpvnet
if (left.StartsWith("#"))
{
Comments[filePath][left.TrimStart("#".ToCharArray())] = right;
Comments[filePath][left.TrimStart('#')] = right;
continue;
}

View File

@@ -0,0 +1,23 @@
<Window x:Class="mpvnet.EverythingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Media File Search" Height="300" Width="600" ResizeMode="NoResize"
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded" FontSize="13">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Name="FilterTextBox" PreviewKeyDown="FilterTextBox_PreviewKeyDown" TextChanged="FilterTextBox_TextChanged"></TextBox>
<ListView Name="ListView" Grid.Row="1" MouseUp="ListView_MouseUp" PreviewKeyDown="ListView_PreviewKeyDown">
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
</Window>

View File

@@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
namespace mpvnet
{
public partial class EverythingWindow : Window
{
public EverythingWindow()
{
InitializeComponent();
if (App.IsDarkMode)
{
ListView.Foreground = Brushes.White;
ListView.Background = Brushes.Black;
FilterTextBox.Foreground = Brushes.White;
FilterTextBox.Background = Brushes.Black;
}
}
const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001;
const int EVERYTHING_REQUEST_PATH = 0x00000002;
const int EVERYTHING_SORT_SIZE_DESCENDING = 6;
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
public static extern int Everything_SetSearch(string lpSearchString);
[DllImport("Everything.dll")]
public static extern void Everything_SetRequestFlags(UInt32 dwRequestFlags);
[DllImport("Everything.dll")]
public static extern void Everything_SetSort(UInt32 dwSortType);
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
public static extern bool Everything_Query(bool bWait);
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
public static extern void Everything_GetResultFullPathName(UInt32 nIndex, StringBuilder lpString, UInt32 nMaxCount);
[DllImport("Everything.dll")]
public static extern bool Everything_GetResultSize(UInt32 nIndex, out long lpFileSize);
[DllImport("Everything.dll")]
public static extern UInt32 Everything_GetNumResults();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
Keyboard.Focus(FilterTextBox);
}
void SelectFirst()
{
if (ListView.Items.Count > 0)
ListView.SelectedIndex = 0;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
handled = true;
return IntPtr.Zero;
}
private void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
{
int index = ListView.SelectedIndex;
index -= 1;
if (index < 0) index = 0;
ListView.SelectedIndex = index;
ListView.ScrollIntoView(ListView.SelectedItem);
}
break;
case Key.Down:
{
int index = ListView.SelectedIndex;
index += 1;
if (index > ListView.Items.Count - 1) index = ListView.Items.Count - 1;
ListView.SelectedIndex = index;
ListView.ScrollIntoView(ListView.SelectedItem);
}
break;
case Key.Escape:
Close();
break;
case Key.Enter:
Execute();
break;
}
}
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape) Close();
if (e.Key == Key.Enter) Execute();
}
void Execute()
{
if (ListView.SelectedItem != null)
mp.LoadFiles(ListView.SelectedItem as string);
Keyboard.Focus(FilterTextBox);
}
private void ListView_MouseUp(object sender, MouseButtonEventArgs e)
{
Execute();
}
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string searchtext = FilterTextBox.Text;
Task.Run(() => Search(searchtext));
}
object LockObject = new object();
void Search(string searchtext)
{
lock (LockObject)
{
try
{
List<string> items = new List<string>();
UInt32 i;
const int bufsize = 500;
StringBuilder buf = new StringBuilder(bufsize);
Everything_SetSearch(searchtext);
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
Everything_SetSort(EVERYTHING_SORT_SIZE_DESCENDING);
Everything_Query(true);
for (i = 0; i < Everything_GetNumResults(); i++)
{
Everything_GetResultFullPathName(i, buf, bufsize);
string ext = Path.GetExtension(buf.ToString()).TrimStart('.').ToLower();
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext))
items.Add(buf.ToString());
if (items.Count > 100) break;
}
Application.Current.Dispatcher.Invoke(() => {
ListView.ItemsSource = items;
SelectFirst();
});
}
catch (Exception)
{
Msg.ShowError("Search query failed.",
"The search feature depends on [Everything](https://www.voidtools.com) being installed.");
}
}
}
}
}

View File

@@ -7,7 +7,6 @@ using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using Sys;
namespace mpvnet
{
@@ -31,10 +30,19 @@ namespace mpvnet
if (App.IsDarkMode)
{
Foreground = Brushes.White;
Foreground2 = Brushes.Silver;
Background = Brushes.Black;
}
}
public Brush Foreground2 {
get { return (Brush)GetValue(Foreground2Property); }
set { SetValue(Foreground2Property, value); }
}
public static readonly DependencyProperty Foreground2Property =
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(InputWindow), new PropertyMetadata(Brushes.DarkSlateGray));
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
CollectionView.Refresh();

View File

@@ -11,13 +11,9 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sys;
using static mpvnet.libmpv;
using static mpvnet.Native;
using PyRT = IronPython.Runtime;
namespace mpvnet
{
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
@@ -25,7 +21,7 @@ namespace mpvnet
public class mp
{
public static event Action VideoSizeChanged;
// Lua/JS evens libmpv events
// Lua/JS event libmpv event
// MPV_EVENT_NONE
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
@@ -78,9 +74,11 @@ namespace mpvnet
{
string portableFolder = Application.StartupPath + "\\portable_config\\";
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
string startupFolder = Application.StartupPath + "\\";
if (!Directory.Exists(appdataFolder) && !Directory.Exists(portableFolder) &&
Sys.IsDirectoryWritable(Application.StartupPath))
Sys.IsDirectoryWritable(Application.StartupPath) &&
!File.Exists(startupFolder + "mpv.conf"))
{
using (TaskDialog<string> td = new TaskDialog<string>())
{
@@ -88,15 +86,17 @@ namespace mpvnet
td.Content = "[MPV documentation about files on Windows.](https://mpv.io/manual/master/#files-on-windows)";
td.AddCommandLink("appdata", appdataFolder, appdataFolder);
td.AddCommandLink("portable", portableFolder, portableFolder);
td.AddCommandLink("startup", startupFolder, startupFolder);
td.AllowCancel = false;
_MpvConfFolder = td.Show();
}
}
else
if (Directory.Exists(portableFolder))
_MpvConfFolder = portableFolder;
else
_MpvConfFolder = appdataFolder;
else if (Directory.Exists(portableFolder))
_MpvConfFolder = portableFolder;
else if (Directory.Exists(appdataFolder))
_MpvConfFolder = appdataFolder;
else if (File.Exists(Application.StartupPath + "\\mpv.conf"))
_MpvConfFolder = Application.StartupPath + "\\";
if (string.IsNullOrEmpty(_MpvConfFolder)) _MpvConfFolder = appdataFolder;
if (!Directory.Exists(_MpvConfFolder)) Directory.CreateDirectory(_MpvConfFolder);
@@ -345,7 +345,7 @@ namespace mpvnet
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
public static void register_event(string name, PyRT.PythonFunction pyFunc)
public static void register_event(string name, IronPython.Runtime.PythonFunction pyFunc)
{
foreach (var eventInfo in typeof(mp).GetEvents())
{
@@ -380,7 +380,7 @@ namespace mpvnet
}
}
public static void unregister_event(PyRT.PythonFunction pyFunc)
public static void unregister_event(IronPython.Runtime.PythonFunction pyFunc)
{
foreach (var eventObjects in PythonEventObjects)
if (eventObjects.PythonFunction == pyFunc)
@@ -565,17 +565,15 @@ namespace mpvnet
if (get_property_int("playlist-count") == 1)
{
string path = get_property_string("path");
if (!Directory.Exists(Path.GetDirectoryName(path))) return;
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(' ');
if (!File.Exists(path)) return;
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
files = files.Where((file) => types.Contains(Path.GetExtension(file).TrimStart(".".ToCharArray()).ToLower())).ToList();
files = files.Where((file) => App.VideoTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower()) ||
App.AudioTypes.Contains(Path.GetExtension(file).TrimStart('.').ToLower())).ToList();
files.Sort(new StringLogicalComparer());
int index = files.IndexOf(path);
files.Remove(path);
foreach (string i in files)
commandv("loadfile", i, "append");
if (index > 0)
commandv("playlist-move", "0", (index + 1).ToString());
}
@@ -665,7 +663,7 @@ namespace mpvnet
Add(track, mi.GetVideo(i, "Forced") == "Yes" ? "Forced" : "");
Add(track, mi.GetVideo(i, "Default") == "Yes" ? "Default" : "");
Add(track, mi.GetVideo(i, "Title"));
track.Text = "V: " + track.Text.Trim(" ,".ToCharArray());
track.Text = "V: " + track.Text.Trim(' ', ',');
track.Type = "v";
track.ID = i + 1;
MediaTracks.Add(track);
@@ -685,7 +683,7 @@ namespace mpvnet
Add(track, mi.GetAudio(i, "Forced") == "Yes" ? "Forced" : "");
Add(track, mi.GetAudio(i, "Default") == "Yes" ? "Default" : "");
Add(track, mi.GetAudio(i, "Title"));
track.Text = "A: " + track.Text.Trim(" ,".ToCharArray());
track.Text = "A: " + track.Text.Trim(' ', ',');
track.Type = "a";
track.ID = i + 1;
MediaTracks.Add(track);
@@ -702,7 +700,7 @@ namespace mpvnet
Add(track, mi.GetText(i, "Forced") == "Yes" ? "Forced" : "");
Add(track, mi.GetText(i, "Default") == "Yes" ? "Default" : "");
Add(track, mi.GetText(i, "Title"));
track.Text = "S: " + track.Text.Trim(" ,".ToCharArray());
track.Text = "S: " + track.Text.Trim(' ', ',');
track.Type = "s";
track.ID = i + 1;
MediaTracks.Add(track);

View File

@@ -146,6 +146,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Windows\EverythingWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Windows\CommandPaletteWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -190,7 +194,10 @@
<Compile Include="NativeHelp.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sys\TaskDialog.cs" />
<Compile Include="TaskDialog.cs" />
<Compile Include="Windows\EverythingWindow.xaml.cs">
<DependentUpon>EverythingWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\CommandPaletteWindow.xaml.cs">
<DependentUpon>CommandPaletteWindow.xaml</DependentUpon>
</Compile>
@@ -245,7 +252,6 @@
</ItemGroup>
<ItemGroup>
<Content Include="Resources\inputConfHeader.txt" />
<Content Include="screenshot.jpg" />
<Content Include="Resources\inputConf.txt" />
</ItemGroup>
<ItemGroup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 KiB

View File

@@ -23,7 +23,7 @@ AppPublisher=Frank Skare (stax76)
#endif
Compression=lzma2
DefaultDirName={commonpf}\{#MyAppName}
OutputBaseFilename=mpvnet-setup-{#arch}-{#MyAppVersion}
OutputBaseFilename=mpv.net-setup-{#arch}-{#MyAppVersion}
OutputDir={#GetEnv('USERPROFILE')}\Desktop
DefaultGroupName={#MyAppName}
SetupIconFile=mpv.net\mpvnet.ico

View File

@@ -1,6 +1,5 @@
function CheckExitCode {
if ($LastExitCode -gt 0)
{
if ($LastExitCode -gt 0) {
Write-Host "`nExit code $LastExitCode was returned.`n" -ForegroundColor Red
exit
}