Compare commits

..

11 Commits
4.5 ... 4.6

Author SHA1 Message Date
Frank Skare
7575a2d736 - 2019-07-06 23:51:28 +02:00
Frank Skare
17c198e711 - 2019-07-06 23:46:14 +02:00
Frank Skare
1f8635e9c4 - 2019-07-06 09:35:14 +02:00
Frank Skare
37e6c198a1 - 2019-07-06 03:46:36 +02:00
Frank Skare
751c8779f4 - 2019-07-06 02:39:25 +02:00
Frank Skare
9e2bf46636 - 2019-07-05 07:17:58 +02:00
Frank Skare
3529323d93 - 2019-07-05 06:36:15 +02:00
Frank Skare
ba52c1f8b5 - 2019-07-05 05:40:14 +02:00
Frank Skare
bf2070d758 - 2019-07-05 05:38:52 +02:00
Frank Skare
7a1de4cf0f - 2019-07-05 05:05:37 +02:00
Frank Skare
caf0bee161 - 2019-07-01 04:17:16 +02:00
13 changed files with 172 additions and 208 deletions

View File

@@ -1,3 +1,19 @@
### 4.6
- fix for middle mouse button not working
- fix of logo overlay using a huge amount of memory (thx for the [ghacks article](https://www.ghacks.net/2019/07/05/a-look-at-mpv-net-a-mpv-frontend-with-everything-integration/))
- fix config dialog showing a message about app restart without reason
- when multiple files are selected in Windows File Explorer and enter is
pressed, the files are opened as selected, the order is random though
because Explorer starts multiple mpv.net processes concurrently
- libmpv was updated to shinchiro 2019-06-30
- the [mpv.conf defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt) were changed to show a larger OSC
- in case a file is opened that has a aspect ratio smaller then 1.2 then
the window size will use a aspect ratio of 1.8
- new JavaScript script osc-visibility.js included in the distribution
under startup\scripts. It sets the OSC to be always on for audio files
and auto for non audio files
### 4.5 ### 4.5
- opening a URL manually no longer uses a input box but uses the clipboard directly - opening a URL manually no longer uses a input box but uses the clipboard directly

View File

@@ -52,12 +52,13 @@ Table of contents
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot)) - Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
- Modern UI with dark mode ([Screenshot](#config-editor-screenshot)) - Modern UI with dark mode ([Screenshot](#config-editor-screenshot))
- 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, IPC and conf files - mpv's OSC, IPC and conf files
- [Command Line Interface](https://mpv.io/manual/master/#options) - [Command Line Interface](https://mpv.io/manual/master/#options)
- DXVA2 video decoding acceleration - 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 - OpenGL based video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot)) - Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
- Extension to start mpv.net from Google Chrome ([Manual](Manual.md#chrome-extension))
### Screenshots ### Screenshots
@@ -86,7 +87,7 @@ A searchable key and mouse binding editor.
#### Command Palette Screenshot #### 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 F1 and find it easily in the searchable command palette.
![Command Palette](https://raw.githubusercontent.com/stax76/mpv.net/master/img/CommandPalette.png) ![Command Palette](https://raw.githubusercontent.com/stax76/mpv.net/master/img/CommandPalette.png)

View File

@@ -1752,7 +1752,6 @@ namespace Tommy
} }
else else
stringBuilder.Append(c); stringBuilder.Append(c);
break; break;
} }
} }

View File

@@ -1,9 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Interop; using System.Windows.Interop;
@@ -13,42 +12,43 @@ namespace mpvnet
{ {
public class Command public class Command
{ {
public string Name { get; set; } public static void Execute(string id, string[] args)
public Action<string[]> Action { get; set; }
static List<Command> commands;
public static List<Command> Commands
{ {
get switch (id)
{ {
if (commands == null) case "manage-file-associations": ManageFileAssociations(); break;
{ case "cycle-audio": CycleAudio(); break;
commands = new List<Command>(); case "load-audio": LoadAudio(); break;
Type type = typeof(Command); case "load-sub": LoadSubtitle(); break;
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); case "open-url": OpenURL(); break;
case "execute-mpv-command": ExecuteMpvCommand(); break;
foreach (MethodInfo i in methods) case "show-history": ShowHistory(); break;
{ case "show-media-search": ShowDialog(typeof(EverythingWindow)); break;
ParameterInfo[] parameters = i.GetParameters(); case "show-command-palette": ShowDialog(typeof(CommandPaletteWindow)); break;
case "show-about": ShowDialog(typeof(AboutWindow)); break;
if (parameters == null || case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
parameters.Length != 1 || case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
parameters[0].ParameterType != typeof(string[])) case "open-conf-folder": Process.Start(mp.ConfFolder); break;
continue; case "open-files": OpenFiles(args); break;
case "shell-execute": Process.Start(args[0]); break;
Command cmd = new Command() { case "show-info": ShowInfo(); break;
Name = i.Name.Replace("_", "-"), case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
Action = (Action<string[]>)i.CreateDelegate(typeof(Action<string[]>)) }; default: Msg.ShowError($"No command '{id}' found."); break;
commands.Add(cmd);
}
}
return commands;
} }
} }
public static void open_files(string[] args) public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
public static void ShowDialog(Type winType)
{
InvokeOnMainThread(new Action(() => {
Window win = Activator.CreateInstance(winType) as Window;
new WindowInteropHelper(win).Owner = MainForm.Instance.Handle;
win.ShowDialog();
}));
}
public static void OpenFiles(params string[] args)
{ {
bool append = Control.ModifierKeys.HasFlag(Keys.Control); bool append = Control.ModifierKeys.HasFlag(Keys.Control);
bool loadFolder = true; bool loadFolder = true;
@@ -59,75 +59,14 @@ namespace mpvnet
if (arg == "no-folder") loadFolder = false; if (arg == "no-folder") loadFolder = false;
} }
MainForm.Instance.Invoke(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog() { Multiselect = true }) using (var d = new OpenFileDialog() { Multiselect = true })
if (d.ShowDialog() == DialogResult.OK) if (d.ShowDialog() == DialogResult.OK)
mp.Load(d.FileNames, loadFolder, append); mp.Load(d.FileNames, loadFolder, append);
})); }));
} }
// deprecated in 2019 public static void ShowHistory()
public static void add_files_to_playlist(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
using (var d = new OpenFileDialog() { Multiselect = true })
if (d.ShowDialog() == DialogResult.OK)
foreach (string file in d.FileNames)
mp.commandv("loadfile", file, "append");
}));
}
public static void open_conf_folder(string[] args)
{
Process.Start(mp.ConfFolder);
}
public static void show_input_editor(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
InputWindow w = new InputWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_conf_editor(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
ConfWindow w = new ConfWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_about(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
AboutWindow w = new AboutWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_command_palette(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
var w = new CommandPaletteWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_media_search(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
var w = new EverythingWindow();
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
w.ShowDialog();
}));
}
public static void show_history(string[] args)
{ {
var fp = mp.ConfFolder + "history.txt"; var fp = mp.ConfFolder + "history.txt";
@@ -139,9 +78,7 @@ namespace mpvnet
File.WriteAllText(fp, ""); File.WriteAllText(fp, "");
} }
public static void shell_execute(string[] args) => Process.Start(args[0]); public static void ShowInfo()
public static void show_info(string[] args)
{ {
try try
{ {
@@ -205,9 +142,9 @@ namespace mpvnet
} }
} }
public static void execute_mpv_command(string[] args) public static void ExecuteMpvCommand()
{ {
MainForm.Instance.Invoke(new Action(() => { InvokeOnMainThread(new Action(() => {
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand")); string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand"));
if (string.IsNullOrEmpty(command)) return; if (string.IsNullOrEmpty(command)) return;
RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command); RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
@@ -215,22 +152,22 @@ namespace mpvnet
})); }));
} }
public static void open_url(string[] args) public static void OpenURL()
{ {
MainForm.Instance.Invoke(new Action(() => { InvokeOnMainThread(new Action(() => {
string clipboard = Clipboard.GetText(); string clipboard = System.Windows.Forms.Clipboard.GetText();
if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n")) if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n"))
{ {
Msg.ShowError("The clipboard does not contain a valid URL or file, URLs have to contain :// and is not allowed to contain a newline character."); Msg.ShowError("The clipboard does not contain a valid URL or file, URLs have to contain :// and are not allowed to contain a newline character.");
return; return;
} }
mp.Load(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control)); mp.Load(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
})); }));
} }
public static void load_sub(string[] args) public static void LoadSubtitle()
{ {
MainForm.Instance.Invoke(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog()) using (var d = new OpenFileDialog())
{ {
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false)); d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
@@ -242,9 +179,9 @@ namespace mpvnet
})); }));
} }
public static void load_audio(string[] args) public static void LoadAudio()
{ {
MainForm.Instance.Invoke(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog()) using (var d = new OpenFileDialog())
{ {
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false)); d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
@@ -257,7 +194,7 @@ namespace mpvnet
})); }));
} }
public static void cycle_audio(string[] args) public static void CycleAudio()
{ {
string filePath = mp.get_property_string("path", false); string filePath = mp.get_property_string("path", false);
if (!File.Exists(filePath)) return; if (!File.Exists(filePath)) return;
@@ -274,7 +211,7 @@ namespace mpvnet
} }
} }
public static void manage_file_associations(string[] args) public static void ManageFileAssociations()
{ {
using (var td = new TaskDialog<string>()) using (var td = new TaskDialog<string>())
{ {
@@ -283,7 +220,7 @@ namespace mpvnet
td.AddCommandLink("Register video file extensions", "video"); td.AddCommandLink("Register video file extensions", "video");
td.AddCommandLink("Register audio file extensions", "audio"); td.AddCommandLink("Register audio file extensions", "audio");
td.AddCommandLink("Unregister file extensions", "unreg"); td.AddCommandLink("Unregister file extensions", "unreg");
string result = td.Show(); string result = td.Show();
@@ -291,14 +228,10 @@ namespace mpvnet
{ {
using (var proc = new Process()) using (var proc = new Process())
{ {
proc.StartInfo.FileName = Application.ExecutablePath; proc.StartInfo.FileName = System.Windows.Forms.Application.ExecutablePath;
proc.StartInfo.Arguments = "--reg-file-assoc " + result; proc.StartInfo.Arguments = "--reg-file-assoc " + result;
proc.StartInfo.Verb = "runas"; proc.StartInfo.Verb = "runas";
try { try { proc.Start(); } catch { }
proc.Start();
}
catch (Exception)
{ }
} }
} }
} }

View File

@@ -109,15 +109,9 @@ namespace mpvnet
} }
else else
{ {
string switchName = i.Substring(2); string name = i.Substring(2);
mp.ProcessProperty(name, "yes");
switch (switchName) ProcessProperty(name, "yes");
{
case "fs":
case "fullscreen":
mp.Fullscreen = true;
break;
}
} }
} }
} }
@@ -228,6 +222,13 @@ namespace mpvnet
return val.ToString(); return val.ToString();
} }
public static int GetInt(string path, string name)
{
object val = GetObject(path, name);
if (val == null || !(val is int)) return 0;
return (int)val;
}
public static object GetObject(string path, string name) 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)))
@@ -393,15 +394,4 @@ namespace mpvnet
Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10; Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10;
} }
} }
public class SingleProcess
{
public static int Message { get; } = RegisterWindowMessage("mpvnet_IPC");
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern int RegisterWindowMessage(string id);
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
}
} }

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
namespace mpvnet namespace mpvnet
{ {
@@ -31,24 +32,31 @@ namespace mpvnet
if ((App.ProcessInstance == "single" || App.ProcessInstance == "queue") && !isFirst) if ((App.ProcessInstance == "single" || App.ProcessInstance == "queue") && !isFirst)
{ {
List<string> files = new List<string>(); List<string> files = new List<string>();
files.Add(App.ProcessInstance);
foreach (string arg in args) foreach (string arg in args)
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || File.Exists(arg))) if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || File.Exists(arg)))
files.Add(arg); files.Add(arg);
if (files.Count > 0) Process[] procs = Process.GetProcessesByName("mpvnet");
RegHelp.SetObject(App.RegPath, "ShellFiles", files.ToArray());
RegHelp.SetObject(App.RegPath, "ProcessInstanceMode", App.ProcessInstance); for (int i = 0; i < 20; i++)
foreach(Process process in Process.GetProcessesByName("mpvnet"))
{ {
try { foreach (Process proc in procs)
SingleProcess.AllowSetForegroundWindow(process.Id); {
Native.SendMessage(process.MainWindowHandle, SingleProcess.Message, IntPtr.Zero, IntPtr.Zero); if (proc.MainWindowHandle != IntPtr.Zero)
} catch {} {
Native.AllowSetForegroundWindow(proc.Id);
var data = new Native.COPYDATASTRUCT();
data.lpData = string.Join("\n", files.ToArray());
data.cbData = data.lpData.Length * 2 + 1;
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
mutex.Dispose();
return;
}
}
Thread.Sleep(50);
} }
mutex.Dispose(); mutex.Dispose();
return; return;
} }

View File

@@ -15,9 +15,15 @@ namespace mpvnet
[DllImport("user32.dll", CharSet = CharSet.Unicode)] [DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern void ReleaseCapture(); public static extern void ReleaseCapture();
@@ -70,5 +76,14 @@ namespace mpvnet
public int Width => Right - Left; public int Width => Right - Left;
public int Height => Bottom - Top; public int Height => Bottom - Top;
} }
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
} }
} }

View File

@@ -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("A modern media player")] [assembly: AssemblyDescription("media player")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Frank Skare (stax76)")] [assembly: AssemblyCompany("Frank Skare (stax76)")]
[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("4.5.0.0")] [assembly: AssemblyVersion("4.6.0.0")]
[assembly: AssemblyFileVersion("4.5.0.0")] [assembly: AssemblyFileVersion("4.6.0.0")]

View File

@@ -12,3 +12,4 @@ keep-open-pause = no
osd-playing-msg = '${filename}' osd-playing-msg = '${filename}'
screenshot-directory = '~~desktop/' screenshot-directory = '~~desktop/'
input-default-bindings = no input-default-bindings = no
script-opts=osc-scalewindowed=1.5

View File

@@ -59,7 +59,7 @@ namespace mpvnet
if (setting.Name == pair.Key) if (setting.Name == pair.Key)
{ {
setting.Value = pair.Value.Trim('\'', '"'); setting.Value = pair.Value.Trim('\'', '"');
setting.StartValue = pair.Value; setting.StartValue = pair.Value.Trim('\'', '"');
continue; continue;
} }
} }

View File

@@ -224,12 +224,28 @@ namespace mpvnet
void SetFormPosAndSize() void SetFormPosAndSize()
{ {
if (IsFullscreen || mp.VideoSize.Width == 0) return; if (IsFullscreen)
return;
Size size = mp.VideoSize;
Screen screen = Screen.FromControl(this); Screen screen = Screen.FromControl(this);
int height = mp.VideoSize.Height; int fixedHeight = Convert.ToInt32(screen.Bounds.Height * mp.Autofit);
if (mp.RememberHeight) height = ClientSize.Height;
if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * mp.Autofit); if (size.Height == 0 || size.Width == 0 || size.Width / (float)size.Height < 1.2)
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height); {
size.Height = fixedHeight;
size.Width = (int)(fixedHeight * 1.8);
}
int height = size.Height;
if (mp.RememberHeight)
height = ClientSize.Height;
if (height > screen.Bounds.Height * 0.9)
height = fixedHeight;
int width = Convert.ToInt32(height * size.Width / (double)size.Height);
Point middlePos = new Point(Left + Width / 2, Top + Height / 2); Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height)); var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
NativeHelp.AddWindowBorders(Handle, ref rect); NativeHelp.AddWindowBorders(Handle, ref rect);
@@ -329,6 +345,8 @@ namespace mpvnet
case 0x0104: // WM_SYSKEYDOWN case 0x0104: // WM_SYSKEYDOWN
case 0x0105: // WM_SYSKEYUP case 0x0105: // WM_SYSKEYUP
case 0x020A: // WM_MOUSEWHEEL case 0x020A: // WM_MOUSEWHEEL
case 0x0207: // WM_MBUTTONDOWN
case 0x0208: // WM_MBUTTONUP
if (mp.WindowHandle != IntPtr.Zero) if (mp.WindowHandle != IntPtr.Zero)
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam); Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
break; break;
@@ -363,22 +381,17 @@ namespace mpvnet
int[] d_corners = { d_w, d_h, -d_w, -d_h }; int[] d_corners = { d_w, d_h, -d_w, -d_h };
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom }; int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32()); int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
if (corner >= 0) corners[corner] -= d_corners[corner];
if (corner >= 0)
corners[corner] -= d_corners[corner];
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false); Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
m.Result = new IntPtr(1); m.Result = new IntPtr(1);
return; return;
} case 0x004A: // WM_COPYDATA
var copyData = (Native.COPYDATASTRUCT)m.GetLParam(typeof(Native.COPYDATASTRUCT));
string[] files = copyData.lpData.Split('\n');
string mode = files[0];
files = files.Skip(1).ToArray();
if (m.Msg == SingleProcess.Message) switch (mode)
{
object filesObject = RegHelp.GetObject(App.RegPath, "ShellFiles");
if (filesObject is string[] files)
{
switch (RegHelp.GetString(App.RegPath, "ProcessInstanceMode"))
{ {
case "single": case "single":
mp.Load(files, true, Control.ModifierKeys.HasFlag(Keys.Control)); mp.Load(files, true, Control.ModifierKeys.HasFlag(Keys.Control));
@@ -388,11 +401,9 @@ namespace mpvnet
mp.commandv("loadfile", file, "append"); mp.commandv("loadfile", file, "append");
break; break;
} }
}
RegHelp.RemoveValue(App.RegPath, "ShellFiles"); Activate();
Activate(); return;
return;
} }
base.WndProc(ref m); base.WndProc(ref m);
@@ -479,13 +490,13 @@ namespace mpvnet
BuildMenu(); BuildMenu();
ContextMenuStrip = ContextMenu; ContextMenuStrip = ContextMenu;
IgnoreDpiChanged = false; IgnoreDpiChanged = false;
CheckUrlInClipboard(); CheckClipboardForURL();
} }
protected override void OnActivated(EventArgs e) protected override void OnActivated(EventArgs e)
{ {
base.OnActivated(e); base.OnActivated(e);
CheckUrlInClipboard(); CheckClipboardForURL();
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
Native.SendMessage(Handle, m.Msg, m.WParam, m.LParam); Native.SendMessage(Handle, m.Msg, m.WParam, m.LParam);
} }
@@ -528,7 +539,7 @@ namespace mpvnet
CursorHelp.Show(); CursorHelp.Show();
} }
void CheckUrlInClipboard() void CheckClipboardForURL()
{ {
string clipboard = Clipboard.GetText(); string clipboard = Clipboard.GetText();

View File

@@ -144,7 +144,7 @@ namespace mpvnet
MPV_END_FILE_REASON_REDIRECT = 5 MPV_END_FILE_REASON_REDIRECT = 5
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct mpv_event_log_message public struct mpv_event_log_message
{ {
public string prefix; public string prefix;

View File

@@ -274,27 +274,8 @@ namespace mpvnet
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE: case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message)); var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args); string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
if (args.Length > 1 && args[0] == "mpv.net") if (args.Length > 1 && args[0] == "mpv.net")
{ Command.Execute(args[1], args.Skip(2).ToArray());
bool found = false;
foreach (Command i in Command.Commands)
{
if (args[1] == i.Name)
{
found = true;
i.Action.Invoke(args.Skip(2).ToArray());
}
}
if (!found)
{
List<string> names = mpvnet.Command.Commands.Select((item) => item.Name).ToList();
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 [default input bindings and menu definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt).");
}
}
else if (args.Length > 0) else if (args.Length > 0)
ClientMessage?.Invoke(args); ClientMessage?.Invoke(args);
break; break;
@@ -558,11 +539,18 @@ namespace mpvnet
} }
} }
static DateTime LastLoad;
public static void Load(string[] files, bool loadFolder, bool append) public static void Load(string[] files, bool loadFolder, bool append)
{ {
if (files is null || files.Length == 0) return; if (files is null || files.Length == 0) return;
HideLogo(); HideLogo();
if ((DateTime.Now - LastLoad).TotalMilliseconds < 500)
append = true;
LastLoad = DateTime.Now;
for (int i = 0; i < files.Length; i++) for (int i = 0; i < files.Length; i++)
if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower())) if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower()))
commandv("sub-add", files[i]); commandv("sub-add", files[i]);
@@ -579,7 +567,7 @@ namespace mpvnet
public static void LoadFolder() public static void LoadFolder()
{ {
Thread.Sleep(50); // user reported race condition Thread.Sleep(200); // user reported race condition
string path = get_property_string("path"); string path = get_property_string("path");
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return; if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList(); List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
@@ -660,18 +648,20 @@ namespace mpvnet
if (MainForm.Instance is null) return; if (MainForm.Instance is null) return;
Rectangle cr = MainForm.Instance.ClientRectangle; Rectangle cr = MainForm.Instance.ClientRectangle;
if (cr.Width == 0 || cr.Height == 0) return; if (cr.Width == 0 || cr.Height == 0) return;
int len = cr.Height / 5;
using (Bitmap b = new Bitmap(cr.Width, cr.Height)) using (Bitmap b = new Bitmap(len, len))
{ {
using (Graphics g = Graphics.FromImage(b)) using (Graphics g = Graphics.FromImage(b))
{ {
g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.Clear(Color.Black); g.Clear(Color.Black);
int iconWidth = cr.Height / 7; Rectangle rect = new Rectangle(0, 0, len, len);
Rectangle r = new Rectangle(cr.Width / 2 - iconWidth / 2, cr.Height / 2 - iconWidth / 2, iconWidth, iconWidth); g.DrawImage(Properties.Resources.mpvnet, rect);
g.DrawImage(Properties.Resources.mpvnet, r); BitmapData bd = b.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
BitmapData bd = b.LockBits(cr, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb); int x = Convert.ToInt32((cr.Width - len) / 2.0);
commandv("overlay-add", "0", "0", "0", "&" + bd.Scan0.ToInt64().ToString(), "0", "bgra", bd.Width.ToString(), bd.Height.ToString(), bd.Stride.ToString()); int y = Convert.ToInt32(((cr.Height - len) / 2.0) * 0.9);
commandv("overlay-add", "0", $"{x}", $"{y}", "&" + bd.Scan0.ToInt64().ToString(), "0", "bgra", bd.Width.ToString(), bd.Height.ToString(), bd.Stride.ToString());
b.UnlockBits(bd); b.UnlockBits(bd);
IsLogoVisible = true; IsLogoVisible = true;
} }