How to Write and Use ActiveX Controls for Microsoft Windows CE

Microsoft Corporation

June 1999

Summary: Discusses how to build and distribute Microsoft® ActiveX® controls for Microsoft Windows® CE and how to use them in Windows CE-based applications. (8 printed pages) Includes:

Introduction
Introducing ActiveX Controls
Building ActiveX Controls for Windows CE–based Devices
Distributing ActiveX Controls
Using ActiveX Controls in Applications for Windows CE–based Devices
Summary
For More Information

Introduction

The Microsoft® Windows® CE operating system is designed to be compact, powerful, and fast. It is used in embedded systems and devices such as the Palm-size PC and Handheld PC. Software written for these systems and devices must also be compact and responsive.

ActiveX is a set of technologies that enable software components to interact with one another in a networked environment, regardless of the language in which the components were created. An ActiveX control is a user interface element created using ActiveX technology. ActiveX controls are small, fast, and powerful, and make it easy to integrate and reuse software components. This article introduces ActiveX controls, discusses how to build and distribute ActiveX controls for Windows CE, and describes how to use ActiveX controls in Windows CE–based applications.

Introducing ActiveX Controls

Reuse is a central goal in software design. Reusing instead of rewriting code saves development effort. ActiveX controls are reusable software components that can quickly add specialized functionality to Web sites, desktop applications, and development tools. ActiveX controls have become the primary architecture for developing programmable software components for use in a variety of different containers, ranging from software development tools to user productivity tools.

ActiveX controls are a Component Object Model (COM) technology. COM is a software architecture that allows applications to be built from binary software components. COM is the underlying architecture that forms the foundation for higher-level software services, such as those provided by OLE, a technology for transferring and sharing information among applications.

Although OLE was originally based on dynamic data exchange (DDE), shortly after the initial release of OLE it was redesigned and based on COM. This new release of OLE gave developers the ability to add new interfaces to an OLE component without needing to recompile the component's clients. If a component was replaced by a newer version, new clients could take advantage of new interfaces, but existing clients could continue to use the old interfaces.

At the same time as the redesign of OLE, the Microsoft Visual Basic® version 2.0 development system introduced Visual Basic custom controls (VBX) to the development community. VBXs were self-contained code modules, written in C or C++, which could be embedded in any Visual Basic–based application by dragging and dropping them onto a form.

The next advance leading toward ActiveX controls was the proliferation of 32-bit technology. VBX could only be compiled for 16-bit applications. Because COM was 32-bit compatible, it was the ideal basis for a new control technology. Furthermore, controls developed using COM could be written in any language and hosted in applications developed in any language. OLE custom controls (OCX) were introduced and replaced VBX technology. The original OLE control specification required each component to implement a minimum of nine specified interfaces, with a total of 60 methods and seven optional interfaces. This detailed specification of well-defined interfaces made OLE controls easy to use but tiresome for control developers to create.

The final incident motivating the development of ActiveX controls was the arrival of the Internet, particularly the popularity of the Web. Initially, the size of the control was not a concern because RAM and hard disk space were becoming less expensive each year, but the prospect of downloading controls over a slow connection made size a concern. If users became frustrated because a page with a large component was taking too long to download, they could find Web content elsewhere. The ActiveX control specification was created as an answer to this problem.

ActiveX controls are required to support only one interface, IUnknown, and two API functions, DllRegisterServer and DllUnregisterServer. These two functions ensure that ActiveX controls are self–registering; that is, they can add and remove the necessary information for their use in the target system's registry.

The IUnknown interface exposes three methods: QueryInterface, AddRef, and Release. A client calls QueryInterface to find out if an object supports a particular interface, and to obtain a reference to it. AddRef and Release are used for memory management. Each instance of an ActiveX control has a reference count. Whenever a method, such as QueryInterface, returns an interface pointer to a client, the method must first call AddRef on the interface, which increments the instance's reference count. Whenever a client is finished using an interface, the client is responsible for calling Release on it, which decrements the reference count. When the reference count reaches zero, the instance is deleted and its memory is freed.

Because an ActiveX control does not have to support the standard set of interfaces required for an OLE control, a container application must have specific knowledge about the interface for an ActiveX control in order to use it. However, ActiveX controls are small, fast, lightweight, and resource efficient, making them ideal for use on Windows CE–based devices.

ActiveX controls for Windows CE also support the following features that may be enabled to increase a control's efficiency and effectiveness in certain applications:

Building ActiveX Controls for Windows CE–based Devices

The following software is required to develop and use ActiveX controls for Windows CE–based devices:

Currently, ActiveX controls for Windows CE can only be developed using the Windows CE Toolkit for Visual C++. The Visual C++ development system offers three approaches to building an ActiveX control for a Windows CE–based device:

When building an ActiveX control for a Windows CE–based device, know the requirements of the device. For example, some devices may or may not support color, some devices have a vertical screen orientation as opposed to a traditional horizontal screen orientation, and some devices limit the user's access to their file system. It is important to take into account the specific requirements of the device on which the ActiveX control will be used.

Using MFC

MFC for Windows CE is a powerful C++ class library that can be used to create either container applications for ActiveX controls or the controls themselves. It is especially useful when creating ActiveX controls with a user interface. The MFC ActiveX ControlWizard leads you through a series of dialog boxes in which you choose options for the features and functions of your program. For more information on how to use the MFC ActiveX ControlWizard, see the Visual C++® Programmer's Guide.

After using the MFC ActiveX ControlWizard to create an ActiveX control project, you get a working starter program with the functionality you asked for when completing the steps in the ControlWizard. This starter program includes all the files necessary to build the control, including source (.cpp), header (.h), and resource files (.rc), a module-definition file (.def), a project file (.dsp), and an object description language file (.odl).

Using ATL

ATL for Windows CE is a C++ template library designed and optimized to create the most efficient ActiveX controls possible. You can use the Windows CE ATL Object Wizard to create ActiveX controls. To start the wizard, choose New ATL Object from the Insert menu.

The ATL Object Wizard displays the categories of objects on the left and the icons of the objects in each category on the right. When you choose a category, the wizard displays the icons of the objects in that category. You then double-click the control you want to insert, and the ATL Object Wizard displays a dialog box showing options that apply to your control. In the dialog box, edit the names, properties, and attributes of your new Windows CE–based ActiveX control.

Creating a Design Mode Control

Using an ActiveX control in a container application on a Windows CE–based device requires that a corresponding design mode control be created for use on the desktop development system. This process is not automated, so it is the developer's responsibility to use a separate Microsoft Win32®-based project to create a corresponding Win32-based control for each Windows CE–based control.

The primary concern when creating a design mode control to correspond with a Windows CE–based control is the proper identification of the design mode control. Each ActiveX control has a unique class identifier (CLSID) and each interface has a unique interface identifier (IID). Each identifier is a unique 128-bit code called a universally unique identifier (UUID). The Visual C++ development system automatically generates such codes when controls and interfaces are added to a project. To allow correlation between the two controls, the design mode control must have the same UUIDs as the Windows CE–based run-time control. This may seem contradictory to the use of the word unique in the name UUID; however, the apparent contradiction is resolved if the design mode control is perceived to be the same control as the Windows CE–based run-time control. The design mode control is simply compiled for use on a different platform.

There are various ways to share the necessary UUIDs between the two versions of the control. For example, separate projects with discrete source files can be used and the UUIDs in the appropriate files altered to match. A more efficient approach is to share the source files between the projects for the design mode control and the Windows CE–based run-time control, with preprocessor directives defining sections to omit or include based on the target platform.

To create a design mode control to correspond with an existing Windows CE–based run-time control, use the following procedure:

  1. Write down the names of the source code files in the original projects. These files should have the following extensions: .cpp, .h, .odl, .idl, .rc, and .def.

  2. Create a Win32 version of the control project with the same name as the original control. For MFC controls, use the MFC ActiveX ControlWizard. For ATL controls, use the ATL COM AppWizard.

  3. Except for stdafx.cpp, delete all source files, headers, and dependencies from the project and close the project workspace.

  4. Because the new .dsp and .dsw files must go into the same directory as the original control project, rename the .dsp and .dsw files. For example, if the original project name is Grid, rename your files to Grid_win32.dsp and Grid_win32.dsw.

  5. With a text editor, open the .dsw file in Visual C++ and edit the file to reflect the new project name. Close the .dsw file when you are finished.

  6. Copy the .dsp and .dsw files to the original project directory. This directory contains the original .dsp and .dsw files, plus the source files.

  7. Open the new .dsw file in Visual C++ as a workspace and add the files from step 1 to this project.

  8. Verify that the output control name is the same name as the original project name, such as Grid.ocx rather than Grid_win32.ocx. This control name is specified in Project, Settings, Link, and Output file names.

  9. Make any necessary changes to the project source code to account for differences between the Windows CE operating system and Windows desktop operating systems.

A corresponding design mode control can implement all of the functionality of a Windows CE–based run-time control or can just define empty methods to serve as placeholders on the desktop system. Obviously, the second of the two approaches is faster to implement. However, if the behavior of the control would be useful for desktop applications, it may be worthwhile to fully define the behavior of the control.

Distributing ActiveX Controls

After the ActiveX controls for Windows CE are built, they can be used in-house or distributed for third-party use.

To use an ActiveX control in-house, copy the control to where it will run and then call the regsrvce.exe tool to register the ActiveX control on a Windows CE–based device. If you are using the Visual Basic development system, use the Control Manager to designate the platforms for which the ActiveX control is applicable. For more information, see the section to follow, "Using ActiveX Controls in Visual Basic."

ActiveX controls that will be used by third parties require a Setup program. The Setup program needs to register the control. The regsrvce.exe tool can be used to register an ActiveX control on a Windows CE–based device, and the regsvr32.exe tool can be used to register an ActiveX control on the desktop system. Another option is to write your Setup program to register the control directly.

The Setup program you provide with your ActiveX controls must install the control's .ocx or .dll files and the necessary redistributable .dll files in the Windows system directory. If any of the DLLs are already present on a user's machine, the Setup program needs to compare those versions with the versions it is installing. Reinstall a file only if its version number is later than the file already installed. Because ActiveX controls can be used only in OLE container applications, there is no need to distribute the full set of OLE DLLs with your control.

Using ActiveX Controls in Applications for Windows CE–based Devices

Using an ActiveX control in an application for a Windows CE–based device is similar to using ActiveX controls in desktop applications. The primary difference is the use of design mode and run-time controls. To use an ActiveX control in an application being developed, the design mode control must be registered on the desktop system and the run-time control must be registered on the Windows CE–based device. Controls with a Setup program are registered when they are installed. If there is no Setup program, the controls have to be registered manually. The regsrvce.exe tool registers an ActiveX control on a Windows CE–based device, and the regsvr32.exe tool registers an ActiveX control on the desktop system.

Using ActiveX Controls in Visual Basic

To use an ActiveX control for Windows CE in Visual Basic, you must let Visual Basic know that the design mode control exists. To do this, open the Control Manager tool in the Microsoft Windows CE Toolkit for Visual Basic and follow these steps:

  1. In the left pane, select the configuration to which you want to add an ActiveX control.

  2. Choose Add New Control from the Control menu.

  3. Select the control that you want to add and then choose Open.

The visibility of an ActiveX control determines how you add the control to your project. If the control is visible, you must add it to the Toolbox and put it on a form. To add an ActiveX control to the Toolbox, choose Components from the Project menu to display the Components dialog box. Then select the check box to the left of the control name. When you choose OK, the ActiveX control appears in the Toolbox.

For invisible controls added at run time, add a reference to the control in the References dialog box by choosing References from the Project menu. Select a control type from the References dialog box and then choose OK. Use the CreateObject function to create an object that cannot receive events, or use the CreateObjectWithEvents function to create an object that can receive events. These functions create invisible ActiveX controls only; they cannot create graphical ActiveX controls.

Using ActiveX Controls in Visual C++

In Visual C++, the Gallery stores the links to all the ActiveX controls registered on a computer in the Registered ActiveX Controls folder. To add a third-party ActiveX control to the Gallery, run the Setup program supplied with the control. This registers the ActiveX control with the system, adding a shortcut to the control in the default Registered ActiveX controls folder.

Without a valid Setup program, you cannot add a third-party ActiveX control to the Gallery. To register these ActiveX controls, use the regsrvce.exe tool on a Windows CE–based device or the regsvr32.exe tool on the desktop system.

After an ActiveX control is registered, you can add it to a project with the following steps:

  1. Open the project workspace to which you want to add a control.

  2. If you have more than one project loaded in the workspace, select the appropriate project: Point to Set Active Project on the Project menu, and then choose the project name.

  3. Point to Add To Project on the Project menu, and then choose Components and Controls.

  4. Open the Registered ActiveX Controls folder in the Components and Controls Gallery dialog box, and select the ActiveX control you want to add to your project. Choose Insert.

You can use the shortcut menu to quickly add registered ActiveX controls to a dialog box, and you can use the Components and Controls Gallery to add an ActiveX control to the Controls toolbar of the active project.

An ActiveX control container is a parent program that supplies the environment for an ActiveX control to run. You can create an application capable of containing ActiveX controls with or without MFC, but it is much easier to do so with MFC.

Creating an MFC container program using the MFC AppWizard allows you to access the many features of ActiveX controls and Automation that are implemented by the MFC and ActiveX classes. These features include visual editing, Automation, creating compound files, and support for controls. The MFC AppWizard visual editing options that your parent program will support include creating a container, a miniserver, a full-server, and a program that is both a container and a server.

Summary

ActiveX controls are small, fast, powerful, and reusable software components, making them ideal for use in Windows CE–based applications. These controls can be created using the Windows CE Toolkit for Visual C++ and then distributed for use in Windows CE–based applications created in either Visual C++ or Visual Basic.

For More Information

For the latest information about Windows CE and embedded development tools, see the Microsoft Windows CE Web site at http://www.microsoft.com/windowsce/.

For information about ActiveX controls, see http://www.microsoft.com/com/tech/activex.asp.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. This document is for informational purposes only.

This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT.

© 1999 Microsoft Corporation. All rights reserved.

Microsoft, ActiveX, Visual Basic, Visual C++, Visual J++, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

Java is a trademark of Sun Microsystems, Inc.

Other product and company names mentioned herein may be the trademarks of their respective owners.