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.
 
AAPL
$100.53
Apple Inc.
+1.37
MSFT
$45.33
Microsoft Corpora
+0.22
GOOG
$586.86
Google Inc.
+4.70

MacTech Search:
Community Search:

Software Updates via MacUpdate

Chromium 36.0.1985.143 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. FreeSMUG-Free OpenSource Mac User Group build is... Read more
Macgo Blu-ray Player 2.10.6.1691 - Blu-r...
Macgo Mac Blu-ray Player can bring you the most unforgettable Blu-ray experience on your Mac. Overview Macgo Mac Blu-ray Player can satisfy just about every need you could possibly have in a Blu-ray... Read more
Apple Motion 5.1.2 - Create and customiz...
Apple Motion is designed for video editors, Motion 5 lets you customize Final Cut Pro titles, transitions, and effects. Or create your own dazzling animations in 2D or 3D space, with real-time... Read more
A Better Finder Rename 9.39 - File, phot...
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
PopChar X 6.6 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more
MacUpdate Desktop 6.0.2 - Install Mac ap...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
PDFpenPro 6.3.2 - Advanced PDF toolkit f...
PDFpenPro allows users to edit PDF's easily. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Create... Read more
PDFpen 6.3.2 - Edit and annotate PDFs wi...
PDFpen allows users to easily edit PDF's. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Features... Read more
OS X Yosemite 10.10 DP6 - Developer Prev...
Note: This is a Developer Preview. You must be a registered Apple Mac Developer to download this update. You can also sign up for the free OS X Beta Program to download and preview public beta... Read more
Flavours 1.1.15 - Create and apply theme...
Flavours is a Mac application that allow users to create, apply and share beautifully designed themes. Classy Give your Mac a gorgeous new look by applying delicious themes! Easy Unleash your... Read more

Latest Forum Discussions

See All

Go to Bed – An Interview With Touchfight...
Touchfight Games is an exciting new indie studio that was co-formed between game journalist and author Nathan Meunier, artist Leonard Kenyon, and programmer Jon Kenyon. Their debut game Go To Bed will be released this fall, and with all the... | Read more »
Assault Vector Review
Assault Vector Review By Rob Thomas on August 19th, 2014 Our Rating: :: SIMPLE STRATEGYUniversal App - Designed for iPhone and iPad While this hex-based warp ride is fine in theory, Assault Vector is a bit too simple to be... | Read more »
Tom Hanks’ Hanx Writer has Taken the App...
Tom Hanks’ Hanx Writer has Taken the App Store by Storm Posted by Jessica Fisher on August 19th, 2014 [ permalink ] iPad Only App - Designed for the iPad | Read more »
It Came from Canada: Galaxy Dash
With its use of well-established tropes like endless flying and sci-fi space shooting, the upcoming Galaxy Dash: Race to the Outer Run most likely won’t confound expectations. However, with its robust amount of opportunities for fun player... | Read more »
PromptSmart Review
PromptSmart Review By Jennifer Allen on August 19th, 2014 Our Rating: :: SNAPPY SPEECHGIVINGUniversal App - Designed for iPhone and iPad Offering you a teleprompter in your pocket, PromptSmart is immensely helpful for those who do... | Read more »
The Firm (Games)
The Firm 1 Device: iOS iPhone Category: Games Price: $.99, Version: 1 (iTunes) Description: RELEASE SPECIAL SALE 50%! Welcome to THE FIRM, Your profil retained our full consideration and we have the pleasure to inform you that your... | Read more »
They Need To Be Fed 3 (Games)
They Need To Be Fed 3 1.0.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0.0 (iTunes) Description: 360 degree gravity platforming is back! Run, jump, collect, avoid enemies and feed yourself to the monster at the... | Read more »
Who Wore it Best? Phantom Flower vs. And...
Who Wore it Best? takes a break from all the bloodshed to check out two decidedly tranquil and nature-loving puzzles games: Phantom Flower and And Then it Rained. [ Who Wore it Best? Phantom Flower vs. And Then it Rained is a post from... | Read more »
Sentinel 4: Dark Star Review
Sentinel 4: Dark Star Review By Jennifer Allen on August 19th, 2014 Our Rating: :: STURDY TOWER DEFENSEUniversal App - Designed for iPhone and iPad After 4 years, the latest entry to the Sentinel series is here. It’s not quite as... | Read more »
TrashEver2 - You can move your selected...
TrashEver2 - You can move your selected notes to trash box. 1.0.0 Device: iOS Universal Category: Productivity Price: $.99, Version: 1.0.0 (iTunes) Description: TrashEver is an application only for throwing away the note of Evernote... | Read more »

Price Scanner via MacPrices.net

Razer Taipan Mouse For Gamers And Non-Gamers...
If you’re a serious gamer on either Mac or Windows PCs, a serious gaming mouse is a necessity for first-tier performance. However, even if like me you’re not much of a gamer, there’s still a strong... Read more
15-inch 2.2GHz MacBook Pro on sale for $1899,...
Adorama has the new 15″ 2.2GHz Retina MacBook Pro on sale for $1899 including free shipping plus NY & NJ sales tax only. Their price is $100 off MSRP, and it’s the lowest price available for this... Read more
Mid-Size Tablet Shootout Posted: iPad mini wi...
I ‘m curious about how many iPads Apple is actually selling these days. It’s been widely rumored and anticipated that new models with A8 SoCs, 2 GB of RAM, 8 megapixel cameras, and fingerprint... Read more
The 15 Biggest iPad Air Problems And How To A...
What’s this? Fifteen “biggest” problems with the iPad Air? Does that mean there are a lot of smaller problems as well? Say it isn’t so! My old iPad 2 has manifested no hardware problems in three... Read more
TYLT Syncable-Duo, 2-in-1 USB Cable With Appl...
TYLT has introduced the Syncable-Duo, a universal cable solution for charging and syncing data to smartphones and tablets. The Syncable-Duo eliminates the need for multiple cables by incorporating... Read more
Save up to $140 off MSRP with Apple refurbish...
Apple is offering Certified Refurbished iPad Airs for up to $140 off MSRP. Apple’s one-year warranty is included with each model, and shipping is free. Stock tends to come and go with some of these... Read more
2.5GHz Mac mini on sale for $549, save $50
B&H Photo has the 2.5GHz Mac mini on sale for $549.99 including free shipping. That’s $50 off MSRP, and B&H will also include a free copy of Parallels Desktop software. NY sales tax only. Read more
Chromebooks Are Actually Sometimes A Better C...
Mac360′s Kate MacKenzie notes that when Steve Jobs announced the post-PC era, he was assuming that the dominant post-PC device would be the iPad he was unveiling, or another Apple product like the... Read more
Files-Finder Edition 1.0 app Brings Finder/Ex...
Appsicum’s Files Finder App is designed for iPad users who miss the functionality of the OS X Finder and Windows’ Explorer on their tablet. Files-Finder Edition App is a complete tool having rich... Read more
Apple and Samsung Both Face Growth Declines I...
As the tablet PC market matures and growth slows, the dominance of market leaders Apple and Samsung is also weakening, according to the latest NPD DisplaySearch Monthly Tablet PC Panel Shipment... Read more

Jobs Board

Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** As businesses discover the power of Apple computers and mobile devices, it's your job - as a Solutions Engineer - to show them how to introduce these Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** As more and more people discover Apple , they visit our stores seeking ways to incorporate our products into their lives. It's your job, as a Store Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** Being a Business Manager at an Apple Store means you're the catalyst for businesses to discover and leverage the power, ease, and flexibility of Apple Read more
Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.