Add COM and ActiveX Support in .NET Compact Framework Using Odyssey Software CFCOM

.NET Compact Framework 1.0

Andy Sjöström

September 2003

Applies to:

   Microsoft® .NET Compact Framework version 1.0
   Microsoft Visual Studio® .NET 2003
   Odyssey Software CFCOM version 1.0
   Windows Mobile™ 2003 software for Pocket PCs

Summary: Learn how to add COM and ActiveX support to .NET Compact Framework applications in Visual C#. Also, see how the Macromedia Flash Player 6 for Windows Mobile 2003 software for Pocket PCs can be used in .NET Compact Framework applications. (11 printed pages)

Background: COM and ActiveX® interoperability is available in the full .NET Framework. Managed .NET Compact Framework code can call unmanaged functions residing in DLLs using Platform Invoke (P/Invoke), but full COM and ActiveX support is not available in the .NET Compact Framework. Odyssey Software's CFCOM becomes the intervening layer that exposes COM objects and ActiveX controls as .NET equivalences to .NET Compact Framework applications using a memory foot print that is only about 30K.

Odyssey Software CFCOM enables transparent access to controls such as the Windows Media Player and objects such as the Pocket Outlook Object Model and ADOCE, and virtually any third party COM or ActiveX component. CFCOM can be licensed from Odyssey Software, although the code sample in this article will work with the license key found in the source code.

Download cfcom.exe from the Microsoft Download Center.


Odyssey Software CFCOM
Code Walk-through
Macromedia Flash 6 Player for Pocket PC
Flash Anyplace
Flash Anyplace Code Walk-through


The Microsoft#&174; .NET Compact Framework is a hierarchy of namespaces and classes that, despite its small size, is very similar to the full .NET framework. It is natural that some features in the full .NET Framework had to be left out for size and performance reasons. One of these features is COM interoperability. Many core elements of Microsoft Windows® CE and the Pocket PC within connectivity, messaging, communication, graphics, media, data storage, and personal information management (PIM) are implemented as COM objects or ActiveX controls. There are also many third party COM and ActiveX controls that are intended for use with mobile devices, for example within GPS, charting, security and connectivity. Platform Invoke (P/Invoke) found in the System.Runtime.InteropServices namespace makes it possible to call simple unmanaged code functions. One example of a third-party utilities provider with which existing .NET Compact Framework interoperability services are sufficient is Sapphire Solutions Ltd ( Sapphire Solutions has components and source code for remote access services, encryption, and so on. Sapphire Solutions components are shipped with .NET Compact Framework code samples utilizing Platform Invoke, which makes it easier to start using the code.

Calling more complex unmanaged functions requires a significant amount of complex coding that involves more challenging areas, such as marshalling. Developing COM wrappers often results in simplified function-based interfaces. Integrating COM and ActiveX into managed code is challenging.

Odyssey Software CFCOM

Odyssey Software is not a stranger in the Windows CE developer community. They have been around since 1996 and have played an important role in enabling enterprise mobile application development through products such as CEfusion and ViaXML. The company continues to provide tools to the mobile application development community, this time with an intervening layer between COM and the Compact Framework that exposes COM types as .NET equivalents. CFCOM provides comprehensive COM and ActiveX interoperability to Compact Framework applications.

CFCOM can be seen as a wrapper that enables the use of both COM and .NET objects in the same application. A Compact Framework object is controlled by the Common Language Runtime (CLR) in managed memory while a COM object is held in unmanaged memory. CFCOM is implemented to act as a transparent wrapper, making interaction of managed and unmanaged components possible: setting and getting property values, calling methods, capturing COM events, handling advanced type conversion functionality (a k a marshalling) and generating native .NET exceptions from exceptions occurring in unmanaged code.

To the developer, CFCOM is fundamentally composed of three files:

  • Odyssey.CFCOM.dll contains the CFCOM Runtime.
  • Odyssey.CFCOM.Design.dll is required for design-time support in Microsoft Visual Studio®. This file is placed, by the installer, in the directory C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\ v1.0.5000\Windows CE\Designer.
  • Odyssey.CFCOM.1248.dll is the native (device-specific) runtime component.

Figure 1 illustrates the ComObject and ComControl tools added to the toolbox.

Figure 1. ComObject and ComControl tools added to the toolbox

Odyssey Software also includes a sample Windows Media Player Wrapper Designer that the developer can add to the toolbox and set property values in design-time. Compact Framework applications using Windows Media Player can then quickly be created.

For eMbedded Visual Basic developers, CFCOM means being able to carry on using familiar COM objects and ActiveX controls, without the need to learn C/C++ and P/Invoke. eMbedded Visual C++ developers can continue to write the performance-critical portions of their applications in C++, without having to create native wrappers and dealing with custom marshalling.

For more information on Odyssey Software CFCOM, you can read the Microsoft Case Study, COM Interop Library Gives Compact Framework Applications Easy Access to COM Components and ActiveX Controls.

Code Walk-through

CFCOM is designed to be as transparent as possible. There are only two things that need to be set before using an ActiveX control or COM object:

  • The ProgID or CLSID of the ActiveX control or COM object
  • The CFCOM license key which is acquired from Odyssey Software

After this, it is possible to start using the component using CFCOM's Invoke method. The following code shows how the Windows Media Player can be used in a Compact Framework application.

The license key is set in the application's main entry point.


The one-form application can then start using the Windows Media Player.

public class frmMain : System.Windows.Forms.Form

public frmMain()
mpc.ProgID = "WMPCEOCX.WMP";
mpc.Invoke("ShowControls", InvokeFlags.SetProperty, false);
mpc.Invoke("ShowAudioControls", InvokeFlags.SetProperty, false);
mpc.Invoke("ShowPositionControls", InvokeFlags.SetProperty, false);
mpc.Invoke("ShowTracker", InvokeFlags.SetProperty, false);
mpc.Invoke("ShowStatusBar", InvokeFlags.SetProperty, true);
mpc.Invoke("Autostart", InvokeFlags.SetProperty, true);
mpc.Invoke("Filename", InvokeFlags.SetProperty, "");
mpc.Invoke("SendMouseClickEvents", InvokeFlags.SetProperty, true);
mpc.ComObject.ComEvent += new ComEventHandler(mpc_COMEvent);

Note how the ProgID is set and then how the Invoke method is used to set properties. The InvokeFlags enumeration includes SetProperty, GetProperty, and CallMethod.

For more information about this code and how to add media to Compact Framework applications, see the article, "Play Media with .NET CF using CFCOM" located at:

Figure 2 illustrates the application running with the Windows Media Player ActiveX control.

Figure 2. Windows Media Player Active X control

Macromedia Flash 6 Player for Pocket PC

Macromedia has made available a free Pocket PC player for Macromedia Flash content. Flash is a popular platform for delivering high profile content, movies and even mobile applications. The Flash development community is active and growing. Developers using Flash in mobile application development based on Visual Studio .NET and the Compact Framework can easily bring out fantastic content and applications. The Pocket PC player can be downloaded for personal use free from the Macromedia Web site at:

The player is an ActiveX control which most commonly is hosted in Pocket Internet Explorer and is physically installed as flash.dll in the directory \Windows\Macromedia. Once the player has been installed the user can view Macromedia Flash content in Pocket Internet Explorer. One way to do that is to put the Flash content file (.swf) and HTML file in the same directory and open the HTML file. The HTML file reveals how the ActiveX control is called. The following snippet is from such an HTML file:

<BODY bgcolor="#53695C">
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 ID=rapier4  WIDTH=230 HEIGHT=255>
<PARAM NAME=movie VALUE="book.swf">
<PARAM NAME=menu VALUE=false>
<PARAM NAME=quality VALUE=high>
<PARAM NAME=bgcolor VALUE=#53695C>

The ActiveX control is called using the parameters mentioned after the "PARAM" properties. The movie to be played is called "book.swf," the Flash context menu is turned off, quality is high and the background color is set to #53695C.

Figure 3 illustrates the result in Pocket Internet Explorer.

Figure 3. Pocket PC Flash player in action

The Macromedia Flash content shown in this sample is designed by the Flash developer Phillip Torrone from ( More samples like this and more Pocket PC and Macromedia Flash related information can be found on the site Pocket PC Flash (

For more information on Flash player parameters, see the article, "Scripting with Flash Player and ActiveX" on the Macromedia Web site at:

Let's take a look at how to put the Flash player to work in a Compact Framework application.

Flash Anyplace

Flash Anyplace is an application that hosts the Flash ActiveX control using CFCOM. Flash Anyplace can play back content and provide the user with some control of how the content is played back. Figure 4 illustrates the first form.

Figure 4. Flash player settings

In the form, the user can set what Flash file to view and control the way the Flash file should behave. The second form (figure 5) illustrates the actual Flash file being played.

Figure 5. Viewing the file

Flash Anyplace Code Walk-through

The project consists of two forms. The following code executes when the user taps the "Play" button on the first form:

private void btnPlay_Click(object sender, System.EventArgs e)
Cursor.Current = Cursors.WaitCursor;
frmFlashAnyplacePlayer flashAnyplacePlayer = new frmFlashAnyplacePlayer(this, this.txtFlashFile.Text, this.cmbQuality.SelectedIndex, this.cmbScale.SelectedIndex, this.chkLoop.Checked, this.chkMenu.Checked, this.txtBackgroundColor.Text);

The parameters are sent to the second form, which has a CFCOM ComControl on it. The ProgID of Macromedia's Flash Player is ShockwaveFlash.ShockwaveFlash. This is set in the form's InitializeComponent section:

this.flashPlayer = new Odyssey.CFCOM.ComControl();
this.flashPlayer.ProgID = "ShockwaveFlash.ShockwaveFlash";

It is also possible to use the CLSID found in the HTML file of Flash content played in Pocket Internet Explorer. The line would then be:

this.flashPlayer.ProgID = "{D27CDB6E-AE6D-11cf-96B8-444553540000}";

Note that the license key has to be set before interacting with the ComControl. First, set the license key string in the declarations:


This license key enables usage of CFCOM with the Flash player only (using the ProgID) and with this project only. The AddLicense method should be placed just prior to the Application.Run location in the startup form. CFCOM tracks the license on a per process basis.

static void Main() 
// Set license key
Application.Run(new frmFlashAnyplace());

If the location of the Flash file is on the Internet, use the URL as the movie location. For example, If the location of the Flash file is locally on the Pocket PC use the following format:


The Flash Anyplace project has a Flash file as a Content item, which is installed in the application directory. To get the current application directory and suggest the Flash file as default, the following code is executed:

// Get application directory
string currentDir = new FileInfo(Assembly.GetExecutingAssembly().GetName().CodeBase).DirectoryName;
// Set default values
txtFlashFile.Text = @"file://" + currentDir + @"\book.swf";

The load event of the second form passes the parameters to the Flash player through CFCOM:

flashPlayer.Invoke("quality", InvokeFlags.SetProperty, quality);
flashPlayer.Invoke("bgcolor", InvokeFlags.SetProperty, backgroundColor);
flashPlayer.Invoke("scale", InvokeFlags.SetProperty, scale);
flashPlayer.Invoke("loop", InvokeFlags.SetProperty, loop);
flashPlayer.Invoke("menu", InvokeFlags.SetProperty, menu);
flashPlayer.Invoke("movie", InvokeFlags.SetProperty, flashFile);
catch(Exception ex)
Cursor.Current = Cursors.Default;

If we had tried to pass an invalid parameter name to the Macromedia Flash Player, the exception handling would have returned an appropriate exception. For example, when passing "movie1" as a property instead of "movie", CFCOM would have thrown the exception "0x80020006: DISP_E_UNKNOWNNAME."

Finally, when the user leaves the form with the Flash player, the CFCOM ComControl is disposed:

private void frmFlashAnyplacePlayer_Closing(object sender, System.ComponentModel.CancelEventArgs e)

From CFCOM's help file: "As straightforward as CFCOM may be, there is one very important issue to be aware of. Due to the non-deterministic nature of garbage collection, it is frequently necessary to dispose of COM resources manually. This is accomplished with the ComObject.Dispose and ComControl.Dispose methods. Certain ActiveX controls, such as Windows Media Player, exhibit strange behavior when they are not disposed of before garbage collection."


Odyssey Software CFCOM addresses some very challenging areas of Compact Framework development: ActiveX and COM interoperability. By implementing a transparent layer between managed and unmanaged code, the developer can stay focused on the core challenges that are bringing the right value to its users.