65.9K
CodeProject is changing. Read more.
Home

Late Bound ActiveX Loading [TamilFM]

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (9 votes)

Oct 27, 2006

CPOL

2 min read

viewsIcon

61470

downloadIcon

1057

Late Bound ActiveX loading [TamilFM]

Sample Image - TamilFM_Screen_Shot.jpg

Introduction

This project was inspired by SafeCOMWrapper.

There are several problems using ActiveX from .NET:

  • You cannot guarantee ActiveX references are finalized.
  • When you "Add Reference..." to an ActiveX library, the reference is version specific. So, if you add a reference to the MPlayer11 ActiveX library, it does not work properly when deployed to MPlayer10.
  • The only solution to version independent ActiveX uses Late Bound operations but you miss all the features of a strongly typed language.

Let's solve all these problems by using COMWrapper and AxHost classes. To learn more about the late bound COM usage in .NET, refer to COMWrapper.

Background

This project was highly inspired and influenced by SafeCOMWrapper.

Please refer to this project before proceeding further.

Introducing AxHost and Using for Late Bound ActiveX

AxHost class wraps ActiveX controls and exposes them as fully featured Windows Forms controls. AxHost class was provided by Forms namespace:

public class AxVLCPlayer : AxHost
    {
        /// <summary>
        /// vlc ActiveX control default interface
        /// </summary>
        IVLCCore ocx; 

        public AxVLCPlayer(string strClaid)
            : base(strClaid)
        {

        } 
        /// <summary>
        /// must be overridden to initialize the ocx field
        /// </summary>
        protected override void AttachInterfaces()
        {
            try
            {
                this.ocx = (IVLCCore)COMWrapper.Wrap(this.GetOcx(), typeof(IVLCCore));
            }
            catch (System.Exception)
            {
            }
        } 
}

To load the ActiveX control in C#, we must create a new class from the AxHost class. From the new class, we must call the base (AxHost) class's one parameter constructor; the constructor argument would be the typelib guid of the ActiveX control which we want to load.

The new class will look like the one shown above.

The new class must override the AttachInterfaces() method to access its default interface. The below statement will attach the ActiveX control default interface in the late bound method.

this.ocx = (IVLCCore)COMWrapper.Wrap(this.GetOcx(), typeof(IVLCCore));

The IVLCCore interface must be declared manually:

    public interface IVLCCore : IDisposable
    {
        bool AutoPlay
        {
            get;
            set;
        }

        string MRL
        {
            get;
            set;
        }
        bool Playing
        {
            get;
        }
        int Volume
        {
            get;
            set;
        }
        void addTarget(string uri, object options, VLCPlaylistMode mode, int position);
        void playlistClear();
        void play();
        void stop();
    }

And the interface methods are exposed as shown below:

/// <summary>
/// enable autoplay mode
/// </summary>
public bool AutoPlay
{
    get
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("AutoPlay", AxHost.ActiveXInvokeKind.PropertyGet);
        return ocx.AutoPlay;
    }
    set
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("AutoPlay", AxHost.ActiveXInvokeKind.PropertySet);
        ocx.AutoPlay = value;
    }
}

/// <summary>
/// get/set mrl links
/// </summary>
public string MRL
{
    get
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("MRL", AxHost.ActiveXInvokeKind.PropertyGet);
        return ocx.MRL;
    }
    set
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("MRL", AxHost.ActiveXInvokeKind.PropertySet);
        ocx.MRL = value;
    }
}

/// <summary>
/// check whether the player is playing its content or not
/// </summary>
public bool Playing
{
    get
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("Playing", AxHost.ActiveXInvokeKind.PropertyGet);
        return ocx.Playing;
    }
}

/// <summary>
/// get/set volume
/// </summary>
public int Volume
{
    get
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("Volume", AxHost.ActiveXInvokeKind.PropertyGet);
        return ocx.Volume;
    }
    set
    {
        if (ocx == null)
            throw new AxHost.InvalidActiveXStateException
            ("Volume", AxHost.ActiveXInvokeKind.PropertySet);
        ocx.Volume = value;
    }
}

/// <summary>
/// add target to play list
/// </summary>
/// <param name="uri">URL</param>
/// <param name="options">most cases null</param>
/// <param name="mode">VLCPlaylistMode</param>
/// <param name="position">in play list</param>
public void addTarget
    (string uri, object options, VLCPlaylistMode mode, int position)
{
    if (ocx == null)
        throw new AxHost.InvalidActiveXStateException
        ("addTarget", AxHost.ActiveXInvokeKind.MethodInvoke);
    ocx.addTarget(uri, options, mode, position);
}

/// <summary>
/// clear play list
/// </summary>
public void playlistClear()
{
    if (ocx == null)
        throw new AxHost.InvalidActiveXStateException
        ("playlistClear", AxHost.ActiveXInvokeKind.MethodInvoke);
    ocx.playlistClear();
}

/// <summary>
/// start/resume play
/// </summary>
public void play()
{
    if (ocx == null)
        throw new AxHost.InvalidActiveXStateException
        ("play", AxHost.ActiveXInvokeKind.MethodInvoke);
    ocx.play();
}

/// <summary>
/// stop playing
/// </summary>
public void stop()
{
    if (ocx == null)
        throw new AxHost.InvalidActiveXStateException
        ("stop", AxHost.ActiveXInvokeKind.MethodInvoke);
    ocx.stop();
}

Finally our ActiveX wrapper class is ready. The next thing is just to create the object for this wrapper class and use it as other .NET class objects.

///Initialize the vlc media player
vlcPlayer = new AxVLCPlayer(getClsidFromProgId("VideoLAN.VLCPlugin.1"));
            ((System.ComponentModel.ISupportInitialize)(vlcPlayer)).BeginInit();

 vlcPlayer.Enabled = true;
 vlcPlayer.Location = new System.Drawing.Point(0, 9);
 vlcPlayer.Name = "vlcPlayer";
 vlcPlayer.Size = new System.Drawing.Size(55, 50);
                  ((System.ComponentModel.ISupportInitialize)(vlcPlayer)).EndInit();

///workaround for vlc player size problem
vlcPlayer.Location = new System.Drawing.Point(0, 9);
vlcPlayer.Size = new System.Drawing.Size(55, 50);
vlcPlayer.AutoPlay = true;

That’s all folks. Our ActiveX class is ready.

Conclusion

I'd like to thank my brother (RathaKrishnan) for doing some quick testing for me. Of course there might be a few bugs left for all I know. But I am hoping on getting some quality feedback and suggestions.

History

  • 26th October, 2006: Initial version 2.0