Workaround: ActiveX Controls Not Working via XAML

Mike Henderlight recently posted a nice summary of a bug in WinFX current (September CTP) bits: ActiveX Controls Not Working via XAML.

An attempt to instantiate an ActiveX control with a managed wrapper (Axhost) from XAML fails with an interesting exception. Something to do with a child HWND not being attached to the appropriate parent. Our crack dev, Scott Berry, thinks we're delay-creating a window when we shouldn't.

In any case, the workaround is to instantiate the ActiveX control in the code-behind file. Since I just finished writing a topic for the docs that describes how to do this, I thought it would be convenient to grab the baton from Mike and show you how to do the workaround. I've adapted my doc for the blog. Hope it helps.


In order to complete this walkthrough, you will need:

  • Microsoft Windows Media Player installed on the computer where Microsoft Visual Studio 2005 is installed.

To Create the Project

  1. Create a Windows Presentation Foundation application project named "HostingAxInWpf".

  2. Add a Windows Control Library project to the solution. Name the project "WmpAxLib".

  3. In Solution Explorer, add a reference to the Microsoft Windows Media Player assembly, which is named wmp.dll.

  4. Open the Toolbox. Right-click in the Toolbox and select Choose Items… from the shortcut menu.

  5. Click the COM Components tab and select the Windows Media Player control. Click OK to accept the selection. (The Microsoft Windows Media Player control is added to the Toolbox.)

  6. In Solution Explorer, right-click the UserControl1 file. Select Rename from the shortcut menu and change the name to "WmpAxControl.cs." Click Yes if you are asked to rename all references.

To Create the ActiveX Control

Microsoft Visual Studio automatically generates an AxHost wrapper class for an ActiveX control when it is placed on a design surface. The following procedure creates a managed assembly named AxInterop.WMPLib.dll.

  1. Open WmpAxControl in the Windows Forms designer.
  2. From the Toolbox, drag the Microsoft Windows Media Player control onto the design surface.
  3. In the Properties window, set the value of the Microsoft Windows Media Player control's Dock property to Fill.
  4. Press F6 to build the control library.

To Host the ActiveX Control on a Windows Presentation Foundation Page

  1. In the HostingAxInWpf project, add a reference to the generated ActiveX interop assembly. This assembly is named AxInterop.WMPLib.dll and was placed in the Debug folder of the WmpAxLib project when you imported the Microsoft Windows Media Player control.
  2. Add a reference to the WindowsFormsIntegration assembly, which is named WindowsFormsIntegration.dll. The default location for this file is the C:\Program Files\Reference Assemblies\Microsoft\WPF\v3.0 folder.
  3. Add a reference to the Windows Forms assembly, which is named System.Windows.Forms.dll.
  4. Open Window1.xaml and replace the generated code with the following code.

<

Window x:Class="HostingAxInWpf.Window1"

xmlns="https://schemas.microsoft.com/winfx/avalon/2005"

xmlns:x="https://schemas.microsoft.com/winfx/xaml/2005"

Title="HostingAxInWpf"

Loaded="WindowLoaded"

>

<

Grid Name="grid1">

</

Grid>

</

Window>

5. Open Window1.xaml.cs and uncomment the definition of the WindowLoaded method.

6. Insert the following code to handle the Loaded event. This code creates an instance of the WindowsFormsHost control and adds an instance of the AxWindowsMediaPlayer control as its child.

private void WindowLoaded(object sender, RoutedEventArgs e)

{

// Create the interop host control.

System.Windows.Forms.Integration.WindowsFormsHost host =

new System.Windows.Forms.Integration.WindowsFormsHost();

// Create the ActiveX control.

AxWMPLib.AxWindowsMediaPlayer axWmp = new AxWMPLib.AxWindowsMediaPlayer();

// Add the ActiveX control to the host control's

// collection of child controls.

host.Children.Add(axWmp);

// Add the interop host control to the Grid

// control's collection of child controls.

this.grid1.Children.Add(host);

// Play a .wav file with the ActiveX control.

axWmp.URL = @"C:\WINDOWS\Media\Windows XP Startup.wav";

}

7. Press F5 to build and run the application.


Hopefully, that was relatively quick and painless.