Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b199d33f7a | ||
|
|
a7b6f79ee1 | ||
|
|
fc3c5ee3a7 | ||
|
|
ed71cb704f | ||
|
|
a9474b1c22 | ||
|
|
be3b31f7e6 | ||
|
|
b2884e2037 | ||
|
|
3910776b54 | ||
|
|
b37272db8b | ||
|
|
08a23430c7 | ||
|
|
ba41b8026f | ||
|
|
4aeb00afb5 | ||
|
|
6e6015b185 | ||
|
|
68240ac49d | ||
|
|
bafc481117 | ||
|
|
9198d610ad | ||
|
|
ad4199aff0 | ||
|
|
3164e2322c | ||
|
|
a6d4570b81 | ||
|
|
4fc9c61ecf | ||
|
|
5a969aac7d | ||
|
|
1b9229d4d9 | ||
|
|
225979d220 | ||
|
|
0c3a03181a | ||
|
|
867a83f15a | ||
|
|
1d78d4e4e2 | ||
|
|
23bef4d971 | ||
|
|
9b95b87177 | ||
|
|
aa8ae225c5 | ||
|
|
1bb05c4d99 | ||
|
|
619fcef63f | ||
|
|
9170e55d81 | ||
|
|
dc1240f606 | ||
|
|
cb11279091 | ||
|
|
fd956d401f | ||
|
|
6ea8a67390 | ||
|
|
6d02203727 | ||
|
|
0d396947c1 | ||
|
|
6c85ea9625 | ||
|
|
2d9a67c502 | ||
|
|
d9000a570b |
@@ -1,29 +0,0 @@
|
|||||||
Imports System.ComponentModel.Composition
|
|
||||||
Imports System.IO
|
|
||||||
Imports System.Windows.Forms
|
|
||||||
|
|
||||||
Imports mpvnet
|
|
||||||
|
|
||||||
Imports CSScriptLibrary
|
|
||||||
|
|
||||||
<Export(GetType(IAddon))>
|
|
||||||
Public Class CSScriptAddon
|
|
||||||
Implements IAddon
|
|
||||||
|
|
||||||
Sub New()
|
|
||||||
Dim scriptDir = mp.MpvConfFolder + "scripts"
|
|
||||||
If Not Directory.Exists(scriptDir) Then Return
|
|
||||||
Dim csFiles = Directory.GetFiles(scriptDir, "*.cs").ToList
|
|
||||||
csFiles.AddRange(Directory.GetFiles(Application.StartupPath + "\\Scripts", "*.cs"))
|
|
||||||
If csFiles.Count = 0 Then Return
|
|
||||||
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom
|
|
||||||
|
|
||||||
For Each i In csFiles
|
|
||||||
Try
|
|
||||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
|
||||||
Catch ex As Exception
|
|
||||||
MainForm.Instance.ShowMsgBox(ex.ToString(), MessageBoxIcon.Error)
|
|
||||||
End Try
|
|
||||||
Next
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
160
README.md
@@ -8,23 +8,23 @@ mpv.net is based on libmpv which offers a straightforward C API that was designe
|
|||||||
|
|
||||||
#### CLI options
|
#### CLI options
|
||||||
|
|
||||||
mpv.net has a basic CLI parser to support mpv's [CLI options](https://mpv.io/manual/master/#options).
|
mpv.net has the same [CLI options](https://mpv.io/manual/master/#options) as mpv.
|
||||||
|
|
||||||
#### High quality video output
|
#### High quality video output
|
||||||
|
|
||||||
libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
mpv/libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
||||||
|
|
||||||
#### On Screen Controller
|
#### On Screen Controller
|
||||||
|
|
||||||
mpv.net uses mpv's OSC offering play controls with a modern flat design.
|
mpv.net uses the OSC of mpv/libmpv offering play controls with a modern flat design.
|
||||||
|
|
||||||
#### GPU video decoding
|
#### GPU video decoding
|
||||||
|
|
||||||
libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
mpv/libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||||
|
|
||||||
#### Active development
|
#### Active development
|
||||||
|
|
||||||
mpv.net is under active development, focusing on user feedback. Want a feature? Post a [patch](https://github.com/stax76/mpv.net/pulls) or [request it](https://github.com/stax76/mpv.net/issues)!
|
mpv.net is under active development. Want a feature? Post a [patch](https://github.com/stax76/mpv.net/pulls) or [request it](https://github.com/stax76/mpv.net/issues)!
|
||||||
|
|
||||||
Table of contents
|
Table of contents
|
||||||
-----------------
|
-----------------
|
||||||
@@ -50,45 +50,51 @@ Table of contents
|
|||||||
- Modern UI with dark mode ([Screenshot](#config-editor))
|
- Modern UI with dark mode ([Screenshot](#config-editor))
|
||||||
- Addon/extension API for .NET languages
|
- Addon/extension API for .NET languages
|
||||||
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
||||||
- mpv's OSC, CLI, IPC and conf files
|
- 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
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
#### Main Window
|
#### Main Window Screenshot
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Context Menu
|
#### Context Menu Screenshot
|
||||||
|
|
||||||
Context menu defined in the input.conf file with dark mode support.
|
Context menu defined in the input.conf file with dark mode support.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Config Editor
|
#### Config Editor Screenshot
|
||||||
|
|
||||||
A searchable config editor as alternative to edit the mpv.conf file manually.
|
A searchable config editor as alternative to edit the mpv.conf file manually.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Input Editor
|
#### Input Editor Screenshot
|
||||||
|
|
||||||
A searchable key and mouse binding editor.
|
A searchable key and mouse binding editor.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Command Palette
|
#### Command Palette Screenshot
|
||||||
|
|
||||||
Forgot where a command in the menu is located or what shortcut key it has?
|
Forgot where a command in the menu is located or what shortcut key it has?
|
||||||
Just press Ctrl+Shift+P and find it easily in the searchable command palette.
|
Just press Ctrl+Shift+P and find it easily in the searchable command palette.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Context Menu
|
### Context Menu
|
||||||
|
|
||||||
The context menu can be customized via input.conf file located at:
|
The context menu can be customized via input.conf file located in the config directory:
|
||||||
```
|
|
||||||
|
```Text
|
||||||
C:\Users\%username%\AppData\Roaming\mpv\input.conf
|
C:\Users\%username%\AppData\Roaming\mpv\input.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
if it's missing mpv.net generates it with the following defaults:
|
if it's missing mpv.net generates it with the following defaults:
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||||
@@ -97,41 +103,31 @@ input.conf defines mpv's key and mouse bindings and mpv.net uses comments to def
|
|||||||
|
|
||||||
### Settings
|
### 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 at:
|
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
|
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
|
||||||
```
|
```
|
||||||
or alternativly 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
|
<startup>\portable_config\mpv.conf
|
||||||
```
|
```
|
||||||
if it's missing mpv.net generates it with the following defaults:
|
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpv.conf.txt>
|
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>
|
||||||
|
|
||||||
|
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
|
### Scripting
|
||||||
|
|
||||||
Scripting is supported via Python, C#, Lua, JavaScript and PowerShell
|
|
||||||
|
|
||||||
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
||||||
|
|
||||||
### Add-ons
|
### Add-ons
|
||||||
|
|
||||||
Add-ons have to be located at:
|
[Add-on wiki page](https://github.com/stax76/mpv.net/wiki/Addons)
|
||||||
|
|
||||||
C:\Users\\<user\>\AppData\Roaming\mpv\Addons\ExampleAddon\ExampleAddon.dll
|
|
||||||
|
|
||||||
\<startup\>\Addons\ExampleAddon\ExampleAddon.dll
|
|
||||||
|
|
||||||
\<startup\>\portable_config\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)
|
|
||||||
|
|
||||||
### Architecture
|
### Architecture
|
||||||
|
|
||||||
@@ -151,10 +147,11 @@ mpv.net was started 2017 and consists of about 9000 lines of code.
|
|||||||
|
|
||||||
Third party components are:
|
Third party components are:
|
||||||
|
|
||||||
- libmpv
|
- [libmpv](https://mpv.io/)
|
||||||
- MediaInfo
|
- [MediaInfo](https://mediaarea.net/en/MediaInfo)
|
||||||
- Tommy (TOML parser)
|
- [Tommy (TOML parser)](https://github.com/dezhidki/Tommy)
|
||||||
- IronPython
|
- [IronPython](https://ironpython.net/)
|
||||||
|
- [CS-Script](http://www.csscript.net/)
|
||||||
|
|
||||||
### Support
|
### Support
|
||||||
|
|
||||||
@@ -194,64 +191,25 @@ mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
|||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
### 3.2 (2019-0?-??)
|
### 3.6
|
||||||
|
|
||||||
- mpvInputEdit and mpvConfEdit were discontinued and merged into
|
- playing files from rar archives caused an exception
|
||||||
mpvnet because separate apps were to difficult to work with
|
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
|
||||||
- portable mode: in case no config folder exists and the
|
- the search clear button in the input editor had a render issue in dark mode
|
||||||
startup folder has write access mpvnet will ask where
|
- new search feature added to search and play media files, requires
|
||||||
the config folder should be created (portable or appdata)
|
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L29)
|
||||||
- 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
|
|
||||||
- About dialog added
|
|
||||||
- the input editor shows only a closing message if actually a change was made
|
|
||||||
- the input editor don't show menu separators any longer
|
|
||||||
- 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
|
|
||||||
|
|
||||||
### 3.1 (2019-04-23)
|
### 3.5
|
||||||
|
|
||||||
- the Tracks and Chapters menu are now only added if default bindings exist and
|
- when the main windows gets activated and the clipboard content starts with http
|
||||||
it's now possible to move the chapters menu to the top level by editing input.conf
|
mpv.net will ask to play the URL, previously this was restricted to YouTube URLs
|
||||||
- mpvnet supports now like mpv a portable settings directory. If a directory named portable_config
|
- Python script errors show line and column whenever it is supported by IronPython
|
||||||
next to the mpvnet.exe exists, all config will be loaded and written in this directory.
|
- if conf files exist in the startup directory mpv.net will use the startup
|
||||||
- there is now a portable download in 7zip format.
|
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.0 (2019-04-20)
|
### 3.4
|
||||||
|
|
||||||
- the history feature logs now only files that were opened longer than 90 seconds
|
- 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)
|
||||||
- the default input command for cycling the audio tracks was replaced with an
|
- new zip download option added
|
||||||
mpv.net command that shows detailed track info and has no 'no audio' track. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L89).
|
- new x86 download option added
|
||||||
- new website at <https://mpv-net.github.io/mpv.net-web-site/>
|
|
||||||
- the Tracks menu supports now MKV edition selection. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L106).
|
|
||||||
- the Navigate menu supports now chapter selection. [Default binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L57).
|
|
||||||
- opening the context menu was crashing if the default binding for Tracks was missing
|
|
||||||
|
|
||||||
### 2.9 (2019-04-16)
|
|
||||||
|
|
||||||
- clicking the right top corner in full screen mode
|
|
||||||
closes the player but it did not work on all displays
|
|
||||||
- the info display was changed to display the filename on top
|
|
||||||
so it's not displayed in the middle of the screen
|
|
||||||
- on start up of the config editor all text is now selected in the
|
|
||||||
search text box so it's ready for a new search to be typed
|
|
||||||
- the config editor was changed to write the settings to disk
|
|
||||||
only if the settings were actually modified, also the message
|
|
||||||
that says that the settings will be available on next start
|
|
||||||
is now only shown if the settings were actually modified.
|
|
||||||
- there was an instance in the context menu where the sub menu
|
|
||||||
arrow was overlapping with the text
|
|
||||||
- in the input editor when only one character is entered in the
|
|
||||||
search text box the search is performed only in the input and
|
|
||||||
not in the command or menu
|
|
||||||
- in the input editor the routine that generates the input string
|
|
||||||
was completely rewritten because it was adding Shift where it
|
|
||||||
wasn't necessary (it took a huge amount of time to implement)
|
|
||||||
- the context menu has a new track menu where the active track
|
|
||||||
can be seen and selected, it shows video, audio and subtitle
|
|
||||||
tracks with various metadata. [Menu default definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L104).
|
|
||||||
The screenshots were updated showing the [new track menu](https://github.com/stax76/mpv.net#screenshots).
|
|
||||||
35
addons/CSScriptAddon/CSScriptAddon.vb
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
Imports System.ComponentModel.Composition
|
||||||
|
Imports System.IO
|
||||||
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
|
Imports mpvnet
|
||||||
|
|
||||||
|
Imports CSScriptLibrary
|
||||||
|
|
||||||
|
<Export(GetType(IAddon))>
|
||||||
|
Public Class CSScriptAddon
|
||||||
|
Implements IAddon
|
||||||
|
|
||||||
|
Sub New()
|
||||||
|
Dim scriptFiles As New List(Of String)
|
||||||
|
|
||||||
|
If Directory.Exists(mp.MpvConfFolder + "scripts") Then
|
||||||
|
scriptFiles.AddRange(Directory.GetFiles(mp.MpvConfFolder + "scripts", "*.cs"))
|
||||||
|
End If
|
||||||
|
|
||||||
|
If Directory.Exists(Application.StartupPath + "\scripts") Then
|
||||||
|
scriptFiles.AddRange(Directory.GetFiles(Application.StartupPath + "\scripts", "*.cs"))
|
||||||
|
End If
|
||||||
|
|
||||||
|
If scriptFiles.Count = 0 Then Return
|
||||||
|
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom
|
||||||
|
|
||||||
|
For Each i In scriptFiles
|
||||||
|
Try
|
||||||
|
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
||||||
|
Catch ex As Exception
|
||||||
|
Msg.ShowException(ex)
|
||||||
|
End Try
|
||||||
|
Next
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
@@ -47,6 +47,48 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OptionInfer>On</OptionInfer>
|
<OptionInfer>On</OptionInfer>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>..\..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
||||||
|
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>..\..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
||||||
|
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CSScriptLibrary, Version=3.27.5.0, Culture=neutral, PublicKeyToken=70fcc3d18c749033, processorArchitecture=MSIL">
|
<Reference Include="CSScriptLibrary, Version=3.27.5.0, Culture=neutral, PublicKeyToken=70fcc3d18c749033, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
@@ -114,7 +156,7 @@
|
|||||||
<Content Include="CSScriptLibrary.dll" />
|
<Content Include="CSScriptLibrary.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||||
<Name>mpv.net</Name>
|
<Name>mpv.net</Name>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\mpv.net\bin\x86\Debug\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
<OutputPath>..\mpv.net\bin\x86\Release\</OutputPath>
|
<OutputPath>..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\mpv.net\bin\x64\Debug\</OutputPath>
|
<OutputPath>..\..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
<OutputPath>..\mpv.net\bin\x64\Release\</OutputPath>
|
<OutputPath>..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||||
<Name>mpv.net</Name>
|
<Name>mpv.net</Name>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
36
addons/TestAddon/Properties/AssemblyInfo.cs
Normal 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")]
|
||||||
27
addons/TestAddon/TestAddon.cs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
addons/TestAddon/TestAddon.csproj
Normal 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>
|
||||||
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
BIN
img/mpvnet.pdn
Normal file
BIN
img/mpvnet.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
42
mpv.net.sln
@@ -5,9 +5,11 @@ VisualStudioVersion = 16.0.28729.10
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||||
EndProject
|
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
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -31,6 +33,18 @@ Global
|
|||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = 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.ActiveCfg = Release|x86
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.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.ActiveCfg = Debug|Any CPU
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Debug|x64
|
||||||
@@ -43,18 +57,18 @@ Global
|
|||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = 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.ActiveCfg = Release|x86
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = 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
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.Build.0 = Debug|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.Build.0 = Debug|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.ActiveCfg = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|Any CPU
|
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ using System.ComponentModel.Composition.Hosting;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Sys;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class Addon
|
public class Addon
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ using System.Reflection;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
|
|
||||||
using Sys;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class Command
|
public class Command
|
||||||
@@ -28,7 +26,7 @@ namespace mpvnet
|
|||||||
Type type = typeof(Command);
|
Type type = typeof(Command);
|
||||||
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
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();
|
ParameterInfo[] parameters = i.GetParameters();
|
||||||
|
|
||||||
@@ -46,14 +44,9 @@ namespace mpvnet
|
|||||||
public static void open_files(string[] args)
|
public static void open_files(string[] args)
|
||||||
{
|
{
|
||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
using (var d = new OpenFileDialog())
|
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||||
{
|
|
||||||
d.Multiselect = true;
|
|
||||||
d.Filter = Misc.GetFilter(Misc.FileTypes);
|
|
||||||
|
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
mp.LoadFiles(d.FileNames);
|
mp.LoadFiles(d.FileNames);
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,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)
|
public static void show_history(string[] args)
|
||||||
{
|
{
|
||||||
var fp = mp.MpvConfFolder + "history.txt";
|
var fp = mp.MpvConfFolder + "history.txt";
|
||||||
@@ -116,22 +118,26 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileInfo fileInfo = new FileInfo(mp.get_property_string("path"));
|
string performer, title, album, genre, date, duration, text = "";
|
||||||
|
long fileSize = 0;
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
int width = mp.get_property_int("video-params/w");
|
||||||
|
int height = mp.get_property_int("video-params/h");
|
||||||
|
|
||||||
using (MediaInfo mediaInfo = new MediaInfo(fileInfo.FullName))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
string width = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Width");
|
fileSize = new FileInfo(path).Length;
|
||||||
|
|
||||||
if (width == "")
|
if (App.AudioTypes.Contains(Path.GetExtension(path).ToLower().TrimStart('.')))
|
||||||
{
|
{
|
||||||
string performer = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Performer");
|
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||||
string title = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Title");
|
{
|
||||||
string album = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Album");
|
performer = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Performer");
|
||||||
string genre = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Genre");
|
title = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Title");
|
||||||
string date = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Recorded_Date");
|
album = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Album");
|
||||||
string duration = mediaInfo.GetInfo(MediaInfoStreamKind.Audio, "Duration/String");
|
genre = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Genre");
|
||||||
|
date = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Recorded_Date");
|
||||||
string text = "";
|
duration = mediaInfo.GetInfo(MediaInfoStreamKind.Audio, "Duration/String");
|
||||||
|
|
||||||
if (performer != "") text += "Artist: " + performer + "\n";
|
if (performer != "") text += "Artist: " + performer + "\n";
|
||||||
if (title != "") text += "Title: " + title + "\n";
|
if (title != "") text += "Title: " + title + "\n";
|
||||||
@@ -141,37 +147,30 @@ namespace mpvnet
|
|||||||
if (duration != "") text += "Length: " + duration + "\n";
|
if (duration != "") text += "Length: " + duration + "\n";
|
||||||
|
|
||||||
mp.commandv("show-text", text, "5000");
|
mp.commandv("show-text", text, "5000");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
string height = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Height");
|
|
||||||
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
|
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
|
||||||
TimeSpan duration = TimeSpan.FromSeconds(mp.get_property_number("duration"));
|
TimeSpan duration2 = TimeSpan.FromSeconds(mp.get_property_number("duration"));
|
||||||
string bitrate = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "BitRate");
|
|
||||||
|
|
||||||
if (bitrate == "")
|
|
||||||
bitrate = "0";
|
|
||||||
|
|
||||||
double bitrate2 = Convert.ToDouble(bitrate) / 1000.0 / 1000.0;
|
|
||||||
string videoCodec = mp.get_property_string("video-format").ToUpper();
|
string videoCodec = mp.get_property_string("video-format").ToUpper();
|
||||||
string filename = fileInfo.Name;
|
|
||||||
|
|
||||||
string text = filename + "\n" +
|
text = Path.GetFileName(path) + "\n" +
|
||||||
FormatTime(position.TotalMinutes) + ":" +
|
FormatTime(position.TotalMinutes) + ":" +
|
||||||
FormatTime(position.Seconds) + " / " +
|
FormatTime(position.Seconds) + " / " +
|
||||||
FormatTime(duration.TotalMinutes) + ":" +
|
FormatTime(duration2.TotalMinutes) + ":" +
|
||||||
FormatTime(duration.Seconds) + "\n" +
|
FormatTime(duration2.Seconds) + "\n" +
|
||||||
$"{width} x {height}\n" +
|
$"{width} x {height}\n";
|
||||||
$"{bitrate2.ToString("f1")} Mb/s\n" +
|
|
||||||
Convert.ToInt32(fileInfo.Length / 1024 / 1024).ToString() + " MB\n" +
|
if (fileSize > 0)
|
||||||
$"{videoCodec}\n";
|
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0).ToString() + " MB\n";
|
||||||
|
|
||||||
|
text += $"{videoCodec}\n";
|
||||||
|
|
||||||
mp.commandv("show-text", text, "5000");
|
mp.commandv("show-text", text, "5000");
|
||||||
}
|
|
||||||
|
|
||||||
string FormatTime(double value) => ((int)value).ToString("00");
|
string FormatTime(double value) => ((int)value).ToString("00");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -180,8 +179,9 @@ namespace mpvnet
|
|||||||
public static void execute_mpv_command(string[] args)
|
public static void execute_mpv_command(string[] args)
|
||||||
{
|
{
|
||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.");
|
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand"));
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
|
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand", command);
|
||||||
mp.command_string(command, false);
|
mp.command_string(command, false);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ namespace mpvnet
|
|||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened.");
|
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened.");
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
mp.LoadURL(command);
|
mp.LoadFiles(command);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,5 +241,35 @@ namespace mpvnet
|
|||||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void manage_file_associations(string[] args)
|
||||||
|
{
|
||||||
|
using (var td = new TaskDialog<string>())
|
||||||
|
{
|
||||||
|
td.MainInstruction = "Choose an option.";
|
||||||
|
td.MainIcon = MsgIcon.Shield;
|
||||||
|
|
||||||
|
td.AddCommandLink("Register video file extensions", "video");
|
||||||
|
td.AddCommandLink("Register audio file extensions", "audio");
|
||||||
|
td.AddCommandLink("Unregister file extensions", "unreg");
|
||||||
|
|
||||||
|
string result = td.Show();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(result))
|
||||||
|
{
|
||||||
|
using (var proc = new Process())
|
||||||
|
{
|
||||||
|
proc.StartInfo.FileName = Application.ExecutablePath;
|
||||||
|
proc.StartInfo.Arguments = "--reg-file-assoc " + result;
|
||||||
|
proc.StartInfo.Verb = "runas";
|
||||||
|
try {
|
||||||
|
proc.Start();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,8 +10,6 @@ using System.ComponentModel;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
using Sys;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public partial class MainForm : Form
|
public partial class MainForm : Form
|
||||||
@@ -24,6 +22,7 @@ namespace mpvnet
|
|||||||
Point LastCursorPosChanged;
|
Point LastCursorPosChanged;
|
||||||
int LastCursorChangedTickCount;
|
int LastCursorChangedTickCount;
|
||||||
bool IgnoreDpiChanged = true;
|
bool IgnoreDpiChanged = true;
|
||||||
|
List<string> RecentFiles;
|
||||||
|
|
||||||
public string MpvNetDarkMode { get; set; } = "always";
|
public string MpvNetDarkMode { get; set; } = "always";
|
||||||
public bool MpvFullscreen { get; set; }
|
public bool MpvFullscreen { get; set; }
|
||||||
@@ -50,6 +49,13 @@ namespace mpvnet
|
|||||||
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
||||||
Text += " " + Application.ProductVersion;
|
Text += " " + Application.ProductVersion;
|
||||||
|
|
||||||
|
object recent = RegistryHelp.GetObject("HKCU\\Software\\" + Application.ProductName, "Recent");
|
||||||
|
|
||||||
|
if (recent is string[] r)
|
||||||
|
RecentFiles = new List<string>(r);
|
||||||
|
else
|
||||||
|
RecentFiles = new List<string>();
|
||||||
|
|
||||||
foreach (var i in mp.mpvConf)
|
foreach (var i in mp.mpvConf)
|
||||||
ProcessMpvProperty(i.Key, i.Value);
|
ProcessMpvProperty(i.Key, i.Value);
|
||||||
|
|
||||||
@@ -152,6 +158,21 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuItem recent = FindMenuItem("Recent");
|
||||||
|
|
||||||
|
if (recent != null)
|
||||||
|
{
|
||||||
|
recent.DropDownItems.Clear();
|
||||||
|
|
||||||
|
foreach (string path in RecentFiles)
|
||||||
|
MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(path));
|
||||||
|
|
||||||
|
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||||
|
MenuItem mi = new MenuItem("Clear List");
|
||||||
|
mi.Action = () => RecentFiles.Clear();
|
||||||
|
recent.DropDownItems.Add(mi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
||||||
@@ -286,61 +307,50 @@ namespace mpvnet
|
|||||||
public void BuildMenu()
|
public void BuildMenu()
|
||||||
{
|
{
|
||||||
string content = File.ReadAllText(mp.InputConfPath);
|
string content = File.ReadAllText(mp.InputConfPath);
|
||||||
List<string> lines = null;
|
var items = CommandItem.GetItems(content);
|
||||||
Dictionary<string, string> commandInputDic = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
if (content.Contains("#menu:"))
|
if (!content.Contains("#menu:"))
|
||||||
lines = content.Split("\r\n".ToCharArray()).ToList();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
lines = Properties.Resources.inputConf.Split("\r\n".ToCharArray()).ToList();
|
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
||||||
|
foreach (CommandItem item in items)
|
||||||
foreach (string i in content.Split("\r\n".ToCharArray()))
|
foreach (CommandItem defaultItem in defaultItems)
|
||||||
{
|
if (item.Command == defaultItem.Command)
|
||||||
string line = i.Trim();
|
defaultItem.Input = item.Input;
|
||||||
if (line.StartsWith("#") || !line.Contains(" ")) continue;
|
items = defaultItems;
|
||||||
string input = line.Substring(0, line.IndexOf(" ")).Trim();
|
|
||||||
string command = line.Substring(line.IndexOf(" ") + 1).Trim();
|
|
||||||
commandInputDic[command] = input;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string line in lines)
|
foreach (CommandItem item in items)
|
||||||
{
|
{
|
||||||
if (!line.Contains("#menu:")) continue;
|
if (string.IsNullOrEmpty(item.Path))
|
||||||
string left = line.Substring(0, line.IndexOf("#menu:")).Trim();
|
continue;
|
||||||
if (left.StartsWith("#")) continue;
|
string path = item.Path.Replace("&", "&&");
|
||||||
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 = "";
|
|
||||||
|
|
||||||
MenuItem menuItem = ContextMenu.Add(path, () => {
|
MenuItem menuItem = ContextMenu.Add(path, () => {
|
||||||
try {
|
try {
|
||||||
mp.command_string(command);
|
mp.command_string(item.Command);
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex) {
|
|
||||||
Msg.ShowException(ex);
|
Msg.ShowException(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (menuItem != null)
|
if (menuItem != null)
|
||||||
menuItem.ShortcutKeyDisplayString = input + " ";
|
menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
void mp_PlaybackRestart() => BeginInvoke(new Action(() => { Text = Path.GetFileName(mp.get_property_string("path")) + " - mpv.net " + Application.ProductVersion; }));
|
private void Mp_FileLoaded()
|
||||||
|
{
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void Mp_Idle() => BeginInvoke(new Action(() => { Text = "mpv.net " + Application.ProductVersion; }));
|
void Mp_Idle() => BeginInvoke(new Action(() => { Text = "mpv.net " + Application.ProductVersion; }));
|
||||||
|
|
||||||
@@ -455,7 +465,7 @@ namespace mpvnet
|
|||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||||
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||||
mp.LoadURL(e.Data.GetData(DataFormats.Text).ToString());
|
mp.LoadFiles(e.Data.GetData(DataFormats.Text).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
@@ -501,14 +511,6 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DialogResult ShowMsgBox(string message, MessageBoxIcon icon)
|
|
||||||
{
|
|
||||||
var buttons = MessageBoxButtons.OK;
|
|
||||||
if (icon == MessageBoxIcon.Question) buttons = MessageBoxButtons.OKCancel;
|
|
||||||
var fn = new Func<DialogResult>(() => MessageBox.Show(message, Application.ProductName, buttons, icon));
|
|
||||||
return (DialogResult)Invoke(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnLoad(EventArgs e)
|
protected override void OnLoad(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLoad(e);
|
base.OnLoad(e);
|
||||||
@@ -521,7 +523,7 @@ namespace mpvnet
|
|||||||
mp.observe_property_int("edition", mpPropChangeEdition);
|
mp.observe_property_int("edition", mpPropChangeEdition);
|
||||||
mp.Shutdown += mp_Shutdown;
|
mp.Shutdown += mp_Shutdown;
|
||||||
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
||||||
mp.PlaybackRestart += mp_PlaybackRestart;
|
mp.FileLoaded += Mp_FileLoaded;
|
||||||
mp.Idle += Mp_Idle;
|
mp.Idle += Mp_Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,12 +548,13 @@ namespace mpvnet
|
|||||||
BuildMenu();
|
BuildMenu();
|
||||||
ContextMenuStrip = ContextMenu;
|
ContextMenuStrip = ContextMenu;
|
||||||
IgnoreDpiChanged = false;
|
IgnoreDpiChanged = false;
|
||||||
CheckYouTube();
|
CheckURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnFormClosed(e);
|
base.OnFormClosed(e);
|
||||||
|
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "Recent", RecentFiles.ToArray());
|
||||||
mp.commandv("quit");
|
mp.commandv("quit");
|
||||||
mp.AutoResetEvent.WaitOne(3000);
|
mp.AutoResetEvent.WaitOne(3000);
|
||||||
}
|
}
|
||||||
@@ -565,19 +568,19 @@ namespace mpvnet
|
|||||||
protected override void OnActivated(EventArgs e)
|
protected override void OnActivated(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnActivated(e);
|
base.OnActivated(e);
|
||||||
CheckYouTube();
|
CheckURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckYouTube()
|
void CheckURL()
|
||||||
{
|
{
|
||||||
string clipboard = Clipboard.GetText();
|
string clipboard = Clipboard.GetText();
|
||||||
|
|
||||||
if (clipboard.StartsWith("https://www.youtube.com/watch?") && RegistryHelp.GetValue("HKCU\\Software\\" + Application.ProductName, "LastYouTubeURL") != clipboard && Visible)
|
if (clipboard.StartsWith("http") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastURL") != clipboard && Visible)
|
||||||
{
|
{
|
||||||
RegistryHelp.SetValue("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.LoadURL(clipboard);
|
mp.LoadFiles(clipboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,11 +61,6 @@ public class MenuItem : ToolStripMenuItem
|
|||||||
base.OnClick(e);
|
base.OnClick(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MenuItem Add<T>(ToolStripItemCollection items, string path, Action<T> action, T value)
|
|
||||||
{
|
|
||||||
return Add(items, path, () => action(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MenuItem Add(ToolStripItemCollection items, string path, Action action)
|
public static MenuItem Add(ToolStripItemCollection items, string path, Action action)
|
||||||
{
|
{
|
||||||
string[] a = path.Split(new[] { " > ", " | " }, StringSplitOptions.RemoveEmptyEntries);
|
string[] a = path.Split(new[] { " > ", " | " }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|||||||
111
mpv.net/Misc.cs
@@ -15,12 +15,17 @@ using Microsoft.Win32;
|
|||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class Misc
|
public class App
|
||||||
{
|
{
|
||||||
public static readonly string[] FileTypes = "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(' ');
|
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 string GetFilter(IEnumerable<string> values) => "*." +
|
public static bool IsDarkMode {
|
||||||
String.Join(";*.", values) + "|*." + String.Join(";*.", values) + "|All Files|*.*";
|
get {
|
||||||
|
string darkMode = MainForm.Instance.MpvNetDarkMode;
|
||||||
|
return (darkMode == "system" && Sys.IsDarkTheme) || darkMode == "always";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sys
|
public class Sys
|
||||||
@@ -65,33 +70,31 @@ namespace mpvnet
|
|||||||
static string ExeFilename = Path.GetFileName(Application.ExecutablePath);
|
static string ExeFilename = Path.GetFileName(Application.ExecutablePath);
|
||||||
static string ExeFilenameNoExt = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
static string ExeFilenameNoExt = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
|
||||||
static string[] Types;
|
static string[] Types;
|
||||||
public static string[] VideoTypes = "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 = "mp2 mp3 ac3 wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 ogg mka aac opus flac mpa".Split(" ".ToCharArray());
|
|
||||||
|
|
||||||
public static void Register(string[] types)
|
public static void Register(string[] types)
|
||||||
{
|
{
|
||||||
Types = types;
|
Types = types;
|
||||||
|
|
||||||
RegistryHelp.SetValue(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
RegistryHelp.SetObject(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||||
RegistryHelp.SetValue($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
||||||
RegistryHelp.SetValue($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
||||||
RegistryHelp.SetValue($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
||||||
RegistryHelp.SetValue($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
||||||
|
|
||||||
foreach (string ext in Types)
|
foreach (string ext in Types)
|
||||||
{
|
{
|
||||||
RegistryHelp.SetValue($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
||||||
RegistryHelp.SetValue($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
RegistryHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||||
RegistryHelp.SetValue($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
RegistryHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||||
if (VideoTypes.Contains(ext))
|
if (App.VideoTypes.Contains(ext))
|
||||||
RegistryHelp.SetValue($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
||||||
if (AudioTypes.Contains(ext))
|
if (App.AudioTypes.Contains(ext))
|
||||||
RegistryHelp.SetValue($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
||||||
RegistryHelp.SetValue($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
||||||
RegistryHelp.SetValue($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +119,26 @@ namespace mpvnet
|
|||||||
|
|
||||||
public class RegistryHelp
|
public class RegistryHelp
|
||||||
{
|
{
|
||||||
public static void SetValue(string path, string name, string value)
|
public static void SetObject(string path, string name, object value)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
using (RegistryKey rk = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||||
rk.SetValue(name, value);
|
rk.SetValue(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetValue(string path, string name)
|
public static string GetString(string path, string name)
|
||||||
|
{
|
||||||
|
object val = GetObject(path, name);
|
||||||
|
if (val == null || !(val is string)) return "";
|
||||||
|
return val.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object GetObject(string path, string name)
|
||||||
{
|
{
|
||||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
||||||
if (rk != null)
|
if (rk != null)
|
||||||
return rk.GetValue(name, "").ToString();
|
return rk.GetValue(name, "");
|
||||||
else
|
else
|
||||||
return "";
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveKey(string path)
|
public static void RemoveKey(string path)
|
||||||
@@ -162,7 +172,6 @@ namespace mpvnet
|
|||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class CommandItem : INotifyPropertyChanged
|
public class CommandItem : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
@@ -189,30 +198,26 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObservableCollection<CommandItem> _Items;
|
public static ObservableCollection<CommandItem> GetItems(string content)
|
||||||
|
|
||||||
public static ObservableCollection<CommandItem> Items {
|
|
||||||
get {
|
|
||||||
if (_Items is null)
|
|
||||||
{
|
{
|
||||||
_Items = new ObservableCollection<CommandItem>();
|
var items = new ObservableCollection<CommandItem>();
|
||||||
|
|
||||||
if (File.Exists(mp.InputConfPath))
|
if (!string.IsNullOrEmpty(content))
|
||||||
{
|
{
|
||||||
foreach (string line in File.ReadAllLines(mp.InputConfPath))
|
foreach (string line in content.Split('\r', '\n'))
|
||||||
{
|
{
|
||||||
string val = line.Trim();
|
string val = line.Trim();
|
||||||
if (val.StartsWith("#")) continue;
|
if (val.StartsWith("#")) continue;
|
||||||
if (!val.Contains(" ")) continue;
|
if (!val.Contains(" ")) continue;
|
||||||
CommandItem item = new CommandItem();
|
CommandItem item = new CommandItem();
|
||||||
item.Input = val.Substring(0, val.IndexOf(" ")).Replace("_", "");
|
item.Input = val.Substring(0, val.IndexOf(" "));
|
||||||
|
if (item.Input == "_") item.Input = "";
|
||||||
val = val.Substring(val.IndexOf(" ") + 1);
|
val = val.Substring(val.IndexOf(" ") + 1);
|
||||||
|
|
||||||
if (val.Contains("#menu:"))
|
if (val.Contains("#menu:"))
|
||||||
{
|
{
|
||||||
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
||||||
val = val.Substring(0, val.IndexOf("#menu:"));
|
val = val.Substring(0, val.IndexOf("#menu:"));
|
||||||
|
|
||||||
if (item.Path.Contains(";"))
|
if (item.Path.Contains(";"))
|
||||||
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
||||||
}
|
}
|
||||||
@@ -222,13 +227,41 @@ namespace mpvnet
|
|||||||
continue;
|
continue;
|
||||||
if (item.Command.ToLower() == "ignore")
|
if (item.Command.ToLower() == "ignore")
|
||||||
item.Command = "";
|
item.Command = "";
|
||||||
_Items.Add(item);
|
MigrateCommands(item);
|
||||||
|
items.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ObservableCollection<CommandItem> _Items;
|
||||||
|
|
||||||
|
public static ObservableCollection<CommandItem> Items {
|
||||||
|
get {
|
||||||
|
if (_Items is null)
|
||||||
|
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
|
||||||
return _Items;
|
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
|
public class CursorHelp
|
||||||
|
|||||||
@@ -24,12 +24,23 @@ namespace mpvnet
|
|||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
public static extern IntPtr GetWindowLongPtrW(IntPtr hWnd, int nIndex);
|
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||||
|
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||||
|
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
|
||||||
|
{
|
||||||
|
if (IntPtr.Size == 8)
|
||||||
|
return GetWindowLong64(hWnd, nIndex);
|
||||||
|
else
|
||||||
|
return GetWindowLong32(hWnd, nIndex);
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct RECT
|
public struct RECT
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
||||||
{
|
{
|
||||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtrW(hwnd, -16 /* GWL_STYLE */), false);
|
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtr(hwnd, -16 /* GWL_STYLE */), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,6 @@ using System.Management.Automation.Runspaces;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Sys;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class PowerShellScript
|
public class PowerShellScript
|
||||||
|
|||||||
@@ -14,15 +14,9 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (args.Length == 3 && args[1] == "--reg-file-assoc")
|
if (args.Length == 3 && args[1] == "--reg-file-assoc")
|
||||||
{
|
{
|
||||||
if (args[2] == "audio") FileAssociation.Register(FileAssociation.AudioTypes);
|
if (args[2] == "audio") FileAssociation.Register(App.AudioTypes);
|
||||||
if (args[2] == "video") FileAssociation.Register(FileAssociation.VideoTypes);
|
if (args[2] == "video") FileAssociation.Register(App.VideoTypes);
|
||||||
if (args[2] == "unregister") FileAssociation.Unregister();
|
if (args[2] == "unreg") FileAssociation.Unregister();
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,5 +24,10 @@ namespace mpvnet
|
|||||||
Application.SetCompatibleTextRenderingDefault(false);
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
Application.Run(new MainForm());
|
Application.Run(new MainForm());
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Msg.ShowException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
|||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("mpv.net")]
|
[assembly: AssemblyTitle("mpv.net")]
|
||||||
[assembly: AssemblyDescription("libmpv based media player")]
|
[assembly: AssemblyDescription("A lightweight media player")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("mpv.net")]
|
[assembly: AssemblyProduct("mpv.net")]
|
||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("3.1.0.0")]
|
[assembly: AssemblyVersion("3.6.0.0")]
|
||||||
[assembly: AssemblyFileVersion("3.1.0.0")]
|
[assembly: AssemblyFileVersion("3.6.0.0")]
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
|
using Microsoft.Scripting;
|
||||||
using Microsoft.Scripting.Hosting;
|
using Microsoft.Scripting.Hosting;
|
||||||
|
|
||||||
using IronPython.Hosting;
|
using IronPython.Hosting;
|
||||||
using Sys;
|
using IronPython.Runtime;
|
||||||
using PyRT = IronPython.Runtime;
|
using IronPython.Runtime.Operations;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -22,11 +24,15 @@ namespace mpvnet
|
|||||||
scope.ImportModule("clr");
|
scope.ImportModule("clr");
|
||||||
engine.Execute("import clr", scope);
|
engine.Execute("import clr", scope);
|
||||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||||
|
engine.Execute("import mpvnet", scope);
|
||||||
engine.Execute("from mpvnet import *", scope);
|
engine.Execute("from mpvnet import *", scope);
|
||||||
engine.Execute(code, scope);
|
engine.Execute(code, scope);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
if (ex is SyntaxErrorException e)
|
||||||
|
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message);
|
||||||
|
else
|
||||||
Msg.ShowException(ex);
|
Msg.ShowException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,23 +40,20 @@ namespace mpvnet
|
|||||||
|
|
||||||
public class PythonEventObject
|
public class PythonEventObject
|
||||||
{
|
{
|
||||||
public PyRT.PythonFunction PythonFunction { get; set; }
|
public PythonFunction PythonFunction { get; set; }
|
||||||
public EventInfo EventInfo { get; set; }
|
public EventInfo EventInfo { get; set; }
|
||||||
public Delegate Delegate { get; set; }
|
public Delegate Delegate { get; set; }
|
||||||
|
|
||||||
public void Invoke()
|
public void Invoke() => PythonCalls.Call(PythonFunction);
|
||||||
{
|
|
||||||
PyRT.Operations.PythonCalls.Call(PythonFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||||
{
|
{
|
||||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
PythonCalls.Call(PythonFunction, new[] { arg });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeStrings(string[] arg)
|
public void InvokeStrings(string[] arg)
|
||||||
{
|
{
|
||||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
PythonCalls.Call(PythonFunction, new[] { arg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,12 @@
|
|||||||
|
|
||||||
o script-message mpv.net open-files #menu: Open > Open Files...
|
o script-message mpv.net open-files #menu: Open > Open Files...
|
||||||
u script-message mpv.net open-url #menu: Open > Open URL...
|
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 > -
|
_ ignore #menu: Open > -
|
||||||
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
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...
|
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
||||||
|
_ ignore #menu: Open > -
|
||||||
|
_ ignore #menu: Open > Recent
|
||||||
|
|
||||||
_ ignore #menu: -
|
_ ignore #menu: -
|
||||||
Space cycle pause #menu: Play/Pause
|
Space cycle pause #menu: Play/Pause
|
||||||
@@ -88,8 +91,8 @@
|
|||||||
|
|
||||||
KP7 script-message mpv.net cycle-audio #menu: Audio > Cycle/Next
|
KP7 script-message mpv.net cycle-audio #menu: Audio > Cycle/Next
|
||||||
_ ignore #menu: Audio > -
|
_ ignore #menu: Audio > -
|
||||||
KP6 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.100 #menu: Audio > Delay -0.1
|
KP9 add audio-delay -0.1 #menu: Audio > Delay -0.1
|
||||||
|
|
||||||
KP8 cycle sub #menu: Subtitle > Cycle/Next
|
KP8 cycle sub #menu: Subtitle > Cycle/Next
|
||||||
v cycle sub-visibility #menu: Subtitle > Toggle Visibility
|
v cycle sub-visibility #menu: Subtitle > Toggle Visibility
|
||||||
@@ -110,7 +113,7 @@
|
|||||||
_ ignore #menu: Volume > -
|
_ ignore #menu: Volume > -
|
||||||
m cycle mute #menu: Volume > Mute
|
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%
|
] multiply speed 1.1 #menu: Speed > +10%
|
||||||
_ ignore #menu: Speed > -
|
_ ignore #menu: Speed > -
|
||||||
{ multiply speed 0.5 #menu: Speed > Half
|
{ multiply speed 0.5 #menu: Speed > Half
|
||||||
@@ -144,6 +147,7 @@
|
|||||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
|
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
|
||||||
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
||||||
|
_ script-message mpv.net manage-file-associations #menu: Tools > Manage File Associations...
|
||||||
|
|
||||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual
|
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual
|
||||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > Show mpv default keys
|
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > Show mpv default keys
|
||||||
@@ -172,3 +176,5 @@
|
|||||||
Wheel_Down add volume -10
|
Wheel_Down add volume -10
|
||||||
Prev playlist-prev
|
Prev playlist-prev
|
||||||
Next playlist-next
|
Next playlist-next
|
||||||
|
|
||||||
|
MBTN_LEFT_DBL cycle fullscreen
|
||||||
@@ -1,646 +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;
|
|
||||||
|
|
||||||
using Microsoft.VisualBasic.CompilerServices;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 = "[copymsg Copy Message]";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
|
||||||
td.Footer += $" [{SupportURL} Contact Support]";
|
|
||||||
|
|
||||||
td.Show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = "[copymsg Copy Message]";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
|
||||||
td.Footer += $" [{SupportURL} Contact Support]";
|
|
||||||
|
|
||||||
td.Show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(ex.GetType().Name + "\n\n" + e.Message + "\n\n" + e.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)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = ExpandWikiMarkup(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ExpandedInformation {
|
|
||||||
get => Config.pszExpandedInformation;
|
|
||||||
set => Config.pszExpandedInformation = ExpandWikiMarkup(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 = ExpandWikiMarkup(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 ExpandWikiMarkup(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=\"$1\">$2</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 (Operators.CompareString(stringUni, "copymsg", false) == 0)
|
|
||||||
{
|
|
||||||
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
@@ -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,
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="About mpv.net" Height="230" Width="420" FontSize="16" ShowInTaskbar="False"
|
Title="About mpv.net" Height="230" Width="420" FontSize="16" ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterOwner" ResizeMode="NoResize" PreviewKeyDown="Window_PreviewKeyDown">
|
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
|
||||||
<Grid>
|
<Grid>
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ namespace mpvnet
|
|||||||
Foreground = WPF.WPF.ThemeBrush;
|
Foreground = WPF.WPF.ThemeBrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
|
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();
|
||||||
{
|
protected override void OnMouseDown(MouseButtonEventArgs e) => Close();
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -19,11 +23,20 @@ namespace mpvnet
|
|||||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||||
CollectionView.Filter = yourCostumFilter;
|
CollectionView.Filter = yourCostumFilter;
|
||||||
ListView.ItemsSource = CollectionView;
|
ListView.ItemsSource = CollectionView;
|
||||||
|
|
||||||
|
if (App.IsDarkMode)
|
||||||
|
{
|
||||||
|
ListView.Foreground = Brushes.White;
|
||||||
|
ListView.Background = Brushes.Black;
|
||||||
|
FilterTextBox.Foreground = Brushes.White;
|
||||||
|
FilterTextBox.Background = Brushes.Black;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter(CommandItem item)
|
bool Filter(CommandItem item)
|
||||||
{
|
{
|
||||||
if (item.Command == "") return false;
|
if (item.Command == "" || item.Path == "")
|
||||||
|
return false;
|
||||||
string filter = FilterTextBox.Text.ToLower();
|
string filter = FilterTextBox.Text.ToLower();
|
||||||
if (filter == "") return true;
|
if (filter == "") return true;
|
||||||
if (item.Command.ToLower().Contains(filter) ||
|
if (item.Command.ToLower().Contains(filter) ||
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
||||||
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
||||||
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
||||||
<TextBlock x:Name="ApplyTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static WPF:WPF.ThemeBrush}" MouseUp="ApplyTextBlock_MouseUp">Write config to disk</TextBlock>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -3,14 +3,12 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
using DynamicGUI;
|
using DynamicGUI;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -29,8 +27,14 @@ namespace mpvnet
|
|||||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||||
LoadSettings(MpvSettingsDefinitions, MpvConf);
|
LoadSettings(MpvSettingsDefinitions, MpvConf);
|
||||||
LoadSettings(MpvNetSettingsDefinitions, MpvNetConf);
|
LoadSettings(MpvNetSettingsDefinitions, MpvNetConf);
|
||||||
SearchControl.Text = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\mpv.net", "conf editor search", "");
|
SearchControl.Text = RegistryHelp.GetString(@"HKCU\Software\mpv.net", "config editor search");
|
||||||
SetDarkTheme();
|
|
||||||
|
if (App.IsDarkMode)
|
||||||
|
{
|
||||||
|
Foreground = Brushes.White;
|
||||||
|
Foreground2 = Brushes.Silver;
|
||||||
|
Background = Brushes.Black;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Brush Foreground2 {
|
public Brush Foreground2 {
|
||||||
@@ -41,22 +45,6 @@ namespace mpvnet
|
|||||||
public static readonly DependencyProperty Foreground2Property =
|
public static readonly DependencyProperty Foreground2Property =
|
||||||
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(ConfWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(ConfWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
||||||
|
|
||||||
void SetDarkTheme()
|
|
||||||
{
|
|
||||||
string darkMode = MpvNetSettingsDefinitions.Where(item => item.Name == "dark-mode").First().Value;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!((darkMode == "system" && isDarkTheme) || darkMode == "always"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Foreground = Brushes.White;
|
|
||||||
Foreground2 = Brushes.Silver;
|
|
||||||
Background = Brushes.Black;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadSettings(List<SettingBase> settingsDefinitions,
|
private void LoadSettings(List<SettingBase> settingsDefinitions,
|
||||||
Dictionary<string, string> confSettings)
|
Dictionary<string, string> confSettings)
|
||||||
{
|
{
|
||||||
@@ -126,7 +114,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (left.StartsWith("#"))
|
if (left.StartsWith("#"))
|
||||||
{
|
{
|
||||||
Comments[filePath][left.TrimStart("#".ToCharArray())] = right;
|
Comments[filePath][left.TrimStart('#')] = right;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +131,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
base.OnClosed(e);
|
base.OnClosed(e);
|
||||||
WriteToDisk();
|
WriteToDisk();
|
||||||
Registry.SetValue(@"HKEY_CURRENT_USER\Software\mpv.net", "conf editor search", SearchControl.Text);
|
RegistryHelp.SetObject(@"HKCU\Software\mpv.net", "config editor search", SearchControl.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteToDisk()
|
void WriteToDisk()
|
||||||
@@ -164,8 +152,7 @@ namespace mpvnet
|
|||||||
WriteToDisk(mp.MpvConfPath, MpvConf, MpvSettingsDefinitions);
|
WriteToDisk(mp.MpvConfPath, MpvConf, MpvSettingsDefinitions);
|
||||||
WriteToDisk(mp.MpvNetConfPath, MpvNetConf, MpvNetSettingsDefinitions);
|
WriteToDisk(mp.MpvNetConfPath, MpvNetConf, MpvNetSettingsDefinitions);
|
||||||
|
|
||||||
MessageBox.Show("Changes will be available on next mpv.net startup.",
|
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||||
Title, MessageBoxButton.OK, MessageBoxImage.Information);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteToDisk(string filePath,
|
void WriteToDisk(string filePath,
|
||||||
@@ -251,9 +238,11 @@ namespace mpvnet
|
|||||||
Process.Start("https://github.com/stax76/mpv.net#Support");
|
Process.Start("https://github.com/stax76/mpv.net#Support");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
{
|
{
|
||||||
WriteToDisk();
|
base.OnKeyDown(e);
|
||||||
|
if (e.Key == Key.Escape)
|
||||||
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
23
mpv.net/Windows/EverythingWindow.xaml
Normal 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>
|
||||||
168
mpv.net/Windows/EverythingWindow.xaml.cs
Normal 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -25,14 +26,29 @@ namespace mpvnet
|
|||||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||||
CollectionView.Filter = yourCostumFilter;
|
CollectionView.Filter = yourCostumFilter;
|
||||||
DataGrid.ItemsSource = CollectionView;
|
DataGrid.ItemsSource = CollectionView;
|
||||||
|
|
||||||
|
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(ConfWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
CollectionView.Refresh();
|
CollectionView.Refresh();
|
||||||
|
|
||||||
if (SearchControl.SearchTextBox.Text == "?")
|
if (SearchControl.SearchTextBox.Text == "?")
|
||||||
MessageBox.Show("Filtering works by searching in the Input, Menu and Command but it's possible to reduce the filter scope to either of Input, Menu or Command by prefixing as follows:\n\ni <input search>\ni: <input search>\n\nm <menu search>\nm: <menu search>\n\nc <command search>\nc: <command search>\n\nIf only one character is entered the search will be performed only in the input.", "Filtering", MessageBoxButton.OK, MessageBoxImage.Information);
|
Msg.Show("Filtering works by searching in the Input, Menu and Command but it's possible to reduce the filter scope to either of Input, Menu or Command by prefixing as follows:\n\ni <input search>\ni: <input search>\n\nm <menu search>\nm: <menu search>\n\nc <command search>\nc: <command search>\n\nIf only one character is entered the search will be performed only in the input.", "Filtering");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter(CommandItem item)
|
bool Filter(CommandItem item)
|
||||||
@@ -77,7 +93,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
foreach (CommandItem i in CommandItem.Items)
|
foreach (CommandItem i in CommandItem.Items)
|
||||||
if (items.ContainsKey(i.Input) && i.Input != "")
|
if (items.ContainsKey(i.Input) && i.Input != "")
|
||||||
MessageBox.Show($"Duplicate found:\n\n{i.Input}: {i.Path}\n\n{items[i.Input].Input}: {items[i.Input].Path}\n\nPlease note that you can chain multiple commands in the same line by using a semicolon as separator.", "Duplicate Found", MessageBoxButton.OK, MessageBoxImage.Warning);
|
Msg.Show($"Duplicate found:\n\n{i.Input}: {i.Path}\n\n{items[i.Input].Input}: {items[i.Input].Path}\n\nPlease note that you can chain multiple commands in the same line by using a semicolon as separator.", "Duplicate Found");
|
||||||
else
|
else
|
||||||
items[i.Input] = i;
|
items[i.Input] = i;
|
||||||
}
|
}
|
||||||
@@ -110,8 +126,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (InitialInputConfContent == GetInputConfContent()) return;
|
if (InitialInputConfContent == GetInputConfContent()) return;
|
||||||
File.WriteAllText(mp.InputConfPath, GetInputConfContent());
|
File.WriteAllText(mp.InputConfPath, GetInputConfContent());
|
||||||
MessageBox.Show("Changes will be available on next mpv.net startup.",
|
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||||
Title, MessageBoxButton.OK, MessageBoxImage.Information);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
private void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
||||||
@@ -119,8 +134,15 @@ namespace mpvnet
|
|||||||
DataGrid grid = (DataGrid)sender;
|
DataGrid grid = (DataGrid)sender;
|
||||||
|
|
||||||
if (e.Command == DataGrid.DeleteCommand)
|
if (e.Command == DataGrid.DeleteCommand)
|
||||||
if (MessageBox.Show($"Confirm to delete: {(grid.SelectedItem as CommandItem).Input} ({(grid.SelectedItem as CommandItem).Path})", "Confirm Delete", MessageBoxButton.OKCancel, MessageBoxImage.Question) != MessageBoxResult.OK)
|
if (Msg.ShowQuestion($"Confirm to delete: {(grid.SelectedItem as CommandItem).Input} ({(grid.SelectedItem as CommandItem).Path})") != MsgResult.OK)
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnKeyDown(e);
|
||||||
|
if (e.Key == Key.Escape)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,13 +11,9 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Sys;
|
|
||||||
|
|
||||||
using static mpvnet.libmpv;
|
using static mpvnet.libmpv;
|
||||||
using static mpvnet.Native;
|
using static mpvnet.Native;
|
||||||
|
|
||||||
using PyRT = IronPython.Runtime;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
||||||
@@ -25,7 +21,7 @@ namespace mpvnet
|
|||||||
public class mp
|
public class mp
|
||||||
{
|
{
|
||||||
public static event Action VideoSizeChanged;
|
public static event Action VideoSizeChanged;
|
||||||
// Lua/JS evens libmpv events
|
// Lua/JS event libmpv event
|
||||||
|
|
||||||
// MPV_EVENT_NONE
|
// MPV_EVENT_NONE
|
||||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||||
@@ -78,25 +74,29 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
string portableFolder = Application.StartupPath + "\\portable_config\\";
|
string portableFolder = Application.StartupPath + "\\portable_config\\";
|
||||||
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
||||||
|
string startupFolder = Application.StartupPath + "\\";
|
||||||
|
|
||||||
if (!Directory.Exists(appdataFolder) && !Directory.Exists(portableFolder) &&
|
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>())
|
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||||
{
|
{
|
||||||
td.MainInstruction = "Choose a settings folder.";
|
td.MainInstruction = "Choose a settings folder.";
|
||||||
td.Content = "[https://mpv.io/manual/master/#files-on-windows MPV documentation about files on Windows.]";
|
td.Content = "[MPV documentation about files on Windows.](https://mpv.io/manual/master/#files-on-windows)";
|
||||||
td.AddCommandLink("appdata", appdataFolder, appdataFolder);
|
td.AddCommandLink("appdata", appdataFolder, appdataFolder);
|
||||||
td.AddCommandLink("portable", portableFolder, portableFolder);
|
td.AddCommandLink("portable", portableFolder, portableFolder);
|
||||||
|
td.AddCommandLink("startup", startupFolder, startupFolder);
|
||||||
td.AllowCancel = false;
|
td.AllowCancel = false;
|
||||||
_MpvConfFolder = td.Show();
|
_MpvConfFolder = td.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Directory.Exists(portableFolder))
|
||||||
if (Directory.Exists(portableFolder))
|
|
||||||
_MpvConfFolder = portableFolder;
|
_MpvConfFolder = portableFolder;
|
||||||
else
|
else if (Directory.Exists(appdataFolder))
|
||||||
_MpvConfFolder = appdataFolder;
|
_MpvConfFolder = appdataFolder;
|
||||||
|
else if (File.Exists(Application.StartupPath + "\\mpv.conf"))
|
||||||
|
_MpvConfFolder = Application.StartupPath + "\\";
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_MpvConfFolder)) _MpvConfFolder = appdataFolder;
|
if (string.IsNullOrEmpty(_MpvConfFolder)) _MpvConfFolder = appdataFolder;
|
||||||
if (!Directory.Exists(_MpvConfFolder)) Directory.CreateDirectory(_MpvConfFolder);
|
if (!Directory.Exists(_MpvConfFolder)) Directory.CreateDirectory(_MpvConfFolder);
|
||||||
@@ -278,7 +278,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
List<string> names = mpvnet.Command.Commands.Select((item) => item.Name).ToList();
|
List<string> names = mpvnet.Command.Commands.Select((item) => item.Name).ToList();
|
||||||
names.Sort();
|
names.Sort();
|
||||||
Msg.ShowError($"No command '{args[1]}' found.", $"Available commands are:\n\n{string.Join("\n", names)}\n\nHow to bind these commands can be seen in the [https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt default input bindings and menu definition].");
|
Msg.ShowError($"No command '{args[1]}' found.", $"Available commands are:\n\n{string.Join("\n", names)}\n\nHow to bind these commands can be seen in the [default input bindings and menu definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClientMessage?.Invoke(args);
|
ClientMessage?.Invoke(args);
|
||||||
@@ -345,7 +345,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
|
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())
|
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)
|
foreach (var eventObjects in PythonEventObjects)
|
||||||
if (eventObjects.PythonFunction == pyFunc)
|
if (eventObjects.PythonFunction == pyFunc)
|
||||||
@@ -522,8 +522,6 @@ namespace mpvnet
|
|||||||
foreach (string i in args)
|
foreach (string i in args)
|
||||||
if (!i.StartsWith("--") && File.Exists(i))
|
if (!i.StartsWith("--") && File.Exists(i))
|
||||||
mp.commandv("loadfile", i, "append");
|
mp.commandv("loadfile", i, "append");
|
||||||
else if (!i.StartsWith("--") && i.StartsWith("http"))
|
|
||||||
mp.LoadURL(i);
|
|
||||||
|
|
||||||
mp.set_property_string("playlist-pos", "0");
|
mp.set_property_string("playlist-pos", "0");
|
||||||
|
|
||||||
@@ -543,16 +541,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadURL(string url)
|
public static void LoadFiles(params string[] files)
|
||||||
{
|
|
||||||
int count = mp.get_property_int("playlist-count");
|
|
||||||
mp.commandv("loadfile", url, "append");
|
|
||||||
mp.set_property_int("playlist-pos", count);
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
mp.commandv("playlist-remove", "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LoadFiles(string[] files)
|
|
||||||
{
|
{
|
||||||
int count = mp.get_property_int("playlist-count");
|
int count = mp.get_property_int("playlist-count");
|
||||||
|
|
||||||
@@ -571,23 +560,20 @@ namespace mpvnet
|
|||||||
|
|
||||||
static void LoadFolder()
|
static void LoadFolder()
|
||||||
{
|
{
|
||||||
if (WasFolderLoaded)
|
if (WasFolderLoaded) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (get_property_int("playlist-count") == 1)
|
if (get_property_int("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 = get_property_string("path");
|
string path = get_property_string("path");
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(path))) return;
|
if (!File.Exists(path)) return;
|
||||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
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());
|
files.Sort(new StringLogicalComparer());
|
||||||
int index = files.IndexOf(path);
|
int index = files.IndexOf(path);
|
||||||
files.Remove(path);
|
files.Remove(path);
|
||||||
|
|
||||||
foreach (string i in files)
|
foreach (string i in files)
|
||||||
commandv("loadfile", i, "append");
|
commandv("loadfile", i, "append");
|
||||||
|
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
commandv("playlist-move", "0", (index + 1).ToString());
|
commandv("playlist-move", "0", (index + 1).ToString());
|
||||||
}
|
}
|
||||||
@@ -677,7 +663,7 @@ namespace mpvnet
|
|||||||
Add(track, mi.GetVideo(i, "Forced") == "Yes" ? "Forced" : "");
|
Add(track, mi.GetVideo(i, "Forced") == "Yes" ? "Forced" : "");
|
||||||
Add(track, mi.GetVideo(i, "Default") == "Yes" ? "Default" : "");
|
Add(track, mi.GetVideo(i, "Default") == "Yes" ? "Default" : "");
|
||||||
Add(track, mi.GetVideo(i, "Title"));
|
Add(track, mi.GetVideo(i, "Title"));
|
||||||
track.Text = "V: " + track.Text.Trim(" ,".ToCharArray());
|
track.Text = "V: " + track.Text.Trim(' ', ',');
|
||||||
track.Type = "v";
|
track.Type = "v";
|
||||||
track.ID = i + 1;
|
track.ID = i + 1;
|
||||||
MediaTracks.Add(track);
|
MediaTracks.Add(track);
|
||||||
@@ -697,7 +683,7 @@ namespace mpvnet
|
|||||||
Add(track, mi.GetAudio(i, "Forced") == "Yes" ? "Forced" : "");
|
Add(track, mi.GetAudio(i, "Forced") == "Yes" ? "Forced" : "");
|
||||||
Add(track, mi.GetAudio(i, "Default") == "Yes" ? "Default" : "");
|
Add(track, mi.GetAudio(i, "Default") == "Yes" ? "Default" : "");
|
||||||
Add(track, mi.GetAudio(i, "Title"));
|
Add(track, mi.GetAudio(i, "Title"));
|
||||||
track.Text = "A: " + track.Text.Trim(" ,".ToCharArray());
|
track.Text = "A: " + track.Text.Trim(' ', ',');
|
||||||
track.Type = "a";
|
track.Type = "a";
|
||||||
track.ID = i + 1;
|
track.ID = i + 1;
|
||||||
MediaTracks.Add(track);
|
MediaTracks.Add(track);
|
||||||
@@ -714,7 +700,7 @@ namespace mpvnet
|
|||||||
Add(track, mi.GetText(i, "Forced") == "Yes" ? "Forced" : "");
|
Add(track, mi.GetText(i, "Forced") == "Yes" ? "Forced" : "");
|
||||||
Add(track, mi.GetText(i, "Default") == "Yes" ? "Default" : "");
|
Add(track, mi.GetText(i, "Default") == "Yes" ? "Default" : "");
|
||||||
Add(track, mi.GetText(i, "Title"));
|
Add(track, mi.GetText(i, "Title"));
|
||||||
track.Text = "S: " + track.Text.Trim(" ,".ToCharArray());
|
track.Text = "S: " + track.Text.Trim(' ', ',');
|
||||||
track.Type = "s";
|
track.Type = "s";
|
||||||
track.ID = i + 1;
|
track.ID = i + 1;
|
||||||
MediaTracks.Add(track);
|
MediaTracks.Add(track);
|
||||||
|
|||||||
BIN
mpv.net/mpv.ico
|
Before Width: | Height: | Size: 264 KiB |
@@ -35,52 +35,13 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<StartupObject>mpvnet.Program</StartupObject>
|
<StartupObject>mpvnet.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<OutputPath>bin\x64\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
|
||||||
<OutputPath>bin\x86\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
@@ -90,11 +51,51 @@
|
|||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationIcon>mpv.ico</ApplicationIcon>
|
<ApplicationIcon>mpvnet.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\x86\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
@@ -145,6 +146,10 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Windows\EverythingWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Include="Windows\CommandPaletteWindow.xaml">
|
<Page Include="Windows\CommandPaletteWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -189,7 +194,10 @@
|
|||||||
<Compile Include="NativeHelp.cs" />
|
<Compile Include="NativeHelp.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.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">
|
<Compile Include="Windows\CommandPaletteWindow.xaml.cs">
|
||||||
<DependentUpon>CommandPaletteWindow.xaml</DependentUpon>
|
<DependentUpon>CommandPaletteWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -218,7 +226,6 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<None Include="..\README.md">
|
<None Include="..\README.md">
|
||||||
<Link>README.md</Link>
|
<Link>README.md</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="app.manifest" />
|
<None Include="app.manifest" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
@@ -235,6 +242,7 @@
|
|||||||
<Link>LICENSE.txt</Link>
|
<Link>LICENSE.txt</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="mpvnet.ico" />
|
||||||
<Content Include="Resources\mpvConf.txt" />
|
<Content Include="Resources\mpvConf.txt" />
|
||||||
<Content Include="Resources\mpvConfToml.txt" />
|
<Content Include="Resources\mpvConfToml.txt" />
|
||||||
<Content Include="Resources\mpvNetConfToml.txt" />
|
<Content Include="Resources\mpvNetConfToml.txt" />
|
||||||
@@ -243,9 +251,7 @@
|
|||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="mpv.ico" />
|
|
||||||
<Content Include="Resources\inputConfHeader.txt" />
|
<Content Include="Resources\inputConfHeader.txt" />
|
||||||
<Content Include="screenshot.jpg" />
|
|
||||||
<Content Include="Resources\inputConf.txt" />
|
<Content Include="Resources\inputConf.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
BIN
mpv.net/mpvnet.ico
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 497 KiB |
@@ -1,7 +0,0 @@
|
|||||||
$scriptDir = Split-Path -Path $PSCommandPath -Parent
|
|
||||||
$exePath = $scriptDir + "\mpv.net\bin\mpvnet.exe"
|
|
||||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
|
||||||
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
|
||||||
$targetDir = $desktopDir + "\mpv.net-" + $version
|
|
||||||
Copy-Item $scriptDir\mpv.net\bin $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
|
||||||
& "C:\Program Files\7-Zip\7z.exe" a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
|
||||||
28
setup.iss
@@ -1,19 +1,33 @@
|
|||||||
#define MyAppName "mpv.net"
|
#define MyAppName "mpv.net"
|
||||||
#define MyAppVersion GetFileVersion("mpv.net\bin\mpvnet.exe")
|
|
||||||
#define MyAppExeName "mpvnet.exe"
|
#define MyAppExeName "mpvnet.exe"
|
||||||
#define MyAppSourceDir "mpv.net\bin"
|
|
||||||
|
#ifndef arch
|
||||||
|
#define arch "x64"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if arch == "x64"
|
||||||
|
#define MyAppSourceDir "mpv.net\bin\x64"
|
||||||
|
#define MyAppVersion GetFileVersion("mpv.net\bin\x64\mpvnet.exe")
|
||||||
|
#else
|
||||||
|
#define MyAppSourceDir "mpv.net\bin\x86"
|
||||||
|
#define MyAppVersion GetFileVersion("mpv.net\bin\x86\mpvnet.exe")
|
||||||
|
#endif
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppId={{9AA2B100-BEF3-44D0-B819-D8FC3C4D557D}}
|
AppId={{9AA2B100-BEF3-44D0-B819-D8FC3C4D557D}}
|
||||||
AppName={#MyAppName}
|
AppName={#MyAppName}
|
||||||
AppVersion={#MyAppVersion}
|
AppVersion={#MyAppVersion}
|
||||||
AppPublisher=stax76
|
AppPublisher=Frank Skare (stax76)
|
||||||
|
#if arch == "x64"
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
#endif
|
||||||
Compression=lzma2
|
Compression=lzma2
|
||||||
DefaultDirName={pf}\{#MyAppName}
|
DefaultDirName={commonpf}\{#MyAppName}
|
||||||
OutputBaseFilename=mpvnet-{#MyAppVersion}
|
OutputBaseFilename=mpv.net-setup-{#arch}-{#MyAppVersion}
|
||||||
OutputDir=C:\Users\frank\Desktop
|
OutputDir={#GetEnv('USERPROFILE')}\Desktop
|
||||||
DefaultGroupName={#MyAppName}
|
DefaultGroupName={#MyAppName}
|
||||||
|
SetupIconFile=mpv.net\mpvnet.ico
|
||||||
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
@@ -27,4 +41,4 @@ Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions
|
|||||||
Filename: "{app}\{#MyAppExeName}"; Description: "Associate audio file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc audio"
|
Filename: "{app}\{#MyAppExeName}"; Description: "Associate audio file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc audio"
|
||||||
|
|
||||||
[UninstallRun]
|
[UninstallRun]
|
||||||
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unregister"
|
Filename: "{app}\{#MyAppExeName}"; Flags: runascurrentuser runhidden; Parameters: "--reg-file-assoc unreg"
|
||||||
51
setup.ps1
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
function CheckExitCode {
|
||||||
|
if ($LastExitCode -gt 0) {
|
||||||
|
Write-Host "`nExit code $LastExitCode was returned.`n" -ForegroundColor Red
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$msbuild = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
|
||||||
|
|
||||||
|
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x64
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x86
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /Darch="x64" setup.iss
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /Darch="x86" setup.iss
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
$scriptDir = Split-Path -Path $PSCommandPath -Parent
|
||||||
|
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
||||||
|
|
||||||
|
$exePath = $scriptDir + "\mpv.net\bin\x64\mpvnet.exe"
|
||||||
|
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||||
|
$targetDir = $desktopDir + "\mpv.net-portable-x64-" + $version
|
||||||
|
Copy-Item $scriptDir\mpv.net\bin\x64 $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
||||||
|
& "C:\Program Files\7-Zip\7z.exe" a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
& "C:\Program Files\7-Zip\7z.exe" a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
$exePath = $scriptDir + "\mpv.net\bin\x86\mpvnet.exe"
|
||||||
|
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||||
|
$targetDir = $desktopDir + "\mpv.net-portable-x86-" + $version
|
||||||
|
Copy-Item $scriptDir\mpv.net\bin\x86 $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
|
||||||
|
& "C:\Program Files\7-Zip\7z.exe" a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||
|
|
||||||
|
& "C:\Program Files\7-Zip\7z.exe" a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"
|
||||||
|
|
||||||
|
CheckExitCode
|
||||||