Click here to Skip to main content
13,902,931 members
Click here to Skip to main content

Stats

741.2K views
30.1K downloads
281 bookmarked
Posted 14 Sep 2010
Licenced CPOL

PVS.AVPlayer - MCI Audio and Video Library

, 7 Aug 2018
Windows Media Control Interface (MCI) library with many added features
PVS.AVPlayer
PVS.AVPlayer .NET 2.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 3.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 3.5
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.5
PVS.AVPlayer .NET 4.5.1
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.5.2
PVS.AVPlayer.XML
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6.1
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6.2
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.7
PVS.AVPlayer .NET 4.7.1
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.7.2
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer All Source Code
AVPlayerExample
AVPlayerExample
AVPlayerExample.csproj.user
bin
Debug
PVS.AVPlayer.XML
Release
Dialogs
Display Overlays
obj
Debug
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
WingDings3a.ttf
Voice Recorder
FolderView
FolderView
bin
Debug
PVS.AVPlayer.XML
Release
FolderView.csproj.user
obj
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
PVS.AVPlayer
AVPlayerExample.csproj.user
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Custom Items
Native Methods
Bob.png
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
PVS.AVPlayer.XML
Custom Items
FolderView.csproj.user
Debug
Bob.png
Crystal Italic1.ttf
media7a.ico
media7b.ico
Media8a.ico
Media8b.ico
Subtitles Overlay
Various
How To (C#)
PVSAVPlayerHowTo
bin
Debug
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Release
obj
Debug
Release
Properties
How To (VB.NET)
PVSAVPlayerHowToVB
bin
Debug
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Release
My Project
Application.myapp
obj
Debug
Release
PVSAVPlayerHowTo.vbproj.user
PVS.AVPlayer Examples
AVPlayerExample.ex_
FolderView.ex_
AVPlayerExample.exe
FolderView.exe
PVS.AVPlayer.dll
/****************************************************************

    PVS.AVPlayer - Version 0.46
    September 2015, The Netherlands
    © Copyright 2015 PVS The Netherlands

    ****************

    The PVS.AVPlayer library source code is divided into 3 files:
    1. Player.cs - Player source code
    2. Recorder.cs - (Microphone) Recorder source code
    3. PlayerRecorder.cs - (this file) code used by both Player.cs and Recorder.cs

    Required references:
    System
    System.Drawing
    System.Windows.Forms

    ****************

    This file: PlayerRecorder.cs

    Global Class
    MCI Class
    SafeNativeMethods Class
    
    Used by 'Player.cs' and 'Recorder.cs'

    ****************

    About Media Control Interface (MCI)
    - for information about MCI, please see https://msdn.microsoft.com/en-us/library/windows/desktop/dd757151%28v=vs.85%29.aspx
    - you can find very many articles about mci on the internet, search examples: 'c# mci', 'mcicommandstring'
      or the subject of your question.

    ****************

    Thanks!

    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 for the beautiful article and all!

    ****************************************************************/


#region Usings

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

#endregion

[assembly: CLSCompliant(true)]

namespace PVS.AVPlayer
{
    // ******************************** Global Class

    // The (internal static) Global class contains some constants and a 'RandomNumber' generator
    // used by both the Player and Recorder class.

    #region Global Class

    internal static class Global
    {
        // PVS.AVPlayer Library Version
        internal const float    VERSION                     = 0.46F;
        internal const string   VERSION_STRING              = "PVS.AVPlayer 0.46";

        // MCI ErrorCodes
        // For a complete list of mci errorcodes please see: https://msdn.microsoft.com/en-us/library/aa228215%28v=vs.60%29.aspx
        internal const int      MCIERR_NO_ERROR             = 0;
        internal const int      MCIERR_UNRECOGNIZED_KEYWORD = 259;
        internal const int      MCIERR_INVALID_DEVICE_NAME  = 263;
        internal const int      MCIERR_PARSER_INTERNAL      = 271;
        internal const int      MCIERR_DEVICE_NOT_READY     = 263;  // actually 276, but this returns the 'proper' message
        internal const int      MCIERR_INTERNAL             = 277;
        internal const int      MCIERR_OUTOFRANGE           = 282;
        internal const int      MCIERR_DUPLICATE_ALIAS      = 289;
        internal const int      MCIERR_NULL_PARAMETER_BLOCK = 297;
        internal const int      MCIERR_FILENAME_REQUIRED    = 304;
        internal const int      MCIERR_NO_WINDOW            = 346;
        internal const int      MCIERR_CREATEWINDOW         = 347;

        // MCI communication buffer sizes
        internal const int      BUFFER_SIZE                 = 512;
        internal const int      SMALL_BUFFER_SIZE           = 64;

        // Used with creating player and recorder ID's (deviceId / alias)
        internal static Random  RandomNumber                = new Random();
        internal const int      ALIAS_REPEAT                = 10; // max repeat to get new alias with error MCIERR_DUPLICATE_ALIAS
    }

    #endregion


    // ******************************** MCI Direct Access (without Player or Recorder Instance)

    // The (public static) MCI class gives direct access to the native Win32 functions
    // mciSendString and mciGetErrorString. These functions are all you need to
    // control any available MCI device (without using a Player or Recorder instance).

    #region MCI Direct Access (without Player or Recorder Instance)

    /// <summary>
    /// Represents a class that provides direct access to (native Win32) MCI functions.
    /// </summary>
    [CLSCompliant(true)]
    public static class Mci
    {
        /// <summary>
        /// Sends a command string to an MCI device. The device that the command is sent to is specified in the command string.
        /// </summary>
        /// <param name="command">String that specifies an MCI command string.</param>
        /// <param name="resultText">A buffer that receives return information. If there's no return information, this parameter can be null.</param>
        /// <param name="hwndCallback">Handle to a callback window if the "notify" flag was specified in the command string or null.</param>
        /// <returns>Returns an MCI error code (0 = no error).</returns>
        public static int SendString(string command, StringBuilder resultText, IntPtr hwndCallback)
        {
            try
            {
                return resultText == null ? SafeNativeMethods.mciSendString(command, null, 0, hwndCallback) : SafeNativeMethods.mciSendString(command, resultText, resultText.Capacity, hwndCallback);
            }
            catch { return Global.MCIERR_PARSER_INTERNAL; }
        }

        /// <summary>
        /// Retrieves a string that describes the specified MCI error code.
        /// </summary>
        /// <param name="errorCode">Error code returned by the MCI.SendString method.</param>
        /// <param name="errorText">A buffer that receives a string describing the specified error.</param>
        /// <returns>Returns an MCI error code (0 = no error).</returns>
        public static int GetErrorString(int errorCode, StringBuilder errorText)
        {
            try
            {
                return SafeNativeMethods.mciGetErrorString(errorCode, errorText, errorText.Capacity);
            }
            catch { return Global.MCIERR_PARSER_INTERNAL; }
        }

        ///// <summary>
        ///// Determines whether the specified System.Object is equal to the current System.Object.
        ///// </summary>
        //[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), System.Runtime.InteropServices.ComVisible(false)]
        //public static new bool Equals(object value)
        //{
        //    return Equals(value);
        //}

        ///// <summary>
        ///// Determines whether the specified Object instances are the same instance.
        ///// </summary>
        //[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), System.Runtime.InteropServices.ComVisible(false)]
        //public static new bool ReferenceEquals(object valueA, object valueB)
        //{
        //    return ReferenceEquals(valueA, valueB);
        //}

    }

    #endregion


    // ******************************** SafeNativeMethods - DLL Import

    // The (internal static) SafeNativeMethods class provides the PVS.AVPlayer library access
    // to native Win32 functions (DllImport, P/Invoke) and also
    // contains a few related (helper) functions (CenterSystemDialog and SleepStatus).

    #region SafeNativeMethods - DLL Import

    [System.Security.SuppressUnmanagedCodeSecurity] 
    internal static class SafeNativeMethods
    {
        // ******************************** MCI

        [DllImport("winmm.dll", CharSet = CharSet.Unicode)]
        internal static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);

        [DllImport("winmm.dll", CharSet = CharSet.Unicode)]
        internal static extern Int32 mciGetErrorString(Int32 errorCode, StringBuilder errorText, Int32 errorTextSize);

        // ******************************** Win32 Windows

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

        internal const uint SWP_NOSIZE = 0x1;
        internal const uint SWP_NOMOVE = 0X2;
        internal const uint SWP_NOZORDER = 0X4;
        internal const uint SWP_HIDEWINDOW = 0x80;
        internal const uint SWP_SHOWWINDOW = 0x40;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        internal static extern IntPtr GetForegroundWindow();

        [StructLayout(LayoutKind.Sequential)]
        internal struct Rect
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect);

        // ******************************** Center System Dialogs

        internal static bool CenterSystemDialog(string fileName, string arguments, Form baseForm) //Rectangle itemBounds)
        {
            bool result = true;

            try
            {
                IntPtr hWndCurrent = GetForegroundWindow();

                System.Diagnostics.Process showControlPanel = new System.Diagnostics.Process
                {
                    StartInfo = {FileName = fileName, Arguments = arguments}
                };
                showControlPanel.Start();

                if (baseForm != null)
                {
                    int i = 0;
                    IntPtr hWnd = GetForegroundWindow();
                    while (i < 100 && hWnd == hWndCurrent)
                    {
                        ++i;
                        System.Threading.Thread.Sleep(10);
                        hWnd = GetForegroundWindow();
                    }

                    if (hWnd != hWndCurrent)
                    {
                        Rectangle r1 = new Rectangle();
                        Rectangle r2 = Screen.GetBounds(baseForm);
                        Rect r3;
                        GetWindowRect(hWnd, out r3);

                        r1.Width = r3.Right - r3.Left + 1;
                        r1.Height = r3.Bottom - r3.Top + 1;

                        r1.X = baseForm.Bounds.Left + (baseForm.Bounds.Width - r1.Width) / 2;
                        if (r1.X < r2.X) r1.X = r2.X + 2;
                        else if (r1.X + r1.Width > r2.Width) r1.X = r2.Width - r1.Width - 2;

                        r1.Y = baseForm.Bounds.Top + (baseForm.Bounds.Height - r1.Height) / 2;
                        if (r1.Y < r2.Y) r1.Y = r2.Y + 2;
                        else if (r1.Y + r1.Height > r2.Height - 48) r1.Y = r2.Height - r1.Height - 48;

                        SetWindowPos(hWnd, IntPtr.Zero, r1.X, r1.Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
                    }
                }
            }
            catch { result = false; }
            return result;
        }

        // ******************************** Change System Sleep Mode

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern uint SetThreadExecutionState(uint esFlags);

        private const uint ES_NO_SLEEP = 0x80000003;
        private static int _sleepCount;
        private static uint _oldState;

        internal static bool SleepStatus
        {
            //get { return sleepCount > 0; }
            set
            {
                if (value)
                {
                    uint flags = SetThreadExecutionState(ES_NO_SLEEP);
                    if (++_sleepCount == 1) _oldState = flags;
                }
                else
                {
                    if (_sleepCount > 0)
                    {
                        if (--_sleepCount == 0) SetThreadExecutionState(_oldState);
                    }
                }
            }
        }
    }

    #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 | Cookies | Terms of Use | Mobile
Web06 | 2.8.190306.1 | Last Updated 7 Aug 2018
Article Copyright 2010 by Peter Vegter
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid