This commit is contained in:
Frank Skare
2019-04-26 11:22:07 +02:00
parent c9ffbaa679
commit d777ca912a
19 changed files with 663 additions and 1139 deletions

View File

@@ -115,8 +115,7 @@ Examples:
### Architecture ### Architecture
mpv.net is mostly written in C# 7.0 and runs on the .NET framework 4.7 or higher. mpv.net is written in C# 7.0 and runs on the .NET framework 4.7 or higher.
Few parts are written in VB.NET and Python.
The Add-on implementation is based on the Managed Extensibility Framework, The Add-on implementation is based on the Managed Extensibility Framework,
the entire application code is accessible for add-ons and Python scripts. the entire application code is accessible for add-ons and Python scripts.

View File

@@ -1,13 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -1,35 +0,0 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
' Review the values of the assembly attributes
<Assembly: AssemblyTitle("VBNET")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("VBNET")>
<Assembly: AssemblyCopyright("Copyright © 2019")>
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'The following GUID is for the ID of the typelib if this project is exposed to COM
<Assembly: Guid("a5571ff4-12ae-4e1a-ad2b-863b07d1b952")>
' Version information for an assembly consists of the following four values:
'
' Major Version
' Minor Version
' Build Number
' Revision
'
' You can specify all the values or you can default the Build and Revision Numbers
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")>

View File

@@ -1,62 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("VBNET.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set(ByVal value As Global.System.Globalization.CultureInfo)
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

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

View File

@@ -1,73 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.VBNET.My.MySettings
Get
Return Global.VBNET.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -1,678 +0,0 @@
Imports System.IO
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Public Delegate Function PFTASKDIALOGCALLBACK(hwnd As IntPtr,
msg As UInteger,
wParam As IntPtr,
lParam As IntPtr,
lpRefData As IntPtr) As Integer
Public Class Msg
Public Shared Property SupportURL As String
Public Shared Sub Show(mainInstruction As String, Optional content As String = Nothing)
Show(mainInstruction, content, MsgIcon.Info, MsgButtons.Ok)
End Sub
Public Shared Sub ShowError(mainInstruction As String, Optional content As String = Nothing)
If mainInstruction = "" Then mainInstruction = content
If mainInstruction = "" Then Exit Sub
Using td As New TaskDialog(Of String)
td.AllowCancel = False
If content = "" Then
If mainInstruction.Length < 80 Then
td.MainInstruction = mainInstruction
Else
td.Content = mainInstruction
End If
Else
td.MainInstruction = mainInstruction
td.Content = content
End If
td.MainIcon = MsgIcon.Error
td.Footer = "[copymsg Copy Message]"
If SupportURL <> "" Then td.Footer += $" [{SupportURL} Contact Support]"
td.Show()
End Using
End Sub
Public Shared Sub ShowException(e As Exception)
Try
Using td As New TaskDialog(Of String)
td.MainInstruction = e.GetType.Name
td.Content = e.Message
td.MainIcon = MsgIcon.Error
td.ExpandedInformation = e.ToString
td.Footer = "[copymsg Copy Message]"
If SupportURL <> "" Then td.Footer += $" [{SupportURL} Contact Support]"
td.Show()
End Using
Catch
MsgBox(e.GetType.Name + vbCrLf + vbCrLf + e.Message + vbCrLf + vbCrLf + e.ToString, MsgBoxStyle.Critical)
End Try
End Sub
Shared ShownMessages As String
Public Shared Sub ShowWarning(mainInstruction As String,
Optional content As String = Nothing,
Optional onlyOnce As Boolean = False)
If onlyOnce AndAlso ShownMessages?.Contains(mainInstruction + content) Then Exit Sub
Show(mainInstruction, content, MsgIcon.Warning, MsgButtons.Ok)
If onlyOnce Then ShownMessages += mainInstruction + content
End Sub
Public Shared Function ShowQuestion(mainInstruction As String,
Optional buttons As MsgButtons = MsgButtons.OkCancel) As MsgResult
Return Show(mainInstruction, Nothing, MsgIcon.None, buttons)
End Function
Public Shared Function ShowQuestion(mainInstruction As String,
content As String,
Optional buttons As MsgButtons = MsgButtons.OkCancel) As MsgResult
Return Show(mainInstruction, content, MsgIcon.None, buttons)
End Function
Public Shared Function Show(mainInstruction As String,
content As String,
icon As MsgIcon,
buttons As MsgButtons,
Optional defaultButton As MsgResult = MsgResult.None) As MsgResult
If mainInstruction Is Nothing Then mainInstruction = ""
Using td As New TaskDialog(Of MsgResult)
td.AllowCancel = False
td.DefaultButton = defaultButton
td.MainIcon = icon
If content Is Nothing Then
If mainInstruction.Length < 80 Then
td.MainInstruction = mainInstruction
Else
td.Content = mainInstruction
End If
Else
td.MainInstruction = mainInstruction
td.Content = content
End If
If buttons = MsgButtons.OkCancel Then
td.AddButton("OK", MsgResult.OK)
td.AddButton("Cancel", MsgResult.Cancel) 'don't use system language
Else
td.CommonButtons = buttons
End If
Return td.Show()
End Using
End Function
End Class
Public Class TaskDialog(Of T)
Inherits TaskDialogNative
Implements IDisposable
Private IdValueDic As New Dictionary(Of Integer, T)
Private IdTextDic As New Dictionary(Of Integer, String)
Private CommandLinkShieldList As New List(Of Integer)
Private ButtonArray As IntPtr, RadioButtonArray As IntPtr
Private Buttons As New List(Of TASKDIALOG_BUTTON)
Private RadioButtons As New List(Of TASKDIALOG_BUTTON)
Private Config As TASKDIALOGCONFIG
Sub New()
Config = New TASKDIALOGCONFIG()
Config.cbSize = CUInt(Marshal.SizeOf(Config))
Config.hwndParent = GetHandle()
Config.hInstance = IntPtr.Zero
Config.dwFlags = TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION
Config.dwCommonButtons = MsgButtons.None
Config.MainIcon = New TASKDIALOGCONFIG_ICON_UNION(0)
Config.FooterIcon = New TASKDIALOGCONFIG_ICON_UNION(0)
Config.cxWidth = 0
Config.cButtons = 0
Config.cRadioButtons = 0
Config.pButtons = IntPtr.Zero
Config.pRadioButtons = IntPtr.Zero
Config.nDefaultButton = 0
Config.nDefaultRadioButton = 0
Config.pszWindowTitle = DirectCast(Assembly.GetEntryAssembly().GetCustomAttributes(GetType(AssemblyProductAttribute), True)(0), AssemblyProductAttribute).Product
Config.pszMainInstruction = ""
Config.pszContent = ""
Config.pszVerificationText = Nothing
Config.pszExpandedInformation = Nothing
Config.pszExpandedControlText = Nothing
Config.pszCollapsedControlText = Nothing
Config.pszFooter = Nothing
Config.pfCallback = New PFTASKDIALOGCALLBACK(AddressOf DialogProc)
End Sub
Function GetHandle() As IntPtr
Dim sb As New StringBuilder(260)
Dim foregroundHandle = GetForegroundWindow()
GetWindowModuleFileName(foregroundHandle, sb, 260)
If Path.GetFileName(sb.ToString.Replace(".vshost", "")) =
Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location) Then
Return foregroundHandle
End If
End Function
#Region "Constants"
Const TDE_CONTENT As Integer = 0
Const TDE_EXPANDED_INFORMATION As Integer = 1
Const TDE_FOOTER As Integer = 2
Const TDE_MAIN_INSTRUCTION As Integer = 3
Const TDN_CREATED As Integer = 0
Const TDN_NAVIGATED As Integer = 1
Const TDN_BUTTON_CLICKED As Integer = 2
Const TDN_HYPERLINK_CLICKED As Integer = 3
Const TDN_TIMER As Integer = 4
Const TDN_DESTROYED As Integer = 5
Const TDN_RADIO_BUTTON_CLICKED As Integer = 6
Const TDN_DIALOG_CONSTRUCTED As Integer = 7
Const TDN_VERIFICATION_CLICKED As Integer = 8
Const TDN_HELP As Integer = 9
Const TDN_EXPANDO_BUTTON_CLICKED As Integer = 10
Const TDM_NAVIGATE_PAGE As Integer = &H400 + 101
Const TDM_CLICK_BUTTON As Integer = &H400 + 102 'wParam = Button ID
Const TDM_SET_MARQUEE_PROGRESS_BAR As Integer = &H400 + 103 'wParam = 0 (nonMarque) wParam != 0 (Marquee)
Const TDM_SET_PROGRESS_BAR_STATE As Integer = &H400 + 104 'wParam = new progress state
Const TDM_SET_PROGRESS_BAR_RANGE As Integer = &H400 + 105 'lParam = MAKELPARAM(nMinRange, nMaxRange)
Const TDM_SET_PROGRESS_BAR_POS As Integer = &H400 + 106 'wParam = new position
Const TDM_SET_PROGRESS_BAR_MARQUEE As Integer = &H400 + 107 'wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
Const TDM_SET_ELEMENT_TEXT As Integer = &H400 + 108 'wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
Const TDM_CLICK_RADIO_BUTTON As Integer = &H400 + 110 'wParam = Radio Button ID
Const TDM_ENABLE_BUTTON As Integer = &H400 + 111 'lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
Const TDM_ENABLE_RADIO_BUTTON As Integer = &H400 + 112 'lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
Const TDM_CLICK_VERIFICATION As Integer = &H400 + 113 'wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
Const TDM_UPDATE_ELEMENT_TEXT As Integer = &H400 + 114 'wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
Const TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE As Integer = &H400 + 115 'wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required)
Const TDM_UPDATE_ICON As Integer = &H400 + 116 'wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise)
#End Region
#Region "Properties"
Private AllowCancelValue As Boolean
WriteOnly Property AllowCancel() As Boolean
Set(Value As Boolean)
If Value Then
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION
ElseIf (Config.dwFlags And TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION) = TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION Then
Config.dwFlags = Config.dwFlags Xor TASKDIALOG_FLAGS.TDF_ALLOW_DIALOG_CANCELLATION
End If
End Set
End Property
Property MainInstruction() As String
Get
Return Config.pszMainInstruction
End Get
Set(Value As String)
Config.pszMainInstruction = Value
End Set
End Property
Property Content() As String
Get
Return Config.pszContent
End Get
Set(Value As String)
Config.pszContent = ExpandWikiMarkup(Value)
End Set
End Property
Property ExpandedInformation() As String
Get
Return Config.pszExpandedInformation
End Get
Set(Value As String)
Config.pszExpandedInformation = ExpandWikiMarkup(Value)
End Set
End Property
Property VerificationText() As String
Get
Return Config.pszVerificationText
End Get
Set(Value As String)
Config.pszVerificationText = Value
End Set
End Property
Property DefaultButton() As MsgResult
Get
Return CType(Config.nDefaultButton, MsgResult)
End Get
Set(Value As MsgResult)
Config.nDefaultButton = Value
End Set
End Property
Property Footer() As String
Get
Return Config.pszFooter
End Get
Set(Value As String)
Config.pszFooter = ExpandWikiMarkup(Value)
End Set
End Property
WriteOnly Property MainIcon() As MsgIcon
Set(Value As MsgIcon)
Config.MainIcon = New TASKDIALOGCONFIG_ICON_UNION(Value)
End Set
End Property
Private SelectedIDValue As Integer = -1
Property SelectedID As Integer
Get
Return SelectedIDValue
End Get
Set(value As Integer)
For Each i In IdValueDic
If i.Key = value Then SelectedIDValue = value
Next
End Set
End Property
Private SelectedValueValue As T
Property SelectedValue() As T
Get
If IdValueDic.ContainsKey(SelectedID) Then Return IdValueDic(SelectedID)
Return SelectedValueValue
End Get
Set(value As T)
SelectedValueValue = value
End Set
End Property
Private SelectedTextValue As String
Property SelectedText() As String
Get
If IdTextDic.ContainsKey(SelectedID) Then Return IdTextDic(SelectedID)
Return SelectedTextValue
End Get
Set(value As String)
SelectedTextValue = value
End Set
End Property
Property CheckBoxChecked() As Boolean
Get
Return (Config.dwFlags And TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) = TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED
End Get
Set(value As Boolean)
If value Then
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED
ElseIf CheckBoxChecked Then
Config.dwFlags = Config.dwFlags Xor TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED
End If
End Set
End Property
Private CommonButtonsValue As MsgButtons
Property CommonButtons() As MsgButtons
Get
Return Config.dwCommonButtons
End Get
Set(Value As MsgButtons)
Config.dwCommonButtons = Value
End Set
End Property
Private TimeoutValue As Integer
Property Timeout As Integer
Get
Return CInt(TimeoutValue / 1000)
End Get
Set(Value As Integer)
TimeoutValue = Value * 1000
If Value > 0 Then
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_CALLBACK_TIMER
End If
End Set
End Property
#End Region
#Region "Methods"
Sub AddButton(text As String, value As T)
Dim id = 1000 + IdValueDic.Count + 1
IdValueDic(id) = value
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
End Sub
Function ExpandWikiMarkup(value As String) As String
If value.Contains("[") Then
Dim re As New Regex("\[(.*?) (.+?)\]")
Dim m = re.Match(value)
If m.Success Then
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS
value = re.Replace(value, "<a href=""$1"">$2</a>")
End If
End If
Return value
End Function
Sub AddCommandLink(text As String, Optional value As T = Nothing)
Dim id = 1000 + IdValueDic.Count + 1
Dim temp As Object = text
IdValueDic(id) = If(value Is Nothing, CType(temp, T), value)
IdTextDic(id) = text
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS
End Sub
Sub AddCommandLink(text As String,
description As String,
value As T,
Optional setShield As Boolean = False)
Dim id = 1000 + IdValueDic.Count + 1
IdValueDic(id) = value
If setShield Then CommandLinkShieldList.Add(id)
If description <> "" Then text = text + vbCrLf + description
Buttons.Add(New TASKDIALOG_BUTTON(id, text))
Config.dwFlags = Config.dwFlags Or TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS
End Sub
Sub AddRadioButton(text As String, value As T)
Dim id = 1000 + IdValueDic.Count + 1
IdValueDic(id) = value
RadioButtons.Add(New TASKDIALOG_BUTTON(id, text))
End Sub
Function Show() As T
MarshalDialogControlStructs()
Dim isChecked As Boolean
Dim hr = TaskDialogIndirect(Config, Nothing, Nothing, isChecked)
CheckBoxChecked = isChecked
If hr < 0 Then Marshal.ThrowExceptionForHR(hr)
If TypeOf SelectedValue Is MsgResult Then SelectedValue = DirectCast(CObj(SelectedID), T)
Return SelectedValue
End Function
Private ExitTickCount As Integer
Function DialogProc(hwnd As IntPtr,
msg As UInteger,
wParam As IntPtr,
lParam As IntPtr,
lpRefData As IntPtr) As Integer
Select Case msg
Case TDN_BUTTON_CLICKED, TDN_RADIO_BUTTON_CLICKED
If TypeOf SelectedValue Is MsgResult Then
SelectedIDValue = wParam.ToInt32
Else
SelectedID = wParam.ToInt32
End If
Case TDN_TIMER
If ExitTickCount = 0 Then
ExitTickCount = Environment.TickCount + Timeout * 1000
End If
If Environment.TickCount > ExitTickCount Then
SendMessage(hwnd, TDM_CLICK_BUTTON, New IntPtr(MsgResult.OK), IntPtr.Zero)
End If
Case TDN_HYPERLINK_CLICKED
Dim url = Marshal.PtrToStringUni(lParam)
If url.StartsWith("mailto") OrElse url.StartsWith("http") Then
Process.Start(url)
ElseIf url = "copymsg" Then
Dim thread As New Thread(
New ThreadStart(Sub()
System.Windows.Forms.Clipboard.SetText(MainInstruction + vbCrLf + vbCrLf + Content + vbCrLf + vbCrLf + ExpandedInformation)
MsgBox("Message was copied to clipboard.",
MsgBoxStyle.Information,
DirectCast(Assembly.GetEntryAssembly().GetCustomAttributes(GetType(AssemblyProductAttribute), True)(0), AssemblyProductAttribute).Product)
End Sub))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
End If
Case TDN_CREATED
For Each i In CommandLinkShieldList
SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, New IntPtr(i), New IntPtr(1))
Next
End Select
End Function
Sub MarshalDialogControlStructs()
If Not Buttons Is Nothing AndAlso Buttons.Count > 0 Then
ButtonArray = AllocateAndMarshalButtons(Buttons)
Config.pButtons = ButtonArray
Config.cButtons = CUInt(Buttons.Count)
End If
If Not RadioButtons Is Nothing AndAlso RadioButtons.Count > 0 Then
RadioButtonArray = AllocateAndMarshalButtons(RadioButtons)
Config.pRadioButtons = RadioButtonArray
Config.cRadioButtons = CUInt(RadioButtons.Count)
End If
End Sub
Shared Function AllocateAndMarshalButtons(structs As List(Of TASKDIALOG_BUTTON)) As IntPtr
Dim initialPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(TASKDIALOG_BUTTON)) * structs.Count)
Dim currentPtr = initialPtr
For Each button In structs
Marshal.StructureToPtr(button, currentPtr, False)
currentPtr = CType((currentPtr.ToInt64 + Marshal.SizeOf(button)), IntPtr)
Next
Return initialPtr
End Function
#End Region
#Region "IDispose Pattern"
Private disposed As Boolean
Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overrides Sub Finalize()
Try
Dispose(False)
Finally
MyBase.Finalize()
End Try
End Sub
Protected Sub Dispose(disposing As Boolean)
If Not disposed Then
disposed = True
If ButtonArray <> IntPtr.Zero Then
Marshal.FreeHGlobal(ButtonArray)
ButtonArray = IntPtr.Zero
End If
If RadioButtonArray <> IntPtr.Zero Then
Marshal.FreeHGlobal(RadioButtonArray)
RadioButtonArray = IntPtr.Zero
End If
If disposing Then
End If
End If
End Sub
#End Region
End Class
Public Class TaskDialogNative
<DllImport("comctl32", CharSet:=CharSet.Unicode, SetLastError:=True)>
Shared Function TaskDialogIndirect(<[In]()> pTaskConfig As TASKDIALOGCONFIG, <Out()> ByRef pnButton As Integer, <Out()> ByRef pnRadioButton As Integer, <MarshalAs(UnmanagedType.Bool)> <Out()> ByRef pVerificationFlagChecked As Boolean) As Integer
End Function
<DllImport("user32.dll")>
Shared Function GetForegroundWindow() As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode)>
Shared Function GetWindowModuleFileName(hwnd As IntPtr,
lpszFileName As StringBuilder,
cchFileNameMax As UInteger) As UInteger
End Function
<DllImport("user32.dll")>
Shared Function SendMessage(handle As IntPtr,
message As Int32,
wParam As IntPtr,
lParam As IntPtr) As IntPtr
End Function
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=4)>
Public Class TASKDIALOGCONFIG
Public cbSize As UInteger
Public hwndParent As IntPtr
Public hInstance As IntPtr
Public dwFlags As TASKDIALOG_FLAGS
Public dwCommonButtons As MsgButtons
<MarshalAs(UnmanagedType.LPWStr)>
Public pszWindowTitle As String
Public MainIcon As TASKDIALOGCONFIG_ICON_UNION
<MarshalAs(UnmanagedType.LPWStr)>
Public pszMainInstruction As String
<MarshalAs(UnmanagedType.LPWStr)>
Public pszContent As String
Public cButtons As UInteger
Public pButtons As IntPtr
Public nDefaultButton As Integer
Public cRadioButtons As UInteger
Public pRadioButtons As IntPtr
Public nDefaultRadioButton As Integer
<MarshalAs(UnmanagedType.LPWStr)>
Public pszVerificationText As String
<MarshalAs(UnmanagedType.LPWStr)>
Public pszExpandedInformation As String
<MarshalAs(UnmanagedType.LPWStr)>
Public pszExpandedControlText As String
<MarshalAs(UnmanagedType.LPWStr)>
Public pszCollapsedControlText As String
Public FooterIcon As TASKDIALOGCONFIG_ICON_UNION
<MarshalAs(UnmanagedType.LPWStr)>
Public pszFooter As String
Public pfCallback As PFTASKDIALOGCALLBACK
Public lpCallbackData As IntPtr
Public cxWidth As UInteger
End Class
Public Enum TASKDIALOG_FLAGS
NONE = 0
TDF_ENABLE_HYPERLINKS = &H1
TDF_USE_HICON_MAIN = &H2
TDF_USE_HICON_FOOTER = &H4
TDF_ALLOW_DIALOG_CANCELLATION = &H8
TDF_USE_COMMAND_LINKS = &H10
TDF_USE_COMMAND_LINKS_NO_ICON = &H20
TDF_EXPAND_FOOTER_AREA = &H40
TDF_EXPANDED_BY_DEFAULT = &H80
TDF_VERIFICATION_FLAG_CHECKED = &H100
TDF_SHOW_PROGRESS_BAR = &H200
TDF_SHOW_MARQUEE_PROGRESS_BAR = &H400
TDF_CALLBACK_TIMER = &H800
TDF_POSITION_RELATIVE_TO_WINDOW = &H1000
TDF_RTL_LAYOUT = &H2000
TDF_NO_DEFAULT_RADIO_BUTTON = &H4000
End Enum
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Unicode)>
Public Structure TASKDIALOGCONFIG_ICON_UNION
Sub New(i As Integer)
spacer = IntPtr.Zero
pszIcon = 0
hMainIcon = i
End Sub
<FieldOffset(0)>
Public hMainIcon As Integer
<FieldOffset(0)>
Public pszIcon As Integer
<FieldOffset(0)>
Public spacer As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential,
CharSet:=CharSet.Unicode, Pack:=4)>
Public Structure TASKDIALOG_BUTTON
Sub New(n As Integer, txt As String)
nButtonID = n
pszButtonText = txt
End Sub
Public nButtonID As Integer
<MarshalAs(UnmanagedType.LPWStr)>
Public pszButtonText As String
End Structure
End Class
Public Enum MsgButtons
None = &H0
Ok = &H1
Yes = &H2
No = &H4
Cancel = &H8
Retry = &H10
RetryCancel = Retry Or Cancel
Close = &H20
OkCancel = Ok Or Cancel
YesNo = Yes Or No
YesNoCancel = YesNo Or Cancel
End Enum
Public Enum MsgIcon
None = 0
Warning = 65535 'TD_WARNING_ICON
[Error] = 65534 'TD_ERROR_ICON
Info = 65533 'TD_INFORMATION_ICON
Shield = 65532 'TD_SHIELD_ICON
SecurityShieldBlue = 65531
SecurityWarning = 65530
SecurityError = 65529
SecuritySuccess = 65528
SecurityShieldGray = 65527
End Enum
Public Enum MsgResult
None = 0
OK = 1
Cancel = 2
Abort = 3
Retry = 4
Ignore = 5
Yes = 6
No = 7
End Enum

View File

@@ -1,109 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A1D11294-05BF-4D77-B008-AECF1AA93C9F}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>VBNET</RootNamespace>
<AssemblyName>VBNET</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42353,42354,42355</NoWarn>
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42353,42354,42355</NoWarn>
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>On</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="TaskDialog.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@@ -9,8 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}" Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VBNET", "VBNET\VBNET.vbproj", "{A1D11294-05BF-4D77-B008-AECF1AA93C9F}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -57,18 +55,6 @@ Global
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|Any CPU {71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|Any CPU
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|Any CPU {71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|Any CPU
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|Any CPU {71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|x64.ActiveCfg = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|x64.Build.0 = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|x86.ActiveCfg = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Debug|x86.Build.0 = Debug|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|Any CPU.Build.0 = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|x64.ActiveCfg = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|x64.Build.0 = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|x86.ActiveCfg = Release|Any CPU
{A1D11294-05BF-4D77-B008-AECF1AA93C9F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -5,7 +5,7 @@ using System.ComponentModel.Composition.Hosting;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using VBNET; using Sys;
namespace mpvnet namespace mpvnet
{ {

View File

@@ -6,7 +6,8 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Interop; using System.Windows.Interop;
using VBNET;
using Sys;
namespace mpvnet namespace mpvnet
{ {

View File

@@ -7,11 +7,11 @@ using System.Windows.Forms;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using VBNET;
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

View File

@@ -4,8 +4,8 @@ using System.Threading;
using System.Management.Automation.Runspaces; using System.Management.Automation.Runspaces;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms;
using VBNET; using Sys;
namespace mpvnet namespace mpvnet
{ {

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Windows.Forms;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting; using Microsoft.Scripting.Hosting;
using VBNET; using IronPython.Hosting;
using Sys;
using PyRT = IronPython.Runtime; using PyRT = IronPython.Runtime;
namespace mpvnet namespace mpvnet

646
mpv.net/Sys/TaskDialog.cs Normal file
View File

@@ -0,0 +1,646 @@
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,
}
}

View File

@@ -11,7 +11,8 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using VBNET; using Sys;
using static mpvnet.libmpv; using static mpvnet.libmpv;
using static mpvnet.Native; using static mpvnet.Native;
@@ -85,8 +86,9 @@ namespace mpvnet
{ {
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 = "[https://mpv.io/manual/master/#files-on-windows MPV documentation about files on Windows.]";
td.AddCommandLink("appdata", appdataFolder); td.AddCommandLink("appdata", appdataFolder, appdataFolder);
td.AddCommandLink("portable", portableFolder); td.AddCommandLink("portable", portableFolder, portableFolder);
td.AllowCancel = false;
_MpvConfFolder = td.Show(); _MpvConfFolder = td.Show();
} }
} }
@@ -269,7 +271,6 @@ namespace mpvnet
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam); Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
})); }));
} }
} }
if (!found) if (!found)

View File

@@ -185,6 +185,7 @@
<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="Windows\ConfWindow.xaml.cs"> <Compile Include="Windows\ConfWindow.xaml.cs">
<DependentUpon>ConfWindow.xaml</DependentUpon> <DependentUpon>ConfWindow.xaml</DependentUpon>
</Compile> </Compile>
@@ -240,12 +241,6 @@
<Content Include="screenshot.jpg" /> <Content Include="screenshot.jpg" />
<Content Include="Resources\inputConf.txt" /> <Content Include="Resources\inputConf.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VBNET\VBNET.vbproj">
<Project>{a1d11294-05bf-4d77-b008-aecf1aa93c9f}</Project>
<Name>VBNET</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="DynamicGUI\OptionSettingControl.xaml"> <Page Include="DynamicGUI\OptionSettingControl.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>