Creating ActiveX Components in C++
Nancy Winnick Cluts
ActiveX™ is a technology built on the Component Object Model (COM) that allows the developer to create objects or controls that can be used to "activate" content on the World Wide Web. Many popular Web sites, such as www.microsoft.com, contain ActiveX controls to provide user interface objects such as list boxes and buttons. This article walks you through the basic steps of creating a simple ActiveX control. I then explain how you can embed this control in a Visual Basic® application or use the control directly from Internet Explorer 3.0. This article is based on Adam Denning's presentation for the Site Builder Conference held in San Jose, California, October 27–30, 1996. To access MSDN resources, go to http://msdn.microsoft.com.
Why Use ActiveX Controls?
Sure, it's a whizzy new technology and it's always fun to be the first person on your floor (of cubicles, no doubt) to brag that you are the master of the latest technology, but does it really buy you anything? The answer is "yes" if you are creating a Web site that you want people to find interesting enough to explore. "But," you may say, "Can't I do that already with Java™ or with scripting languages such as CGI?" Yes, you can, but ActiveX controls have some distinct benefits that other types of controls or scripting do not provide.
Access to operating system features
If you are a Java or Visual Basic developer, you may have run into situations where you really wanted to use some key feature of the operating system. Let's say you want to be able to draw something using DirectX™. You can't do it directly with Visual Basic, and, if you try it in Java, you aren't going to be playing in the sandbox anymore (for those of you who aren't Java-aware, the "sandbox" is the name used for the virtual machine in which your Java applet runs). This virtual machine is not allowed access to your system's services, to protect you, the consumer of the Java applet, from inadvertently downloading a virus that reads from or writes to your hard disk. A way to get around the problem of not being able to access basic system services is to write an ActiveX control using the Win32® API and C++.
Security through Authenticode
Because ActiveX enables you to access basic system services, you need some mechanism by which you can download a control to use without worrying it might do something nasty to your machine. This mechanism is provided by Authenticode, or code signing, which allows a control developer to digitally vouch for his code.
The Pros and Cons of C++
It is true that you can write controls using other tools or languages. It's also true that some people, who shall remain nameless, seem to think that C++ is a difficult language or that you have to thoroughly understand COM to write a control in C++. Okay, so these statements might possibly be true, unless you started out with assembly language and think that the latest tools are for wimps. With C++, you also don't get built-in string manipulation (like you do in Visual Basic), or built-in garbage collection and reference counting (like you do in Java). Of course, you can always buy tools to find memory leaks and C++ does give you the ability to truly customize exactly how strings should be manipulated in your code using the Win32 API. You can get to the GDI layer, use DirectX, get direct access to window handles, and provide threading via C++.
The Microsoft Foundation Classes (MFC) provide some excellent opportunities to work with COM, and make it extremely easy to do so. However, the MFC DLL that you need to provide for your control is rather large (okay, it's huge). This means that the very first time the user opts to download your MFC control, she will take the hit of downloading that large DLL. Once that DLL is downloaded, she's set; she's got the DLL for all MFC-based ActiveX controls that use that same version of MFC. She won't need to download a DLL again unless she encounters an MFC-based ActiveX control that uses a different version of MFC.
Many commercially available compilers and development environments for C++ are available from a variety of vendors, including Borland, Symantec, WatCom, and, yes, even Microsoft. Both MFC and the Active Template Library (ATL) are licensed by all of the major Windows® C++ compiler vendors, so you know that—if you write an ActiveX control using MFC or ATL—you will be able to choose the tools that you like. If you use Visual C++®, you will have access to a fully integrated development environment with full support for Win32 development, MFC-centric tools, and very powerful debugging facilities.
Using the Microsoft Foundation Classes (MFC)
MFC is a C++ class library that contains a set of C++ classes, functions, macros, and variables that support many features of the Win32 and ActiveX technologies. It is an application framework designed to get you up and running with an application skeleton very quickly and easily. By using the built-in classes, you can create full Win32 applications or components.
MFC is based on a single-inheritance hierarchy. At the root of this hierarchy is CObject. Most classes derive from CObject. Another basic component is CWinApp, the class created for Windows applications. However, the class that is of most interest to ActiveX developers is COleControl. This class dispatches messages and events to OLE controls, and is derived from the generic window-handling class, CWnd.
Follow these six basic steps to create an ActiveX control using MFC:
1. Create a skeleton control using AppWizard.
To create the skeleton control, run AppWizard and choose to create a new project workspace. Choose the OLE control option to create an MFC control. Next, choose to make the control available in your dialog box. You can then choose the defaults and App Wizard will create source files based on the COleControl class, which includes support for basic events.
2. Add a property to your control.
At this point, your control is very basic. It really doesn't do much of anything—although you can check to ensure that it builds and runs. To make your control useful, you need to do a bit more work. Run Class Wizard and add a property for your control, filling in the external name for your property. This is the name that the container (any application that is using the control, such as a Visual Basic application or Internet Explorer) will see and use. You'll also need to add code to implement your property if it is anything more than simple value storage.
3. Add a method using Class Wizard.
The next step is to add a method (otherwise known as the code) to your control. Click the option to edit the code for your method. This is the place where you have your "meat and potatoes" and actually do something.
4. Add an event.
Next, you need to add an event. Any time this event occurs (such as a button click), your control can fire this event to notify its container. If you take a look at the source files, you will notice that Class Wizard added code to the dispatch map and added an identifier (a dispid) for the event. You can build your control now. Visual C++ will take care of registering the control for you.
5. Sign your code.
Once your code is built and you have tested it within Visual C++, you will need to digitally sign it if you want to send it out to the masses. In a general sense, this means that you need to vouch that your code does not contain viruses and does what you say it does. Code signing is covered in depth in Signing and Marking ActiveX Controls.
6. Display the control using Visual Basic or Internet Explorer.
This step is optional, but important if you want to add a front-end to your control or if you want to test it using Internet Explorer. Using Visual Basic, choose to insert an OLE control (custom control) and select the control that you just created and registered. The name of the control that shows will be the name you listed when you created the control project. Next, click on the form and add code to handle the event that you specified. Then simply run the Visual Basic application, do whatever you decided to do to fire the event (such as clicking on the button), and see whether your control fires the event up to its containing form.
Using Internet Explorer 3.0, this step is also easy. Use the ActiveX Control Pad to insert the object, selecting the control from the list of ActiveX controls registered on your system. At this point, you can change some of the properties of the control, such as the height and width, and you can also change the HTML code generated. Save out the code to HTML and double-click the HTML file. Your browser of choice (you are using Internet Explorer 3.0, aren't you?) will run with your new page and your new control loaded.
ActiveX Template Library (ATL)
The ActiveX Template Library is a set of C++ template classes that is used to create COM objects. Unlike MFC, ATL is not a framework and does not have a run-time DLL associated with it. This means that if you create a control using ATL, your end-user need download only the object itself. There is no big, honking DLL associated with the object that also needs to be resident. You can use ATL with MFC or as a stand-alone tool. You can also use it with other tools or frameworks if you like. ATL was designed to create controls that are small and fast. Also unlike MFC, ATL uses multiple inheritance rather than single inheritance everywhere.
Creating an ActiveX control using ATL 2.0 is similar to creating a control using MFC. You first create a skeleton COM object using AppWizard. Then you add a method, sign your code, and test it using either a Visual Basic application or Internet Explorer 3.0. With ATL 2.0, you can create one of several control types, such as an Internet Explorer control (all this means is that the wizard throws out the minimum number of interfaces necessary to ensure that the control will be recognized by Internet Explorer and will draw itself). You can add stock properties such as background color, height, and width to the control. The wizard will also create a default HTML page to enable you to display the control in Internet Explorer 3.0. For more information, see the ATL Web site at http://msdn.microsoft.com/VISUALC/prodinfo/.
C++ is a great language for writing performance-critical ActiveX components. With C++, you can create small, fast objects, if you take your time and are careful. MFC can get you up and running fast, but you may take a one-time download hit using its run-time library. ATL might be the answer for you if you want to create compact and fast ActiveX controls. ATL 2.0, which provides all of the updated ActiveX support, is currently in beta release and will soon be available on the Web.