Framework Overview
It is helpful to review the two component frameworks, ActiveX controls and Netscape plug-ins, to note their similarities and differences and evaluate what is needed to create a functional design.
Netscape Plug-ins
Netscape plug-ins were among the first component frameworks to be used in Web development. On the Microsoft Windows platform, plug-ins are constructed as standard Win32 dynamic-link libraries (DLLs) that rely on a series of predefined entry points to expose functionality. They are given a window handle (HWND) by their container, which they then subclass to receive user interaction and operating system notifications through Windows messages.
ActiveX Controls
ActiveX controls are lightweight, reusable Component Object Model (COM) components. They are given a site (in the form of a COM interface pointer) by their container, and they use COM methods and interfaces to communicate with the container. ActiveX controls are smaller, simplified versions of object linking and embedding (OLE) controls (as defined by the OLE Controls 96 specification). ActiveX controls do not necessarily have an HWND; they can be windowless, in which case their container forwards them the information that is normally conveyed through Windows messages.
Design Guidelines
Basically, a Netscape plug-in that hosts ActiveX controls must provide a way to translate the information and requests that are relayed as Windows messages into COM method calls.
The single most important (and difficult) task for the plug-in developer is to implement all of the COM interfaces that are required for an ActiveX control container. The following interfaces are implemented in a standard ActiveX control container:
- IOleInPlaceFrame
- IOleInPlaceUIWindow
- IOleInPlaceSite
- IOleClientSite
- IAdviseSink
- IOleControlSite
- IDispatch
- IPropertyNotifySink
If the plug-in is designed to host only one ActiveX control whose behavior you control, you may omit (or only partially implement) some of these interfaces. However, if the plug-in is designed to be a general purpose control container, it is critical that you implement these interfaces fully and correctly to allow maximum interoperability between the plug-in and the ActiveX controls that it hosts.
After you implement all of the required COM interfaces, the plug-in instantiates the control as any other container does: it initializes the COM Library through the
OleInitialize function and creates an instance of the control (through
CoCreateInstance,
CoGetClassObject, and so on). When the plug-in ends, it also destroys the control instance and uninitializes the COM Library.
Potential Problems
Because this is such a complex design, you may encounter several problems:
- Internet Explorer provides a rich set of COM interfaces, the IHTML* interfaces, to programmatically manipulate the Document Object Model (DOM) of the current HTML page. Many ActiveX controls take advantage of this functionality to interact with the page on which they are hosted. Other browsers may not provide this functionality; as a result, the control may generate errors.
- Similarly, Internet Explorer exposes the IWebBrowser2 COM interface through which ActiveX controls can interact with it programmatically. This interface may not be present on other browsers; as a result, the control cannot access this functionality.
- Internet Explorer allows script code on an HTML page to communicate with an ActiveX control on the page. To do this, Internet Explorer translates script calls that are made to the <OBJECT> tag that hosts the control into IDispatch calls (such as GetIDsOfNames and Invoke) that are delegated to the control. Although other browsers may use the plug-in as an intermediary to achieve a similar functionality, the browser must somehow notify the plug-in of a script call. This functionality is obviously not guaranteed.