TweetFollow Us on Twitter

ActiveX Controls for Mac

Volume Number: 13 (1997)
Issue Number: 6
Column Tag: Webtech

ActiveX Controls for Macintosh

by Michael Fanning, Microsoft

Microsoft's next generation of content-rich web page development

Welcome

Macintosh ActiveX is Microsoft's native implementation of ActiveX controls for the Macintosh platform. A "control" can be loosely defined as a next-generation plug-in technology for Web browsers such as Microsoft's Internet Explorer, Netscape Navigator, and (soon) Apple's Cyberdog browser part. Controls can also be used to quickly add specialized functionality to desktop applications and development tools in addition to Web sites. Mac ActiveX provides a powerful environment for developing interactive and content-rich Web pages. ActiveX on the Macintosh retains much of the ActiveX programming model on the Win32 platform and most features; there are, not surprisingly, some important architectural differences.

Mac ActiveX is built on the Component Object Model (COM), a simple object model that provides mechanisms for object instantiation, object querying and object reference counting (a means of controlling object usage & lifetime). COM interfaces allow for flexible object design and are semantically equivalent to Java interfaces (for a definition of COM interfaces, see the beginning of the 'Architectural Overview' section at the end of this article). Macintosh ActiveX is based on a lightweight COM library which has been optimized for in-process controls. These services allow ActiveX controls to work seamlessly within a browser rather than as separate processes.

Other advanced features of Mac ActiveX make the experience of ActiveX controls more seamless than plug-ins. Transparent download, for example, permits a control to be downloaded, installed, and activated in a Web page without requiring the browser to be restarted or that the user go through any installation procedure.

This article presents a general architectural overview of Mac ActiveX and a detailed description of its software development kit. The last half discusses the mechanics of building and running ActiveX controls and details a simple modification of an SDK sample in order to create a new, custom control. Much of the information here appears in two essential SDK documents, the ActiveX User's Guide and ActiveX Technical Guide. There are pointers to additional SDK documents and other references where topics to which I refer are beyond the scope of this article. I've included definitions of some important, basic terms and concepts as they appear for anyone who might be encountering them for the first time.

The final section of the article contains important information on obtaining technical support from Microsoft for developing ActiveX controls on the Macintosh.

ActiveX and Java

ActiveX and Java are complementary, not competing technologies. First and foremost, Java is a programming language. Second, Java is a set of virtual machine bytecodes that can be executed on any platform running a Java Virtual Machine (VM). Third, Java is a set of programming interfaces that define the underlying services available from Java code.

ActiveX, on the other hand, provides a totally different set of benefits focused on integrating objects created in Metrowerks' CodeWarrior environment with Web pages. ActiveX controls are native Mac applications and can be written using any of the rich MacOS services available through C or C++ interfaces.

ActiveX, OLE, and COM

ActiveX and OLE for Macintosh are both built on the powerful foundation of the Component Object Model. The 2.0x version of OLE was a monolithic release which incorporated COM and the OLE libraries in a single shared library (for PowerMac) or 68k Extension. The latest version of OLE has been broken out into constituent libraries which contain related functionality, one of which is the Microsoft Component Library which supports Mac ActiveX controls. This factored version of COM/OLE interacts more efficiently with Apple's Code Fragment Manager, performance is improved and less code is mapped into memory on launching an OLE application.

The latest version of COM, included in the Mac ActiveX SDK, has been optimized for lightweight, high-performance, in-process objects such as ActiveX controls. New API's make it easier for applications or controls to exploit the Alias Manager and work within the Mac-specific runtime world to deliver compelling Macintosh solutions. ActiveX controls require the use of the new Microsoft Component Library and are not compatible with OLE 2.0x.

SDK Contents Overview

The ActiveX SDK for Macintosh consists of three separate, downloadable archives available at: http://www.microsoft.com/intdev/sdk/mac/mactivex.html

ActiveX SDK (SDK_sea.hqx, ~2.5 MB) -- SDK, including sample controls and containers, projects, source, headers, COM libraries, and ActiveX plug-in adapter.

ActiveX Runtime (Runtime_sea.hqx, ~6000k) -- binary files needed to run ActiveX controls in commercial containers such as Internet Explorer and Netscape Navigator. (Note: this archive contains the 'MS IE ActiveX Lib (PPC)' library required to use ActiveX controls in versions of Internet Explorer later than 3.0b1. If you are using 3.0b1 or earlier, the ActiveX SDK archive listed above contains all the runtime binaries required and you can skip this download.)

ActiveX Documents (Documents_sea.hqx, ~600k) -- documentation describing how to create and run ActiveX controls on Macintosh. It contains the ActiveX User & Technical Guides, as well as documents covering more advanced ActiveX topics such as asynchronous monikers and code download. This archive also includes an introduction to COM and a Component Object Model technical overview/specification.

Note that the Beta3 release of the Mac ActiveX SDK is currently being finalized and will be available by the time this article is printed. Beta3 will be fully compatible with Metrowerks CodeWarrior 11. There will be a document in the SDK correcting any information presented here which needs revision in order to build and run the Beta3 samples. The Beta2 release is fully compatible with Metrowerks CodeWarrior 10.

The ActiveX for Macintosh SDK

General Overview

The ActiveX SDK for Macintosh includes:

  1. Microsoft Component Library & ActiveX Plugin.
  2. Sample Controls.
  3. Sample Containers.
  4. Source, headers, GUIDs, and other supporting files.
  5. Utilities.

The Microsoft Component Library includes the most important elements of the Component Object Model, managing object instantiation, the Registry and essential COM structures. This library can be used to build other, custom interfaces. The ActiveX interfaces are built on this library and do not require the OLE 2.0x libraries. The ActiveX Plug-in permits the use of ActiveX controls in browsers that support Netscape Navigator-compatible plug-in technology.

The Microsoft Component Library was named comi2.ppc.ret in previous beta releases of the Mac ActiveX SDK. You should throw away any copies of this file which exist on your system before using the latest version of the SDK.

The SDK Sample Controls include samples demonstrating basic features of Mac ActiveX controls including property retrieval, data streaming, event handling, drawing, popup menus, dialogs, outgoing custom interfaces, and more. These samples have been designed to easily serve as the basis for writing your own controls. Metrowerks CodeWarrior version 10 or later is required for building all Macintosh ActiveX controls.

The Mac ActiveX SDK ships with several Sample Containers which provide a simple environment for testing individual controls, including a Metrowerks PowerPlant-based container that extends PowerPlant document and view classes to host controls.

SDK Utilities include tools for managing the COM Registration Database, registering and unregistering controls, GUID creation, bin-hexing, and more.

More SDK Details

Folders in the SDK include

*QuickStart*        Documents and tools for getting started in ActiveX right away
COM Libraries       Debug and retail versions of Mac COM
Common              Files used to build ActiveX controls and containers
Container Common    Files used to build more than one sample container 
Containers          Sample ActiveX containers (including Netscape plug-in)
Control Common      Files used to build more than one sample control
External Libraries  Shared libraries used by ActiveX controls
Guids               COM globally unique identifier (GUID) definitions
Headers             ActiveX system header files
Sample Controls     Source code and HTML for samples (see preceding section)
UrlMon              Support for COM URL Moniker interface
Utilities           ActiveX utilities

SDK Utilities

The Utilities folder contains these utility programs:

AutoBin            Automatically generates binhexed versions of controls
Create GUID        Generates GUIDs for interfaces and controls
DeScoder           Decodes COM error values      
RegEdit            Edits the COM Registry ('PPC Registration Database')
Register           Adds/removes a control from the registration database

When a control is created for the first time, it must be binhexed so that the automatic code download feature will download it, decode it (un-binhex it), and register it in the COM Registry. AutoBin is a drag-drop utility which is used to create binhexed versions of controls.

New controls need a globally unique identifier (GUID) defined in their local register.h. Use the CreateGUID utility to generate a unique ID and copy it into the register.h file. Also, don't forget to copy this string into the HTML file that runs your control.

GUIDs (globally unique identifiers), are 128-bit values used to identify COM/ActiveX interfaces and object classes (something like an application Creator code identifies an application, only in 16 bytes, not 4). IIDs are interface identifiers, a type of GUID which specifically identify interfaces. IIDs are used typically when requesting an instance of an interface implementation. CLSIDs, or class identifiers, identify object classes. CLSIDs associate objects with particular ActiveX controls.

DeScoder is a simple utility which returns human-readable strings from error values returned by COM/ActiveX API and methods. Typing in a value of 0x80030002, for example, returns the more descriptive error label 'STG_E_FILENOTFOUND'.

If you have to edit the COM registry (named 'PPC Registration Database' inside System:Preferences) directly, use the RegEdit utility. This program displays the contents of the current COM registry and allows you to edit, add, and remove keys. Removing keys of outdated controls is the most common use of this utility. However, the Register utility program can do that for you as well.

The Register utility provides a simple means of adding or removing control registry information from the Registration Database. In actual use, a control will be registered as part of its code download and installation process. The Register utility is more useful for removing outdated control information before testing a new version of it. To use Register, shift-drag the shared library of the control you want to unregister onto the Register application. The COM libraries must to be either in a common system location, such as the Extensions folder, or in the same folder as the control being unregistered.

Getting Started

Follow these steps to familiarize yourself with the contents of the Mac ActiveX SDK:

  1. Install the runtime files required for your browser.,
  2. Build the ActiveX SDK samples.
  3. Run the sample controls.
  4. Study the sample control source code (and the ActiveX Technical Guide).
  5. Modify a sample control in order to create your own.
  6. Build and run your own control.

The rest of this article provides more detail on accomplishing each of these steps.

Install the Runtime Files

Mac ActiveX controls can be viewed in several different containers and browsers. Commercial containers include Microsoft Internet Explorer 2.1 or later, Netscape Navigator 2.0 or later. To run controls in Internet Explorer 3.0b1 or earlier, Navigator, or Cyberdog, install the ActiveX Plugin and the Microsoft Component Library. The ActiveX Plugin should be placed in the browser Plug-ins folder; the Microsoft Component Library lives in the System:Extensions folder. An OpenDoc part adapter is currently in development to support ActiveX controls in Cyberdog and should be available soon.

Before using Microsoft Internet Explorer to run Mac ActiveX controls, make sure and do the following:

  1. Run Internet Explorer to create the 'Explorer' folder inside System:Preferences.
  2. If you are using Internet Explorer 3.0 (later than b1), drag MS IE ActiveX Lib (PPC) from the ActiveX Runtime portion of the SDK to System:Extensions.
  3. For Internet Explorer 3.0b1 or earlier, or if using another browser that supports plug-ins, such as CyberDog or Netscape Navigator, drag the ActiveX Plugin to your Plug-ins folder.
  4. Drag the Microsoft Component Library from the ActiveX SDK portion of the SDK to System:Extensions. The 'Build ActiveX SDK' script located at the root of the 'ActiveX SDK' folder will perform steps 2-4.
  5. Choose Edit/Preferences within Internet Explorer, then click the 'Web Content' tab. Make sure 'Use Plug-In Objects' is checked. In Internet Explorer version 2.1, choose Edit/Options, click the 'Web Content' tab, and make sure 'Load Plug-In Objects' is checked.
  6. Restart the computer.

Build the ActiveX SDK Samples

Individual ActiveX sample controls can be built by opening the sample projects with Metrowerks CodeWarrior version 10 or later and compiling. The SDK includes a script labeled 'Build ActiveX SDK' which will configure your system for running ActiveX controls (by copying required shared libraries to the Extensions folder, etc.) and build all samples in the SDK. If there is a problem building any samples during script execution, you can cancel by clicking the process icon in the upper right corner of the Mac monitor, selecting 'Build ActiveX SDK' in order to bring the script to the foreground, and pressing command-period.

Run the sample controls

After configuring your system and building a sample control, running it is simply a matter of dragging the HTML (xxx.htm) file found in the sample control folder onto your particular Web Browser.

Writing Your Own Control

Notes on the SDK Sample Code

CBaseControl.cpp and .h in the Control Common folder contain the source for the ActiveX control base class from which all other controls descend. Each individual control folder contains the files CxxxControl.cpp and .h, which include the source for the subclass. Controls that do data streaming will pull in the CBaseBindStatusCallback class, found in Control Common, in order to receive progress status and data streams.

The ActiveX base classes are provided as a convenience to the developer, providing baseline functionality which speeds control development. Developers are encouraged to use the base classes but are not limited to them -- any semantically equivalent implementation of the interfaces can be used. The Mac ActiveX development team is interested in feedback on the base classes in order to make them better and better. See the end of this article for information on contacting the development team through a Microsoft-provided mailing list.

Register.h in each control's project folder contains the defines for the sample control GUIDs, program IDs, and so on, required for COM registration.

The sample controls override anywhere from 2 to 15 methods of the base control depending on the features desired. For simple controls that have no data or properties, you only have to modify some of the event methods and Draw methods. For properties and data, one or both of the Load methods and possibly the OnStopBinding and OnDataAvailable methods of CBaseBindStatusCallback must be modified. The Clock is the simplest, with no data or properties.

The PictPlayer, MoviePlayer and ListBox all implement data streaming to some degree. PictPlayer is an example of a control that receives data through multiple data streams. Instead of mixing in and subclassing CBaseBindStatusCallback, a separate subclass CPictControlBSC is instantiated for each data stream. The MoviePlayer demonstrates data streaming to a file.

Modify, Build and Run a Sample Control

You can prepare for writing your own control by copying an existing control folder and modifying it. The most basic sample control is the clock, as it supports only event handling and drawing, with no support for properties or data streaming.

Here are the steps:

  1. Rename files as desired.
  2. Modify the event and Draw methods for basic functionality.
  3. Modify the Load, OnStopBinding and/or OnDataAvailable methods as necessary for the level of streaming support you require.
  4. Define an identifier in the prefix file for your control.
  5. Add new GUID and constants for your control within the register.h file.
  6. Build.
  7. Generate a .hqx file from the shared library file of your new control.
  8. Modify the HTML file CODEBASE and DATA arguments to point to your .hqx file for code and any data file you may have.
  9. Modify the HTML file CLASSID argument to the ASCII value of your new CLSID GUID.
  10. Drop your new HTML file onto Internet Explorer.

What could be simpler? If your control runs successfully, you probably did everything right. If not, check to make sure your URLs for CODEBASE and DATA are correct, as well as the ASCII CLASSID. Make sure an entry for your control appears in the Registry. Check the ActiveX Cache in System:Preferences:Explorer to see if your control is there.

SpyClock

This section is a step-by-step example of modifying an SDK sample in order to create a new, custom control. The sample we'll modify is 'Clock', the simplest control in the Mac ActiveX SDK, with no persistent data or properties. We'll instrument this control in order to write debug information tracking calls to various control information out to LRPCSpy, an OLE for Macintosh debugging utility. LRPCSpy is located in the Beta3 SDK Utilities folder. Also, be sure to check out CodeSampler in the SDK 'QuickStart' folder. This tool takes care of much of the work involved in generating a new control based on one of the samples. The detailed information given below is a good way to become familiar with ActiveX controls and the work done by CodeSampler to create new versions of them.

Clock Modifications

  1. Duplicate the 'Clock' sample folder and rename it 'SpyClock'.
  2. Within the SpyClock folder, delete the following files, if they exist: Clock, Clock.hqx, and Clock.xSym.
  3. Rename all file names from *Clock* to *SpyClock*. (clock.acx should be named spyclock.acx, for example, CClockControl.cpp should be CSpyClockControl.cpp).
  4. Drag a copy of CBaseCOM.cpp from the SDK 'Common' folder to the 'SpyClock' folder. Drag a copy of CBaseControl.cpp from the 'Control Common' folder to 'SpyClock'. We will modify both these files later on and don't want the changes to be pulled into other controls.
  5. Open the SpyClock.u project file in Metrowerks CodeWarrior.
  6. Choose 'Add File...' from the Project Menu. Add SpyClock.rsrc and CSpyClockControl.cpp to the project.
  7. Remove references to Clock.rsrc and CClockControl.cpp from the project.
  8. Open CSpyClockControl.cpp and do a Find/Replace All, replacing all references to ClockControl with SpyClockControl.
  9. Repeat step #7 in file CSpyClockControl.h. Save and close the file.
  10. Add the following line to the beginning of CSpyClockControl.cpp: #include "spy.h". (This header will be created in a later step). Save and close the file.
  11. Choose 'Project Settings...' from the CodeWarrior Edit Menu. Select 'PPC Project' in the Project section. Edit the project output file name to SpyClock.
  12. Still within Project Settings, select 'C/C++ Language' in the Language Settings section. Edit the Prefix File name to read SpyClockPrefix.h. Close the Project Settings dialog.
  13. Open register.h. Do a Find/Replace All, replacing all references to Clock with SpyClock.
  14. Switch to the Finder, locate the CreateGuid.ppc utility in the SDK, and launch it. CreateGuid.ppc will automatically generate a new GUID for use in our modified control on startup.
  15. Click the 'DEFINE_GUID' radio button. This changes the representation of the GUID currently displayed to an ActiveX macro statement which will literally construct the 128-bit GUID value in the project on compiling. Click 'Copy' to put this macro statement on the Clipboard.
  16. Back in the CodeWarrior IDE, select the first three lines of register.h and then Paste. This will replace Clock's DEFINE_GUID macro with the new version provided by CreateGuid.ppc. Replace the <<name>> placeholder in the macro statement with the label 'CLSID_ocx' (no apostrophes).
  17. Select the text representation of our new GUID from the commented line at the top of register.h. Select the GUID from the left brace all the way through the right brace, then Edit/Copy or press cmd-C.
  18. Select the remaining instance of Clock's GUID in register.h from brace to brace. Press cmd-V or Edit/Paste to replace it with the new GUID. Save and close register.h.
  19. Open spyclock.acx (still within CodeWarrior), select the old GUID in its entirety, and Paste the new version. Save and close the file.
  20. Open SpyClock.inf, select the old GUID at the end of the file from brace to brace and replace it with the new version. Do a Find/Replace All, replacing all occurrences of Clock with SpyClock. Save and close the file.
  21. Open SpyClock.htm. Replace all occurrences of Clock's GUID in this file with the newly generated GUID. Both GUID instances in this file appear without braces. Be sure to delete the right and left braces from the new GUID after pasting each. Save and close the file.

New Code for SpyClock

Now it's time to generate some new code (at last!). Choose New from CodeWarrior's File menu and save the file as "spy.h" to the SpyClock folder. Type the following into the spy.h, save, and close:

#ifndef _SPY_H_
#define _SPY_H_

#include <string.h>

#define SZ_MAX_LEN   128

void    SpyOutputDebugString   (const char *sz);
Boolean SimpleSendHighLevelEvent( OSType sig, 
                                  OSType eventClass, 
                                  OSType eventID,
                                  unsigned long msgRefCon, 
                                  char *eventBuf, 
                                  unsigned long bufLen);

#endif // !_SPY_H_

Create another file inside CodeWarrior and save this one to disk as "spy.c". Type the following into the "spy.c" window, save, and close:

#include "spy.h"

void SpyOutputDebugString(const char *sz)
{
  long cb;
  char buf[SZ_MAX_LEN];   
  
  cb = strlen(sz);
  if (cb > SZ_MAX_LEN)
    cb = SZ_MAX_LEN;

   BlockMove(sz,buf,cb);
   SimpleSendHighLevelEvent('LSpy','Dbg2','TEXT',0,buf,cb);
}


Boolean SimpleSendHighLevelEvent(OSType sig, 
             OSType eventClass, 
             OSType eventID,
             unsigned long messageRefCon, 
             char *eventBuf, 
             unsigned long bufLen)
{
   EventRecord theHLEvt;
   OSErr err;

   theHLEvt.what = kHighLevelEvent;
   theHLEvt.message = eventClass;
   theHLEvt.where = * (Point *) &eventID;

   err = PostHighLevelEvent(&theHLEvt,
                                  sig,
                                  messageRefCon, 
                                  (Ptr) eventBuf, 
                                  bufLen,
                                  receiverIDisSignature);

   if (-917 == err)
      err = PostHighLevelEvent(&theHLEvt,
                                  sig,
                                  messageRefCon, 
                                  (Ptr) eventBuf, 
                                  bufLen,
                                  receiverIDisSignature);

   if (noErr == err)
      return true;
   else
      return false;
}

Add spy.c to the SpyClock project and we're ready to use the SpyOutputDebugString routine to write output messages to the LRPCSpy utility. SpyOutputDebugString checks the length of the debug string passed to it, does a BlockMove to a local buffer, then passes the latter to SimpleSendHighLevelEvent. SpyOutputDebugString specifies LRPCSpy's creator code 'LRPC' as the target for the high-level event. LRPCSpy supports an event class signified by the id 'Dbg2', 'TEXT' indicates the type of message we're passing.

SimpleSendHighLevelEvent does exactly what its name implies: it creates and sends a simple high-level event. If the first try returns a value of -917 ('session was closed'), it makes a second attempt. Note that SimpleSendHighLevelEvent returns a Boolean to indicate whether or not the event was sent successfully. The implementation of SpyOutputDebugString above does not test for a return value.

Also worth noting is that SpyOutputDebugString could easily be replaced with other functionality. The buffer passed in could be converted to a Pascal string and passed to DebugStr() for example. It could open a text file and write the information to disk. It could also be modified to pass the buffer to another ActiveX control (such as the Console control) for output. The SDK Popup sample actually contains an example of the latter.

Now that SpyOutputDebugString is in place, it's time to instrument the SpyClock sample so that we can track code execution when the control is running. Open CBaseControl.cpp and add a #include of "spy.h" to the beginning of the file. Then add SpyOutputDebugString statements to the beginning of each method implementation in the file. Inside CBaseControl::SetSite, for example, add the following statement at the beginning of the member function:

SpyOutputDebugString
   ("CBaseControl::IObjectWithSite::SetSite\r");

Note that the message passed to our output routine contains a complete reference to the method called, that is, it reflects the specific interface IObjectSite which is wrapped by CBaseControl. These 'complete' function names appear in the comments prefacing each CBaseControl method. Just Copy and Paste to add them to each call to SpyOutputDebugString. After modifying the SpyClock copy of CBaseControl.cpp, open CBaseCOM.cpp and make similar changes to each method implementation in the file. Don't forget to add a #include of "spy.h" before any calls to SpyOutputDebugString. Now it's time to build our new control!

Build, BinHex, and Run!

  1. Build SpyClock within Metrowerks CodeWarrior.
  2. Drag the resultant control labeled 'SpyClock' onto the AutoBin 1.0 utility. This will generate a binhexed representation of the control inside the SpyClock folder named 'SpyClock.hqx'.
  3. Launch LRPCSpy. Be sure to modify LRPCSpy's Preferred memory partition size to at least 512K before running.
  4. Drag SpyClock.htm onto Microsoft Internet Explorer or other supported Web Browser.
After doing so, you should see the SpyClock control appear. A window will appear in LRPCSpy in the background. You should see text messages appear in that window which track various control object methods as they are called.

That's all There is to it!

This detailed control modification example should tell you all you need to know in order to start creating your own ActiveX controls on the Macintosh today. The SDK is filled with interesting, powerful examples to study and serve as a basis for the next generation of content-rich Web development. ActiveX is built on a native Macintosh implementation of COM, which has been broken out of OLE and optimized to support high-performance, lightweight, in-process control objects. Why not get started on your own today, and see what comes next, tomorrow?

For those of you with wind left in your lungs and a desire to dive even deeper into what makes ActiveX tick on the Macintosh platform, read on.

Figure 1. ActiveX for Macintosh Architectural Overview.

The overall ActiveX for Macintosh architecture can be viewed as follows:

An Interface is an array of function pointers known as a virtual table. The functions pointed to by the members of a vtable are called the methods, or member functions, of the interface. In C++ terms, an interface is an abstract base class, composed of pure virtual functions, which specifies a protocol without providing an implementation. Although C++ is extremely convenient for defining interfaces -- because C++ builds the vtable for you -- interfaces can be defined, implemented and used in any language.

An ActiveX/COM interface defines a contract between any object which implements the interface and any client which makes use of it. This contract includes the name of the interface and its methods, the parameter types, and the purpose of each member function. An object must implement all methods in an interface and adhere to the defined protocol (or intent) of each routine. By convention, interface names follow an IXXXXX format -- IControl and Iunknown, for example.

As shown in the figure above, applications implement an IContainer interface to host ActiveX controls. The IContainer interface can be implemented for each container of controls within the application, or potentially for the application itself. Typically, an implementation of this interface would be instantiated for each document of an application that hosts controls. This interface would also be implemented by controls that will host other controls.

A control site is an object in the application that is instantiated for each control. The control site implements interfaces needed by the application and the control hosted by the site. The control site object generally exposes a Control Site API to the client application to enable creation and destruction of the control site. The control site may optionally expose an IControl interface on the site object, used by the client application once the control has been created. Alternatively, the control site may simply return the IControl interface of the hosted control to allow more direct communication.

IUnknown is the base COM interface from which all other ActiveX interfaces are derived. It defines methods for three member functions: QueryInterface, AddRef, and Release. QueryInterface provides the basic COM mechanism for interface negotiation (retrieval of pointers to specific interfaces). AddRef and Release comprise COM reference counting, a mechanism for controlling object lifetime which allows independent objects to obtain and release pointers to the same object without coordination.

The IUnknown interface is the only required interface for all COM objects. IUnknown is fully documented in numerous other sources, including two documents in the Mac ActiveX SDK, COM Introduction and COM Technical Overview.

A control site object exposes at least an IUnknown interface and IContainerSite interface to the hosted control. Other interfaces are acquired by querying the IUnknown interface of the site or through the IServiceProvider interface. A typical control site object design appears as follows.

Figure 2.

Sites connect to controls by passing a pointer to their IUnknown interface to the control. Controls will typically immediately query the site for the IContainerSite interface, which will become the primary callback interface.

Communication to the control can occur through any number of interfaces, the most basic being the IControl interface. The IControl interface allows the control to receive calls such as events, focus notifications, activation notifications, and drawing. If a control has no persistent data or properties, this is all that must be implemented. Other optional interfaces shown in the Control object reference the IPersist*** (for example, IPersistStream or IPersistPropertyBag) and IBindStatusCallback interfaces that must be exposed for persistent properties and data streaming operations, respectively. A typical control object design is shown here.

Figure 3.

Writing ActiveX Controls

The mechanics of building ActiveX controls are documented later in this article as well as the SDK ActiveX User's Guide. With this information, it is possible to use base classes provided in the SDK to build controls by overriding a few methods. This section documents in more detail the interfaces that can be implemented by control writers.

An ActiveX control must implement some or all of the following interfaces:

IUnknown                COM query and reference counting
IObjectWithSite         Access to Control Site through generic siting
IControl                Basic Control Methods
IPersist***             Persistent properties and data
IBindStatusCallback     Data Streaming Notification

A control that has no persistent properties and has no need to retrieve data from a URL can choose to implement only the IUnknown, IObjectWithSite, and IControl interfaces. Controls that have persistent properties must implement one or more IPersist interfaces. Controls that must stream data to and from the Internet must implement the Data Streaming notification interface, IBindStatusCallback. For many of these interfaces, the Macintosh ActiveX SDK provides default implementations so that many controls only need to override a few methods to get baseline functionality.

Macintosh ActiveX controls must implement the IObjectWithSite interface to get access to the control site. Since the control site either implements or delegates important functionality from the outside world, this interface is very important. IObjectWithSite is documented in detail in the document, Internet Controls. The interface is defined as follows:

interface IObjectWithSite
{ 
   AXErrorCode SetSite ( [in] IUnknown* Site );
   AXErrorCode GetSite ( [in] REFIID RefID, [out] IUnknown**             Site );
};

IObjectWithSite::SetSite simply gives the control an IUnknown interface to use for obtaining other interfaces on the site as shown above in the control site diagram. IObjectWithSite::GetSite returns the site that is currently set on the control. As shown in the above interface, Macintosh ActiveX controls return an AXErrorCode which is synonymous with the HRESULT type defined earlier for OLE2.

With these two interfaces it is theoretically possible to write a minimally functional ActiveX control. Of course, the control would have no UI and could not handle events. But it could use the site to get properties and stream data. In order to write a truly useful control that has UI and participates more completely in the life of the container, the IControl interface must be implemented. This important interface is covered in detail in the ActiveX Technical Guide.

Controls that support persistent properties and/or data must implement one or more persistence interfaces. These include IPersistMoniker, IPersistStream, IPersistStorage, IPersistMemory and IPersistPropertyBag. Of these, IPersistPropertyBag is the recommended interface for retrieving properties that are specified either on the command line or in a URL for a run-time control. IPersistStream will become more important as HTML authoring environments that support ActiveX controls become available.

ActiveX sites will call the control's IPersistPropertyBag::Load() method with an IPropertyBag interface so that the control can retrieve persistent properties. When the control receives this call it can use the IPropertyBag interface given to read the persistent properties.

Full documentation of the IPersist*** interfaces is available from many other sources and is beyond the scope of the SDK documentation. ActiveX for Macintosh uses these interfaces as specified in other sources. References include:

  • Understanding ActiveX and OLE by David Chappell.
  • ActiveX Controls Inside Out by Adam Denning.
  • Inside OLE Second Edition by Kraig Brockschmidt.
  • Internet Controls (from the ActiveX SDK).

In order to get data across the Internet that is not retrieved as a simple property from a property bag interface, controls must support data streaming interfaces as documented in the URL Moniker and Asynchronous Moniker. The control must implement only the IBindStatusCallback interface for notifications such as progress, data available, and stop binding. In particular, the control must implement the IBindStatusCallback::OnDataAvailable() method for notification whenever new data is available from the net.

The URL Moniker interfaces support both a push and pull model of data streaming as well as file streaming. More information on how ActiveX for Macintosh uses these interfaces can be located in the following SDK documents.

  • URL Monikers.
  • Asynchronous Moniker Specification.

Microsoft Technical Support

Paid Support for the ActiveX for Macintosh SDK

The Macintosh ActiveX SDK is supported by Microsoft Technical Support. You can ask questions through your Premier Level support contract. You can also ask questions through your Priority Level contract or purchase individual Priority Support incidents (essentially a one-time fee for a single issue or problem). If you would like more information on Microsoft's paid support options, call Microsoft Support Sales at (800) 936-3500 from 6:00 a.m. to 6:00 p.m. Pacific time, Monday through Friday, excluding holidays. Microsoft Technical Support is also available on the World Wide Web at http://www.microsoft.com/support/.

Free support for the ActiveX for Macintosh SDK

Newsgroups are a great place for free peer support. As time and resources allow, Microsoft developers, program managers, support engineers, and test engineers visit the site to collect feedback and answer specific questions or correct misinterpretations. Microsoft's participation largely depends on bandwidth and time, which is greatly affected by shipping schedules. Some interesting news groups for Internet Explorer are on microsoft.internetexplorer.

To access newsgroups, use your preferred newsgroup reader and enter the news server address as news://msnews.microsoft.com. You can use the following URL to access the newsgroup directly from a Web browser: news.microsoft.public.newsgroup-name. The newsreader included with Internet Explorer version 3.0 supports multiple news servers; you can download the newsreader from http://www.microsoft.com/ie/ie3/imn.htm.

The Internet Explorer for Macintosh team maintains a site of known issues affecting the current release at: http://www.microsoft.com/iesupport/content/issues/.

Developers working with the ActiveX for Macintosh SDK can subscribe to a mailing list to receive support and ask questions. To subscribe, send e-mail to mactivex-dev@ws63.psdbay.xo.com, using a subject line of "subscribe". For detailed information on other mailing lists covering Microsoft Internet technologies, visit the Mailing Lists page on this Web site.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

A Better Finder Rename 11.25 - File, pho...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
X Lossless Decoder 20201123 - Encode, tr...
X Lossless Decoder(XLD) is a tool for Mac OS X that is able to decode/convert/play various 'lossless' audio files. The supported audio files can be split into some tracks with cue sheet when decoding... Read more
Blackmagic Disk Speed Test 3.3 - Measure...
Blackmagic Disk Speed Test is an easy to use tool to quickly measure and certify your disk performance for working with high quality video! Simply click the start button and Disk Speed Test will... Read more
FotoMagico 5.6.14 - Powerful slideshow c...
FotoMagico lets you create professional slideshows from your photos and music with just a few, simple mouse clicks. It sports a very clean and intuitive yet powerful user interface. High image... Read more
calibre 5.6.0 - Complete e-book library...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital librarian... Read more
VOX 3.3.18 - Music player that supports...
VOX just sounds better! The beauty is in its simplicity, yet behind the minimal exterior lies a powerful music player with a ton of features and support for all audio formats you should ever need.... Read more
Apple Safari 14.0.1 - Apple's Web b...
Apple Safari is Apple's web browser that comes bundled with the most recent macOS. Safari is faster and more energy efficient than other browsers, so sites are more responsive and your notebook... Read more
MenuMeters 2.1.1 - CPU, memory, disk, an...
MenuMeters is a set of CPU, memory, disk, and network monitoring tools for Mac OS X. Although there are numerous other programs which do the same thing, none had quite the feature set I was looking... Read more
iTubeDownloader 6.5.26 - Easily download...
iTubeDownloader is a powerful-yet-simple YouTube downloader for the masses. Because it contains a proprietary browser, you can browse YouTube like you normally would. When you see something you want... Read more
Little Snitch 5.0.3 - Alerts you about o...
Little Snitch gives you control over your private outgoing data. Track background activity As soon as your computer connects to the Internet, applications often have permission to send any... Read more

Latest Forum Discussions

See All

LifeAfter’s Resident Evil crossover has...
LifeAfter’s Resident Evil crossover event is back for phase two after it successfully held an earlier collaboration earlier this year in August. [Read more] | Read more »
Street Kart Racing will hold a Virtual S...
Street Kart Racing has teamed up with SKUSA to launch the Virtual Supernats, “Virtual Las Vegas” following the real-world event being cancelled due to Covid. The live in-game event starts on November 29th and will last for six days. During this... | Read more »
Puppoz is a cutesy balloon popping game...
Puppoz is a new, cutesy action game from developer Superstar Games that sees a bunch of canines darting about different levels popping balloons. It's a free game that you can download now for both iOS and Android devices. [Read more] | Read more »
Lara Croft returns in Tomb Raider Reload...
Square Enix has unveiled the next entry in the Tomb Raider series, this time headed for mobile platforms sometime in 2021. [Read more] | Read more »
Genshin Impact - Fallen Star Challenge G...
| Read more »
New update for The Battle of Polytopia p...
The Battle of Polytopia released on PC back in August of this year with iOS and Android versions being dated too far behind. But now developer Midjiwan AB has released the Moonrise update to put it on the same level as its PC counterpart, bringing... | Read more »
Transport City: Truck Tycoon is a logist...
Transport City: Truck Tycoon is a brand new simulation game from developer Cupgum that's available now for iOS and Android. As you can probably guess from the name of the game it'll see you working on building a supply chain and logistics setup... | Read more »
Bridge Constructor: The Walking Dead is...
Headup Games' team up with their popular bridge-building franchise and AMC's zombie TV is now available for iOS and Android. Bridge Constructor: The Walking Dead is the latest game in the series and the second to make use of another IP after... | Read more »
Genshin Impact - How to Beat Tartaglia (...
In the 1.1 update to Genshin Impact, the final chapter to the story arc in Liyue reaches its climax with a fight against Tartaglia (AKA Childe), one of the Fatui Harbingers. We won't go into detail as to why this is or the circumstances of the... | Read more »
Genshin Impact - Unreconciled Stars Even...
Genshin Impact's 1.1 update has brought a ton of new content to the game, and one of these things is a brand new event: Unreconciled Stars. This event kicked off yesterday and is running through the end of the month. There are sweet rewards and... | Read more »

Price Scanner via MacPrices.net

Cyber Monday MacBook sale: B&H has 13″ In...
B&H Photo has 2020 13″ Intel Dual-Core MacBook Airs on sale today for $200 off Apple’s original MSRP, only $799, as part of their Cyber Monday 2020 sale. Expedited shipping is free to many... Read more
Cyber Monday on Woot: Open-box 16″ MacBook Pr...
Amazon-owned Woot has Apple open-box return 16″ MacBook Pros available today for $550 off the cost of new models as part of their Cyber Monday 2020 sale. Shipping is free for Prime members: – 16″ 6-... Read more
Cyber Monday sale: 27″ 5K 6-core iMac for $15...
Amazon has Apple’s 2020 27″ 5K 3.1GHz 6-Core iMac on sale for $250 off MSRP today as part of their Cyber Monday 2020 sale. Their price reflects an extra $150 instant discount reflected in your Amazon... Read more
Cyber Monday 2020 sale: Get Apple’s hot new M...
Apple reseller B&H Photo has Apple’s new Mac minis with M1 Apple Silicon CPUs on sale starting at only $639 as part of their Cyber Monday 2020 sale. These are the lowest prices we’ve seen so far... Read more
Apple’s New Ship-From-Store Model May Leave I...
FEATURE: 11.30.20 –With the holidays upon us, the mad rush to get our holiday gift shopping done has begun, however, after the Cyber Monday buying blitz is over, you still may want to let your... Read more
Shop at Apple’s online store on Cyber Monday,...
Apple’s Cyber Monday 2020 event is now live and runs through Monday night. Receive a free $150 Apple Store gift card with the purchase of select Macs and $50-$100 with various iPads. Get a $50 Apple... Read more
B&H launches Cyber Monday 2020 sale: Take...
Apple’s new 2020 13″ MacBook Airs with M1 Apple Silicon CPUs are now on sale at B&H Photo for $100-$110 off MSRP, starting at $999, as part of their Cyber Monday 2020 sales event. Free expedited... Read more
B&H launches Cyber Monday Apple iPad Air...
B&H Photo has new 2020 10.9″ Apple iPad Airs in stock and on sale today for up to $50 off MSRP as part of their Cyber Monday 2020 sale. Many configurations are in stock today, and expedited... Read more
B&H Cyber Monday 2020 sale: $400 off Appl...
B&H Photo has 16″ MacBook Pros on sale today for $300-$400 off Apple’s MSRP, starting at $2099, as part of their Cyber Monday 2020 sale. Expedited shipping is free to many addresses in the US.... Read more
Cyber Monday clearance Apple sale: 2020 13″ 1...
Apple reseller B&H Photo has clearance 2020 13″ 1.4GHz Intel-based MacBook Pros on sale today for $1099, $200 off Apple’s original MSRP, as part of their Cyber Monday 2020 sale. Expedited... Read more

Jobs Board

Branch Relationship Banker I - *Apple* Ave...
Description Apple Ave Branch - Muskegon, MI - The Relationship Banker is a Financial Concierge for our walk in customers. You are responsible for building customer Read more
Solutions Partner Marketing Specialist, *App...
Solutions Partner Marketing Specialist, Apple Tempe, AZ, US Requisition Number:79115 As aSolutions Partner Marketing Specialistfor Apple at Insight, you will be Read more
Senior Data Engineer - *Apple* - Theorem, L...
Job Summary Apple is seeking an experienced, detail-minded data engineeringconsultant to join our worldwide business development and strategy team. If you are Read more
Cub Foods - *Apple* Valley - Now Hiring Par...
Cub Foods - Apple Valley - Now Hiring Part Time! United States of America, Minnesota, Apple Valley Retail Post Date Nov 18, 2020 Requisition # 124800 Sign Up for Read more
*Apple* Test Engineer - Vectrus (United Stat...
Overview The Apple Test Engineer (TE) works as part of a team to perform the integration, packaging, testing, and trobleshooting of applications/changes delivered to Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.