Click here to Skip to main content
13,352,879 members (51,382 online)
Click here to Skip to main content

Stats

557.8K views
25.9K downloads
255 bookmarked
Posted 14 Sep 2010

PVS.AVPlayer - MCI Audio and Video Library

, 7 Dec 2017
Windows Media Control Interface (MCI) library with many added features
PVS.AVPlayer
PVS.AVPlayer .NET 2.0
PVS.AVPlayer .NET 3.0
PVS.AVPlayer .NET 3.5
PVS.AVPlayer .NET 4.0
PVS.AVPlayer .NET 4.5
PVS.AVPlayer .NET 4.5.1
PVS.AVPlayer .NET 4.5.2
PVS.AVPlayer .NET 4.6
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.6.1
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.6.2
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.7.1
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.7
PVS.AVPlayer.dll
PVS.AVPlayer All Source Code
AVPlayerExample
AVPlayerExample
AVPlayerExample.csproj.user
bin
Debug
Release
Dialogs
Display Overlays
obj
Debug
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
WingDings3a.ttf
Voice Recorder
FolderView
FolderView
bin
Debug
Release
FolderView.csproj.user
obj
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
PVS.AVPlayer
AVPlayerExample.csproj.user
PVS.AVPlayer.dll
Custom Items
Native Methods
Crystal Italic1.ttf
Dial Green 2.png
Dial Green 4.png
Dial Green.png
Dial Red 2.png
Dial Red.png
media7.ico
media7a.ico
Media8.ico
Media8a.ico
VU Meter.png
WingDings3a.ttf
Sound Recorder
Various
About Dialog
PVS.AVPlayer.dll
Custom Items
FolderView.csproj.user
Crystal Italic1.ttf
media7a.ico
media7b.ico
Media8a.ico
Media8b.ico
Subtitles Overlay
Various
How To (C#)
PVSAVPlayerHowTo
bin
PVS.AVPlayer.dll
Release
Properties
How To (VB.NET)
PVSAVPlayerHowToVB
bin
PVS.AVPlayer.dll
Release
Form1.Designer.v_b
Form1.v_b
My Project
app.manifest
Application.Designer.v_b
Application.myapp
AssemblyInfo.v_b
Resources.Designer.v_b
Settings.Designer.v_b
Overlay.Designer.v_b
Overlay.v_b
PVSAVPlayerHowTo.vbproj.user
PVS.AVPlayer Examples
AVPlayerExample.ex_
FolderView.ex_
AVPlayerExample.ex_
FolderView.ex_
PVS.AVPlayer.dll
#region Usings

using PVS.AVPlayer;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Xml.Serialization;

#endregion

namespace FolderView
{
    public partial class MainWindow : Form
    {
        /*

            PVS.AVPlayer 0.77 Example Application - FolderView
            A simple movie folder viewer.

            This example application shows the use of some of the methods and properties of
            the PVS.AVPlayer library version 0.77.
    
            A large part of the application's functionality is created by using Microsoft Visual Studio Designer.
    
            Many thanks to Microsoft (Windows, .NET Framework, Visual Studio Express, etc.), all the people
            writing about programming on the internet (a great source for ideas and solving problems),
            the websites publishing those or other writings about programming, the people responding
            to the PVS.AVPlayer article with comments and suggestions and, of course, The Code Project:
            thank you Deeksha, Smitha and Sean Ewington for the beautiful article and all!

            Font 'Crystal Italic' by Allen R. Walden (FontInfo.txt in Resources folder). Thank you Allen!

            Application icon by Kyo-Tux (Asher). Thanks!
            www.iconarchive.com/show/soft-icons-by-kyo-tux/Media-icon.html
            Colors and image changed by PVS.

            Special thanks to Sean Ewington of CodeProject who also took care of publishing the many code updates
            and changes in the PVS.AVPlayer articles in a friendly, fast, and highly competent manner.
            Thank you very much, Sean!

            Peter Vegter
            December 2017, The Netherlands
    
            Microsoft Windows 7 (64-bit)
            Microsoft Visual Studio 2017 Community
            Dell Studio XPS 8000 (Intel Core i7 CPU 870, NVIDIA GeForce GT 440)
            Samsung SyncMaster T220 22-inch widescreen monitor
            Dell E173FP 17-inch monitor

        */


        // ******************************** Fields

        #region Fields

        // To avoid too much CPU-usage and/or memory usage
        private const int       PREFERENCES_VERSION             = 3;
        private const int       MAX_VIEW_PLAYERS                = 40;   // The maximum number of players in a folderview
        private const int       MAX_PLAYING_BACKGROUND_PLAYERS  = 12;   // If more than this: pause all folderview players when opening detailview
        private const int       START_POSITION_PERCENT          = 10;

        // Movie file extensions to look for (this list starts with .lnk (shortcut file))
        private const string    MOVIE_EXTENSIONS = ".lnk.asf.avi.bik.divx.dvx.f4v.flv.h264.hdmov.mkv.mod.mov.mp2.mp4.mpeg.mpeg4.mpg.mpv.mts.ogg.ogm.ogv.qt.rm.rms.rmvb.swf.ts.vfw.vob.webm.wmv.xvid";

        // Players and Displays (ItemViews)
        private int             _activeCount;
        private int             _playerCount;
        private Player[]        _myPlayers;
        private ItemView[]      _myItemViews;
        private Random          _random;

        // ItemViews Label Colors
        private readonly Color  NORMAL_COLOR        = Color.FromArgb(189, 159, 87);
        private readonly Color  ERROR_COLOR         = Color.Firebrick;
        private readonly Color  AUDIO_ENABLED_COLOR = Color.ForestGreen;

        // FolderView
        private bool            _busy;
        private bool            _hasQueue;
        private string          _queuePath;
        private bool            _exit;
        private List<string>    _fileList;

        // Treeview (folderBrowser)
        private bool            _dontExpand;
        private bool            _scrollBarHidden;

        // InfoLabels (trackbar labels)
        internal InfoLabel      ItemViewLabel;
        internal InfoLabel      PlayerWindowLabel;

        // Contextmenu Handler
        private int             _playerId;

        // Preferences
        [Serializable]
        public struct Preferences
        {
            public Rectangle WindowBounds;
            public bool WindowMaximized;
            public string InitialDirectory;
            public DisplayMode ItemDisplayMode;
            public int SplitterDistance;
        }
        private Preferences     _prefs;
        private const string    PREFS_FILENAME = "FolderView.inf";
        private readonly string PREFS_PATH = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\FolderView\";

        // About / Website Dialogs
        internal bool           UrlClicked;
        internal int            _goToArticle = 1;

        // Dispose
        private bool            _disposed;

        #endregion

        // ******************************** Main

        #region Main

        // Initialize
        public MainWindow()
        {
            InitializeComponent();
            Icon = Properties.Resources.Media8b;

            _random = new Random();

            // used with finding subtitle files (on Form2)
            Globals.Subtitles = new FileSearch();

            // Set custom menus
            ToolStripManager.Renderer = new CustomMenuRenderer();

            // Set custom font
            InstallCustomFonts();
            countLabel1.Font = Globals.CrystalFont26;
            countLabel1.UseCompatibleTextRendering = true;
            countLabel2.Font = Globals.CrystalFont26;
            countLabel2.UseCompatibleTextRendering = true;

            // FlowLayoutPanel scroll and click eventhandlers - and background image layout
            flowLayoutPanel1.Scroll += FlowLayoutPanel1_Scroll;
            flowLayoutPanel1.MouseWheel += FlowLayoutPanel1_MouseWheel;

            // Adjust submenus margins
            ((ToolStripDropDownMenu)allMenuItem.DropDown).ShowImageMargin = false;
            ((ToolStripDropDownMenu)displayModeAllMenuItem.DropDown).ShowImageMargin = false;

            // Create slider labels
            CreateInfoLabels();

            // Load settings
            GetSettings();

            // Create a filelist (to store moviefilenames in a directory)
            _fileList = new List<string>(MAX_VIEW_PLAYERS);

            // Add text maximum number of files to tooltips
            mainWindowToolTip.SetToolTip(countLabel1, mainWindowToolTip.GetToolTip(countLabel1) + MAX_VIEW_PLAYERS.ToString() + ").");
            mainWindowToolTip.SetToolTip(countLabel2, mainWindowToolTip.GetToolTip(countLabel2) + MAX_VIEW_PLAYERS.ToString() + ").");

            // Allow keys
            KeyPreview = true;

            // finishing setup in Form1_Shown... (for 'smoother' form display)
            Opacity = 0;
        }

        private void CreateInfoLabels()
        {
            ItemViewLabel                       = new InfoLabel();
            ItemViewLabel.RoundedCorners        = true;
            ItemViewLabel.ForeColor             = NORMAL_COLOR;
            ItemViewLabel.Text                  = "00:00:00"; // 'pre-size' small label for brush size
            ItemViewLabel.BackBrush             = new LinearGradientBrush(
                new Rectangle(new Point(0, 0), ItemViewLabel.Size),
                Color.FromArgb(80, 80, 80), Color.Black, LinearGradientMode.Vertical);
            ItemViewLabel.AlignOffset           = new Point(0, 2);

            PlayerWindowLabel                   = new InfoLabel();
            PlayerWindowLabel.Font              = Globals.CrystalFont16;
            PlayerWindowLabel.UseCompatibleTextRendering = true;
            PlayerWindowLabel.TextMargin        = new Padding(4, 2, 3, 0);
            PlayerWindowLabel.RoundedCorners    = true;
            PlayerWindowLabel.ForeColor         = NORMAL_COLOR;
            PlayerWindowLabel.BackBrush         = new LinearGradientBrush(
                new Rectangle(new Point(0, 0), PlayerWindowLabel.Size),
                Color.FromArgb(64, 64, 64), Color.Black, LinearGradientMode.Vertical);
            PlayerWindowLabel.AlignOffset       = new Point(0, -3);

        }

        private void MainWindow_Shown(object sender, EventArgs e)
        {
            // Set folderbrowser
            FolderBrowser_Init();
            FolderBrowser_SetPath(_prefs.InitialDirectory);
            FolderBrowser_HideScrollBar(true);

            Application.DoEvents();
            Opacity = 1; // make form visible

            // Set initial FolderView
            CreateFolderView(_prefs.InitialDirectory);
        }

        private void MainWindow_Activated(object sender, EventArgs e)
        {
            flowLayoutPanel1.Focus();
        }

        private void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F1)
            {
                e.Handled = true;
                ShowAboutDialog();
            }
            else if (e.KeyCode == Keys.Escape || (e.KeyCode == Keys.Q && e.Control))
            {
                e.Handled = true;
                Close();
            }
        }

        private void ShowAboutDialog()
        {
            UrlClicked = false;

            AboutDialog aboutMessage = new AboutDialog(this);
            aboutMessage.ShowDialog(this);
            aboutMessage.Dispose();

            if (UrlClicked) AskOpenWebSite();
        }

        // Asks for opening Code Project website
        private void AskOpenWebSite()
        {
            string theWebPage = @"http://www.codeproject.com";

            WebSiteDialog webSiteDialog = new WebSiteDialog(this) { Selection = _goToArticle };
            if (webSiteDialog.ShowDialog(this) == DialogResult.OK)
            {
                _goToArticle = webSiteDialog.Selection;
                webSiteDialog.Dispose();

                if (_goToArticle == 1) theWebPage += @"/Articles/109714/PVS-AVPlayer-MCI-Audio-and-Video-Library";
                else if (_goToArticle == 2) theWebPage += @"/Articles/1116698/PVS-AVPlayer-MCI-Sound-Recorder";
                try
                {
                    System.Diagnostics.Process.Start(theWebPage);
                }
                catch
                {
                    MessageBox.Show(
                    caption: "Folder View",
                    icon: MessageBoxIcon.Exclamation,
                    text: "Could not open the requested webpage. Please check your Browser.",
                    buttons: MessageBoxButtons.OK,
                    owner: this);
                }
            }
            else
            {
                webSiteDialog.Dispose();
            }
        }

        // Repairing scroll redraw issues with paused players
        private void FlowLayoutPanel1_Scroll(object sender, ScrollEventArgs e)
        {
            flowLayoutPanel1.Invalidate(true);
        }
        // ... and with
        void FlowLayoutPanel1_MouseWheel(object sender, MouseEventArgs e)
        {
            flowLayoutPanel1.Invalidate(true);
        }

        // Don't close the Form (application) yet when a Player starts playing a mediafile (in method CreateFolderView)
        // (because a Player allows user interface actions while 'processing' a mediafile and
        // all Displays and Players will be 'disposed' when closing the Form)
        // 'sends a message' to CreateFolderView (if busy)
        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_busy)
            {
                _exit = true; // do Application.Exit() when finished
                _hasQueue = true; // don't create new ItemViews, Players or start playing a mediafile
                e.Cancel = true; // don't exit app (yet)
            }
            else
            {
                Hide();
                // Save settings
                SaveSettings();
                // Dispose all open Forms but this one
                for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
                {
                    if (Application.OpenForms[i] != this) Application.OpenForms[i].Dispose();
                }
            }
        }

        // Moved from 'Main Window.Designer.cs' to here and added a few things
        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;

                if (disposing)
                {
                    RemoveFolderView();
                    _fileList.Clear();

                    if (ItemViewLabel != null)  ItemViewLabel.Dispose();
                    if (PlayerWindowLabel != null) PlayerWindowLabel.Dispose();

                    Globals.CrystalFont16.Dispose();
                    Globals.CrystalFont26.Dispose();
                    Globals.FontCollection1.Dispose();

                    if (components != null) components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #endregion

        // ******************************** Settings - Config File

        #region Settings - Config File

        private void GetSettings()
        {
            bool loadOk = false;

            _prefs.ItemDisplayMode = DisplayMode.ZoomAndCenter;
            _prefs.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            _prefs.SplitterDistance = 0;

            // Load and Apply Settings
            if (File.Exists(PREFS_PATH + PREFS_FILENAME))
            {
                try
                {
                    using (StreamReader reader = new StreamReader(PREFS_PATH + PREFS_FILENAME))
                    {
                        XmlSerializer xml = new XmlSerializer(typeof(Preferences));
                        _prefs = (Preferences)xml.Deserialize(reader);
                    }
                    loadOk = true;
                }
                catch { /* ignore */ }
            }

            if (loadOk)
            {
                // check window position (multiple screens)
                if (SystemInformation.VirtualScreen.Contains(_prefs.WindowBounds))
                {
                    StartPosition = FormStartPosition.Manual;
                    Bounds = _prefs.WindowBounds;
                }

                if (_prefs.WindowMaximized)
                {
                    if (StartPosition != FormStartPosition.Manual)
                    {
                        Top = (Screen.PrimaryScreen.WorkingArea.Height - Height) / 2;
                        Left = (Screen.PrimaryScreen.WorkingArea.Width - Width) / 2;
                    }
                    WindowState = FormWindowState.Maximized;
                }
                if (_prefs.SplitterDistance > 0) splitContainer1.SplitterDistance = _prefs.SplitterDistance;
            }
        }

        private void SaveSettings()
        {
            // Collect Settings
            _prefs.WindowBounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;
            _prefs.WindowMaximized = WindowState == FormWindowState.Maximized;
            _prefs.SplitterDistance = splitContainer1.SplitterDistance;

            // Save Settings
            try
            {
                Directory.CreateDirectory(PREFS_PATH); // create folder if not already existing
                using (StreamWriter writer = new StreamWriter(PREFS_PATH + PREFS_FILENAME))
                {
                    XmlSerializer xml = new XmlSerializer(typeof(Preferences));
                    xml.Serialize(writer, _prefs);
                }
            }
            catch { /* ignore */ }
        }

        #endregion

        // ******************************** Create / Remove FolderView / ResolveShortcut

        #region Create / Remove FolderView / ResolveShortcut

        // Create and display a new Folder view
        private void CreateFolderView(string path)
        {
            if (_busy)
            {
                _hasQueue = true;
                _queuePath = path;
                return;
            }
            _busy = true;

            // don't (causes more flicker)
            // folderBrowser.BeginUpdate();

            do
            {
                RemoveFolderView();
                _fileList.Clear();

                if (_hasQueue)
                {
                    _hasQueue = false;
                    folderLabel.Text = _queuePath;
                }
                else folderLabel.Text = path;

                try
                {
                    // Get all mediafiles in folder
                    foreach (string file in Directory.GetFiles(folderLabel.Text))
                    {
                        int index = MOVIE_EXTENSIONS.IndexOf(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase);
                        if (index == 0) // .lnk - shortcut file
                        {
                            string linkFile = ResolveShortcut(file);
                            if (MOVIE_EXTENSIONS.IndexOf(Path.GetExtension(linkFile), StringComparison.OrdinalIgnoreCase) > 0)
                            {
                                _fileList.Add(linkFile);
                            }
                        }
                        else if (index > 0)
                        {
                            _fileList.Add(file);
                        }
                    }
                }
                catch //(Exception e)
                {
                    //MessageBox.Show(e.Message);
                    continue;
                }

                if (_fileList.Count > 0)
                {
                    // Set (max) number of Players
                    _playerCount = _fileList.Count > MAX_VIEW_PLAYERS ? MAX_VIEW_PLAYERS : _fileList.Count;

                    // Create Displays and Players
                    _myItemViews = new ItemView[_playerCount];
                    _myPlayers = new Player[_playerCount];

                    for (int i = 0; i < _playerCount && !_hasQueue; i++)
                    {
                        _myItemViews[i] = new ItemView()
                        {
                            Name = i.ToString(),
                            ContextMenuStrip = itemViewMenu,
                        };

                        _myItemViews[i].FileName.Click += FileName_Click; // label
                        _myItemViews[i].FileName.ForeColor = NORMAL_COLOR;
                        _myItemViews[i].FileName.Text = Path.GetFileName(_fileList[i]);

                        _myPlayers[i] = new Player();
                        _myPlayers[i].Display.Window = _myItemViews[i].Display;
                        _myPlayers[i].Display.Mode = _prefs.ItemDisplayMode;
                        _myPlayers[i].Sliders.Position = _myItemViews[i].customSlider1;
                        _myPlayers[i].Audio.Enabled = false;
                        _myPlayers[i].Repeat = true;

                        _myItemViews[i].ItemParent = this;
                        _myItemViews[i].ItemPlayer = _myPlayers[i];

                        if (_playerCount > MAX_PLAYING_BACKGROUND_PLAYERS) _myPlayers[i].Paused = true;
                    }

                    // Add items to TableLayoutPanel
                    if (!_hasQueue)
                    {
                        flowLayoutPanel1.Controls.AddRange(_myItemViews);
                        countLabel1.Text = _playerCount.ToString("000");
                        // add mouse event here, because the items are now on a form
                        // without a form an event subsription is ignored
                        for (int i = 0; i < _myPlayers.Length; i++)
                        {
                            _myPlayers[i].Events.MediaMouseClick += MediaDisplay_Click;
                        }
                    }

                    // Start Players
                    for (int i = 0; i < _playerCount && !_hasQueue; i++)
                    {
                        _myPlayers[i].Play(_fileList[i]);
                        if (_myPlayers[i].LastError)
                        {
                            _myPlayers[i].Dispose();
                            _myPlayers[i] = null;
                            _myItemViews[i].customSlider1.Enabled = false;
                            _myItemViews[i].FileName.ForeColor = ERROR_COLOR;
                        }
                        else
                        {
                            countLabel2.Text = (++_activeCount).ToString("000");
                            // set playback position to START_POSITION_PERCENT of total lenght
                            //_myPlayers[i].Position.Progress = 0.1;
                            _myPlayers[i].Position.Progress = _random.NextDouble() / 2.5 + 0.1;
                        }
                    }

                    // See Form1_FormClosing eventhandler
                    if (_exit)
                    {
                        _hasQueue = false;
                        _busy = false;
                        Application.Exit();
                    }
                }
            } while (_hasQueue);

            // contextmenustrip2
            bool menuEnabled = _playerCount > 0;

            // don't (causes more flicker)
            // folderBrowser.EndUpdate();

            _busy = false;
        }

        private void RemoveFolderViewOld()
        {
            // reset counters
            _activeCount = 0;
            countLabel1.Text = "000";
            countLabel2.Text = "000";

            if (_playerCount > 0)
            {
                // Dispose Players and remove and dispose ItemViews
                for (int i = 0; i < _playerCount; i++)
                {
                    if (_myPlayers[i] != null)
                    {
                        _myPlayers[i].Dispose();
                        _myPlayers[i] = null;
                    }
                }

                flowLayoutPanel1.Controls.Clear();

                for (int i = 0; i < _playerCount; i++)
                {
                    if (_myItemViews[i] != null)
                    {
                        _myItemViews[i].ContextMenuStrip = null;
                        _myItemViews[i].Dispose();
                        _myItemViews[i] = null;
                    }
                }

                //flowLayoutPanel1.Controls.Clear();
                _playerCount = 0;
            }
        }

        private void RemoveFolderView()
        {
            // reset counters
            _activeCount = 0;
            countLabel1.Text = "000";
            countLabel2.Text = "000";

            if (_playerCount > 0)
            {
                // Dispose Players and remove and dispose ItemViews
                for (int i = _playerCount - 1; i >= 0; i--)
                {
                    if (_myPlayers[i] != null)
                    {
                        _myPlayers[i].Dispose();
                        _myPlayers[i] = null;
                    }
                }

                for (int i = _playerCount - 1; i >= 0; i--)
                {
                    if (_myItemViews[i] != null)
                    {
                        _myItemViews[i].ContextMenuStrip = null;
                        _myItemViews[i].Dispose();
                        _myItemViews[i] = null;
                    }
                }

                flowLayoutPanel1.Controls.Clear();
                _playerCount = 0;
            }
        }

        // taken from: https://blez.wordpress.com/2013/02/18/get-file-shortcuts-target-with-c/
        private string ResolveShortcut(string fileName)
        {
            //if (!String.Equals(Path.GetExtension(fileName), ".lnk", StringComparison.OrdinalIgnoreCase)) return string.Empty;
            try
            {
                FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read);
                using (BinaryReader fileReader = new BinaryReader(fileStream))
                {
                    fileStream.Seek(0x14, SeekOrigin.Begin);     // Seek to flags
                    uint flags = fileReader.ReadUInt32();        // Read flags
                    if ((flags & 1) == 1)
                    {
                        // Bit 1 set means we have to skip the shell item ID list
                        fileStream.Seek(0x4c, SeekOrigin.Begin); // Seek to the end of the header
                        uint offset = fileReader.ReadUInt16();   // Read the length of the Shell item ID list
                        fileStream.Seek(offset, SeekOrigin.Current); // Seek past it (to the file locator info)
                    }

                    long fileInfoStartsAt = fileStream.Position; // Store the offset where the file info
                    // structure begins
                    uint totalStructLength = fileReader.ReadUInt32(); // read the length of the whole struct
                    fileStream.Seek(0xc, SeekOrigin.Current); // seek to offset to base pathname
                    uint fileOffset = fileReader.ReadUInt32(); // read offset to base pathname
                    // the offset is from the beginning of the file info struct (fileInfoStartsAt)
                    fileStream.Seek((fileInfoStartsAt + fileOffset), SeekOrigin.Begin); // Seek to beginning of
                    // base pathname (target)
                    long pathLength = (totalStructLength + fileInfoStartsAt) - fileStream.Position - 2; // read
                    // the base pathname. I don't need the 2 terminating nulls.
                    char[] linkTarget = fileReader.ReadChars((int)pathLength); // should be unicode safe
                    string link = new string(linkTarget);

                    int begin = link.IndexOf("\0\0", StringComparison.Ordinal);
                    if (begin > -1)
                    {
                        int end = link.IndexOf("\\\\", begin + 2, StringComparison.Ordinal) + 2;
                        end = link.IndexOf('\0', end) + 1;

                        string firstPart = link.Substring(0, begin);
                        string secondPart = link.Substring(end);

                        return firstPart + secondPart;
                    }
                    return link;
                }
            }
            catch
            {
                return string.Empty;
            }
        }

        #endregion

        // ******************************** ItemView Click Eventhandlers

        #region ItemView Click Eventhandlers

        // Handle ItemView Player Display Click
        void MediaDisplay_Click(object sender, MediaMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _playerId = Convert.ToInt32(((Panel)sender).Parent.Name);
                OpenMenuItem_Click(sender, EventArgs.Empty);
            }
        }

        // Handle ItemView Label Click
        void FileName_Click(object sender, EventArgs e)
        {
            //if (MouseButtons == MouseButtons.Left)
            {
                _playerId = Convert.ToInt32(((Label)sender).Parent.Name);
                OpenMenuItem_Click(sender, e);
            }
        }

        #endregion

        // ******************************** Contextmenu Items Handlers

        #region Contextmenu Items Handlers

        // ******************************** ContextMenu Opening and Closing

        // Before contextmenu is shown or closed:
        private void ItemViewMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            _playerId = Convert.ToInt32(((ContextMenuStrip)sender).SourceControl.Name);
            bool enable = _myPlayers[_playerId] != null;

            pauseMenuItem.Enabled = enable;
            muteMenuItem.Enabled = enable;
            displayModeMenuItem.Enabled = enable;

            if (enable)
            {
                pauseMenuItem.Text = _myPlayers[_playerId].Paused ? "Play" : "Pause";
                muteMenuItem.Text = _myPlayers[_playerId].Audio.Enabled ? "Mute" : "Mute Off";

                stretchMenuItem.Checked = _myPlayers[_playerId].Display.Mode == DisplayMode.Stretch;
                zoomAndCenterMenuItem.Checked = !stretchMenuItem.Checked;
            }
            else
            {
                pauseMenuItem.Text = "Play";
                muteMenuItem.Text = "Mute Off";
            }

            ((ItemView)itemViewMenu.SourceControl).FileName.BackColor = Color.FromArgb(64, 24, 24);
        }

        private void ItemViewMenu_Closing(object sender, ToolStripDropDownClosingEventArgs e)
        {
            ((ItemView)itemViewMenu.SourceControl).FileName.BackColor = BackColor; // Color.FromArgb(18, 18, 18);
        }


        // ******************************** All Items

        // Play (Resume) all Players
        private void PlayAllMenuItem_Click(object sender, EventArgs e)
        {
            PauseAllPlayers(false);
        }

        // Pause all Players
        private void PauseAllMenuItem_Click(object sender, EventArgs e)
        {
            PauseAllPlayers(true);
        }

        // Mute all Players
        private void MuteAllMenuItem_Click(object sender, EventArgs e)
        {
            AudioMuteAllPlayers();
        }

        // DisplayMode Stretch all Players
        private void StretchAllMenuItem_Click(object sender, EventArgs e)
        {
            _prefs.ItemDisplayMode = DisplayMode.Stretch;
            for (int i = 0; i < _myPlayers.Length; i++)
            {
                if (_myPlayers[i] != null) _myPlayers[i].Display.Mode = DisplayMode.Stretch;
            }
        }


        // DisplayMode ZoomAndCenter all Players
        private void ZoomAndCenterAllMenuItem_Click(object sender, EventArgs e)
        {
            _prefs.ItemDisplayMode = DisplayMode.ZoomAndCenter;
            for (int i = 0; i < _myPlayers.Length; i++)
            {
                if (_myPlayers[i] != null) _myPlayers[i].Display.Mode = DisplayMode.ZoomAndCenter;
            }
        }

        // ******************************** Selected Player

        // Play (Resume) / Pause selected Player
        private void PauseMenuItem_Click(object sender, EventArgs e)
        {
            _myPlayers[_playerId].Paused = !_myPlayers[_playerId].Paused;
        }

        // Mute On / Off selected Player
        private void MuteMenuItem_Click(object sender, EventArgs e)
        {
            if (_myPlayers[_playerId].Audio.Enabled)
            {
                _myPlayers[_playerId].Audio.Enabled = false;
                _myItemViews[_playerId].FileName.ForeColor = NORMAL_COLOR;
            }
            else
            {
                AudioMuteAllPlayers();
                _myPlayers[_playerId].Audio.Enabled = true;
                _myItemViews[_playerId].FileName.ForeColor = AUDIO_ENABLED_COLOR;
            }
        }

        // DisplayMode Stretch selected Player
        private void StretchMenuItem_Click(object sender, EventArgs e)
        {
            _myPlayers[_playerId].Display.Mode = DisplayMode.Stretch;
        }

        // DisplayMode ZoomAndCenter selected Player
        private void ZoomAndCenterMenuItem_Click(object sender, EventArgs e)
        {
            _myPlayers[_playerId].Display.Mode = DisplayMode.ZoomAndCenter;
        }

        // ******************************** Open, Open With..., Properties

        // Open mediafile in new window or in other application
        private void OpenMenuItem_Click(object sender, EventArgs e)
        {
            OpenItem(false);
        }

        // Open at in item shown position
        private void OpenAtMenuItem_Click(object sender, EventArgs e)
        {
            OpenItem(true);
        }

        private void OpenItem(bool fromStart)
        {
            if (_myPlayers.Length > MAX_PLAYING_BACKGROUND_PLAYERS) PauseAllPlayers(true);
            AudioMuteAllPlayers();

            if (_myPlayers[_playerId] != null)
            {
                PlayerWindow playerForm;

                if (fromStart || (Control.ModifierKeys == Keys.Shift || Control.ModifierKeys == Keys.Control)) playerForm = new PlayerWindow(this, _fileList[_playerId], TimeSpan.Zero);
                else playerForm = new PlayerWindow(this, _fileList[_playerId], _myPlayers[_playerId].Position.FromStart);

                if (playerForm._lastError)
                {
                    playerForm.Dispose();
                }
                else
                {
                    Point pos = MousePosition;
                    Rectangle screen = Screen.GetWorkingArea(pos);

                    // center the form on the mouse click position, but adjust if not fully visible on screen
                    if (pos.X > screen.Left + (playerForm.Width / 2))
                    {
                        pos.X -= (playerForm.Width / 2);
                        if (pos.X + playerForm.Width > screen.Left + screen.Width) pos.X = screen.Left + screen.Width - playerForm.Width - 8;
                    }
                    else pos.X = screen.Left + 8;
                    if (pos.Y > screen.Top + (playerForm.Height / 2))
                    {
                        pos.Y -= (playerForm.Height / 2);
                        if (pos.Y + playerForm.Height > screen.Top + screen.Height) pos.Y = screen.Top + screen.Height - playerForm.Height - 8;
                    }
                    else pos.Y = screen.Top + 8;

                    playerForm.StartPosition = FormStartPosition.Manual;
                    playerForm.Location = pos;
                    playerForm.Show(this);
                    return;
                }
            }

            try { System.Diagnostics.Process.Start(_fileList[_playerId]); }
            catch { }
        }

        // Select application to open mediafile
        private void OpenWithMenuItem_Click(object sender, EventArgs e)
        {
            if (_myPlayers.Length > MAX_PLAYING_BACKGROUND_PLAYERS) PauseAllPlayers(true);
            AudioMuteAllPlayers();

            try { System.Diagnostics.Process.Start("rundll32.exe", "shell32.dll,OpenAs_RunDLL " + _fileList[_playerId]); }
            catch { }
        }

        // Show mediafile Explorer properties dialog
        private void PropertiesMenuItem_Click(object sender, EventArgs e)
        {
            // 'dirty trick' to position the properties dialog - should have a second look at this (?)
            //Cursor.Position = PointToScreen(new Point(folderBrowser.Width + _myItemViews[_playerId].Left + (_myItemViews[_playerId].Width / 2), panel1.Height + _myItemViews[_playerId].Top + (_myItemViews[_playerId].Height / 3)));
            Cursor.Position = PointToScreen(new Point(folderBrowser.Width + _myItemViews[_playerId].Left + _myItemViews[_playerId].Width + 10, panel1.Height + _myItemViews[_playerId].Top + 3));

            try
            {
                SafeNativeMethods.SHELLEXECUTEINFO info = new SafeNativeMethods.SHELLEXECUTEINFO();
                info.cbSize = Marshal.SizeOf(info);
                info.lpVerb = "properties";
                info.lpParameters = "details";
                info.lpFile = _fileList[_playerId];
                info.nShow = SafeNativeMethods.SW_SHOW;
                info.fMask = SafeNativeMethods.SEE_MASK_INVOKEIDLIST;
                SafeNativeMethods.ShellExecuteEx(ref info);
            }
            catch { /* ignore */}
        }

        // ******************************** About / Quit

        // About application
        private void AboutMenuItem_Click(object sender, EventArgs e)
        {
            ShowAboutDialog();
        }

        // Quit application
        private void QuitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        // ******************************** Contextmenu Helper methods

        // Pause / Resume playback all Players
        private void PauseAllPlayers(bool pause)
        {
            for (int i = 0; i < _myPlayers.Length; i++)
            {
                if (_myPlayers[i] != null) _myPlayers[i].Paused = pause;
            }
        }

        private void AudioMuteAllPlayers()
        {
            for (int i = 0; i < _myPlayers.Length; i++)
            {
                if (_myPlayers[i] != null && _myPlayers[i].Audio.Enabled)
                {
                    _myPlayers[i].Audio.Enabled = false;
                    _myItemViews[i].FileName.ForeColor = NORMAL_COLOR;
                }
            }
        }

        #endregion

        // ******************************** Player Windows Contextmenu Handlers

        #region Player Windows Contextmenu Handlers

        // Pause all Player Windows
        internal void PauseAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).PauseMenuFromMain();
            }
        }

        // Resume all Player Windows
        internal void ResumeAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).ResumeMenuFromMain();
            }
        }

        // Mute all Player Windows
        internal void MuteAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).MuteMenuFromMain();
            }
        }

        // Mute Off all Player Windows
        internal void MuteOffAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).MuteOffMenuFromMain();
            }
        }

        // Zoom all Player Windows
        internal void ZoomAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).ZoomMenuFromMain();
            }
        }

        // Stretch all Player Windows
        internal void StretchAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).StretchMenuFromMain();
            }
        }

        // FullScreen Off all Player Windows
        internal void FullScreenOffAllWindows()
        {
            foreach (Form window in Application.OpenForms)
            {
                if (window != this) ((PlayerWindow)window).FullScreenOffFromMain();
            }
        }

        // Hide Subtitles all Player Windows
        internal void HideSubtitlesAllWindows()
        {
            Form topWindow = ActiveForm;
            foreach (Form window in Application.OpenForms)
            {
                if (window != this)
                {
                    ((PlayerWindow)window).SubtitlesOffFromMain();
                }
            }
            if (topWindow != ActiveForm) topWindow.Activate();
        }

        // Show Subtitles all Player Windows
        internal void ShowSubtitlesAllWindows()
        {
            Form topWindow = ActiveForm;
            foreach (Form window in Application.OpenForms)
            {
                if (window != this)
                {
                    ((PlayerWindow)window).SubtitlesOnFromMain();
                }
            }
            if (topWindow != ActiveForm) topWindow.Activate();
        }

        // Close all Player Windows
        internal void CloseAllWindows()
        {
            FormCollection forms = Application.OpenForms;
            for (int i = forms.Count - 1; i >= 0; i--)
            {
                if (forms[i] != this) forms[i].Close();
            }
        }

        #endregion

    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Peter Vegter
United States United States
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.180111.1 | Last Updated 7 Dec 2017
Article Copyright 2010 by Peter Vegter
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid