The .NET Framework 4.0, like previous versions,
offers support for interoperability with the COM architecture via an
engine named Runtime Callable Wrapper,
which is the infrastructure that provides a communication bridge
between .NET and COM. It is also responsible for type marshaling and
handling events. Because of this engine, you can import COM objects and
use them in your managed applications. Basically you can import two
kinds of COM components: type libraries and ActiveX components.
Importing COM components is basically accomplished via two command-line
tools: TlbImp.exe, which is required to import a type library, and AxImp.exe,
which is instead required for importing ActiveX controls.
Importing COM Components into Visual Studio
Create a new Windows
Forms project with Visual Basic and, when ready, open the Visual Studio
toolbox. When done, right-click the toolbox and select Choose Items. This launches the same-named dialog that you already know because of adding .NET controls to the toolbox. Select the COM tab and search for the Windows Media Player item, as shown in Figure 1.
When you click OK, Visual Studio generates two files for you:
Interop.WMPLib.dll, which is a CLR wrapper for using COM objects exposed by the Windows Media Player type library in a .NET fashion
AxInterop.WMPLib.dll, which is a Windows Forms proxy that provides the infrastructure required for hosting the control in your forms
At this point notice that the
Windows Media Player ActiveX control is available inside the toolbox.
Now drag the control over the current form and design the media player
as you like. At this point Visual Studio generates some code for you to
declare the control and enables you to use it. If you expand the
Form1.designer.vb file, you find the following initialization code for
the ActiveX control:
Friend WithEvents AxWindowsMediaPlayer1 As AxWMPLib.AxWindowsMediaPlayer
...
Me.AxWindowsMediaPlayer1.Enabled = True
Me.AxWindowsMediaPlayer1.Location = New System.Drawing.Point(24, 13)
Me.AxWindowsMediaPlayer1.Name = "AxWindowsMediaPlayer1"
Me.AxWindowsMediaPlayer1.OcxState = _
CType(resources.GetObject("AxWindowsMediaPlayer1.OcxState"),
System.Windows.Forms.AxHost.State)
Me.AxWindowsMediaPlayer1.Size = New System.Drawing.Size(239, 196)
Me.AxWindowsMediaPlayer1.TabIndex = 0
ActiveX controls are wrapped by the System.Windows.Forms.AxHost class that enable treating COM components as you would do with .NET objects.
|
Now you can work with the ActiveX control in a managed way, as illustrated in next subsection.
Using COM Objects in Code
When you have an instance
of the ActiveX control, or of a type library, you can access its members
like any other .NET object, thus invoking methods, assigning
properties, or handling events. For example the following code assigns
the URL property of the media player with a media file to start playing:
Private Sub Form1_Load(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load
AxWindowsMediaPlayer1.URL = "C:\users\alessandro\music\MySong.mp3"
End Sub
You can also handle events if available, as demonstrated by the following code snippet:
Private Sub AxWindowsMediaPlayer1_MediaError(ByVal sender As Object,
ByVal e As AxWMPLib.
_WMPOCXEvents_MediaErrorEvent) _
Handles AxWindowsMediaPlayer1.
MediaError
MessageBox.Show("An error occurred while opening media")
End Sub
In this particular case the MediaError
event is raised when an error occurs in playing the media file. At a
more general level, notice how wrapping an ActiveX control allows
importing different kinds of members, including events.
Catching Exceptions
When you implement Try..Catch..End Try blocks, you can intercept and handle only CLS-compliant exceptions, that is, exceptions inheriting from System.Exception. Exceptions wrapped by the COM import tools are not CLS-compliant, so a classic Try block would fail. To intercept exceptions coming from wrapped objects, the .NET Framework offers the System.Runtime.CompilerServices.RuntimeWrappedException that can be used for error handling when working with wrappers. The following code shows an example:
Try
AxWindowsMediaPlayer1.URL = "C:\users\alessandro\music\MySong.mp3"
Catch ex As RuntimeWrappedException
Catch ex As Exception
End Try
Other than usual exception properties, this class exposes a WrappedException property, of type Object, which represents the occurred problem.
Releasing COM Objects
You should always
explicitly release objects that wrap COM components so that associated
resources are also released. You accomplish this by invoking the System.Runtime.InteropServices.Marshal.ReleaseCOMObject method. Continuing with the previous example, you release the AxWindowsMediaPlayer1 object as follows:
Private Sub Form1_FormClosing(ByVal sender As Object,
ByVal e As System.Windows.Forms.
FormClosingEventArgs) Handles _
Me.FormClosing
System.Runtime.InteropServices.Marshal.
ReleaseComObject(AxWindowsMediaPlayer1)
End Sub
This is important because
COM objects treat system resources differently from .NET objects;
therefore, an explicit release is required.