How to Write and Use ActiveX Controls for Microsoft Windows CE 3.0
Summary: This paper 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. (8 printed pages)
Introducing ActiveX Controls
Building ActiveX Controls for Windows CE–Based Devices
Creating a Design Mode Control
Distributing ActiveX Controls
Using ActiveX Controls in Applications for Windows CE–Based Devices
Using ActiveX Controls in eMbedded Visual C++ 3.0
For More Information
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 Pocket PC and Handheld PC. Software written for these systems and devices must also be compact and responsive.
Microsoft ActiveX® is a set of technologies that enables 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 paper 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.
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 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), it was redesigned shortly after the initial release of OLE 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 specified interface, which increments the reference count of the instance. 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:
- Just-in-time activation. An ActiveX control can be visible, but not activated. Activation is deferred until the user interacts with the control. The control does not create its window until it is activated, so this option saves time and resources if the control is never activated.
- Mouse interaction while inactive. When a control is visible, but not activated, it can still process mouse messages delegated to it by the container. Once the control is activated, it processes messages in the usual manner.
- Flicker-free activation. If an ActiveX control draws itself the same way in both its active and inactive states, flicker-free activation can reduce screen flicker. This option prevents the control from being redrawn when it makes the transition from the inactive to the active state.
- Windowless activation. A windowless ActiveX control does not have its own window. The container is responsible for routing user-input messages to the control. Windowless controls load faster, do not have to be rectangular, and can have transparent backgrounds.
- Unclipped device context. An ActiveX control can speed up its drawing operations by using this option if it never draws outside its client rectangle. This option has no effect on windowless controls.
- Optimized drawing. When a container draws several controls into the same device context, each control selects its required graphics device interface (GDI) objects. If each control does not have to restore the previously selected objects, it can save time. The container can restore the original objects after all the controls have been drawn.
The following software is required to develop and use ActiveX controls for Windows CE–based devices:
- Microsoft Visual C++® Enterprise Edition 6.0, or Professional Edition 6.0
- Microsoft eMbedded Visual Tools 3.0
- Microsoft eMbedded Visual C++ 3.0
- Microsoft Windows CE Platform Software Development Kit (SDK) for the device you are using
- Microsoft Windows CE Services version 2.2 or later
Currently, ActiveX controls for Windows CE can be developed using the Microsoft eMbedded Visual C++ 3.0. The eMbedded Visual C++ development system offers three approaches to building an ActiveX control for a Windows CE–based device:
- The least automated approach is to write the control without using a programming framework and instead use the standard Windows CE OLE application programming interfaces (APIs).
- Using the Microsoft Foundation Classes (MFC) for Windows CE.
- Using the Active Template Library (ATL) for Windows CE, which is highly recommended because it creates smaller and faster controls.
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 printing, 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.
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 Creating ActiveX Controls using MFC topic in eMbedded Visual C++ Help.
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 (.vcp), a project workspace (.vcw), and an object description language file (.odl).
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 COM AppWizard to create ActiveX controls. To start the wizard, from the Projects menu, click New, and then click WCE ATL COM AppWizard.
After the AppWizard completes the starter program you can add controls using the ATL Object Wizard. To start the ATL Object Wizard, from the menu bar, click Insert, and then click New ATL Object.... Categories of objects are displayed on the left and the icons of the objects in each category are displayed 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 the specified control. In the dialog box, edit the names, properties, and attributes of the new Windows CE–based ActiveX 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 eMbedded 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
- 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.
- 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.
- Except for stdafx.cpp, delete all source files, headers, and dependencies from the project and close the project workspace.
- 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, then rename your files to Grid_win32.dsp and Grid_win32.dsw.
- 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.
- Copy the .dsp and .dsw files to the original project directory. This directory contains the original .dsp and .dsw files, plus the source files.
- Open the new .dsw file in Visual C++ as a workspace and add the files from step 1 to this project.
- 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.
- 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.
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.
ActiveX controls that will be used by third parties require a setup program. The setup program must 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 must compare those versions with the versions it is installing. Reinstall a file only if its version number is higher 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 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 must 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.
In eMbedded Visual C++, the Components and Controls Gallery stores the links to all the ActiveX controls registered on a computer in its 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.
To add a registered ActiveX control to a project
- Open the project workspace to which you want to add a control.
- If you have more than one project loaded in the workspace, select the appropriate project: on the Project menu, click Set Active Project, and then click the project name.
- On the Project menu, click Add To Project, and then click Components and Controls.
- In the Components and Controls Gallery dialog box, open the Registered ActiveX Controls folder, click the ActiveX control you want to add to your project, and then click 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, Windows CE Sockets, creating compound files, and support for controls. The WCE MFC AppWizard also offers a choice to build either a DLL or EXE. The WCE MFC AppWizard has visual editing options that your parent program will support, including creating a container, a miniserver, a full-server, and a program that is both a container and a server.
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 Microsoft eMbedded Visual Tools 3.0 and then distributed for use in Windows CE–based applications created in eMbedded Visual C++.
For the latest information about Windows CE and embedded development tools, see the Microsoft Windows CE Web site.
For information about ActiveX controls, see the Microsoft COM Technologies Web site.