Skip to main content.

Web Based Programming Tutorials

Homepage | Forum - Join the forum to discuss anything related to programming! | Programming Resources

Web Programming Desktop Reference 6in1

Chapter 29 -- Overview of ActiveX

Chapter 29

Overview of ActiveX


CONTENTS




ActiveX is not a single technological thing. If you've browsed Microsoft's Web site (http://www.microsoft.com) you've probably gathered that ActiveX is a centerpiece of Microsoft's overall Internet strategy. ActiveX helps application developers and Web content authors build dynamic Internet tools, content, and sites. That's a pretty tall order.

To achieve this design goal, Microsoft needed to bring together a number of different components. When you're first introduced to a bunch of new items, it's often hard to assimilate all the pieces of information into an overall picture. (The old forest versus the trees problem.) So this chapter will take you through a quick tour of all the major components of ActiveX so that as we slice into the gory details, you won't lose sight of the overall ActiveX design.

ActiveX Controls for the Internet

As the content you consume from the Internet becomes more and more dynamic, the Web browser will be managing more and more of the computing tasks required to render that content. Much has been made of the executable content model for Web content. Sun Microsystem's Java takes early honors in the race for the development standard for executable content. Many Web sites employ simple multimedia widgets provided by Java, such as the Animator class.

Note
You can find a wealth of information about Java and many of the freely available classes for Web page developers at http://java.sun.com or http://www.gamelan.com.

Netscape helped to push Java into prominence by releasing Navigator 2.0 with support for Java applets. Java provides Web developers a highly sophisticated tool set for interacting with the user and the client machine. Microsoft, not to be outdone, announced support for Java in MSIE 3.0 and a new alternative called ActiveX Controls. ActiveX Controls are based upon the OLE 2.0 standard. ActiveX Controls are to Web pages what the VBX and OCX are to MS-Windows GUI development.

You'll use ActiveX Controls in many of the places you're using Java applets today. ActiveX Controls have several advantages over Java applets, which include the following:

Let's take a brief look at each of these advantages.

Built Using Tools You Already Know

Java requires that you learn an entire new language. Although Java and C++ have syntactic similarities, Java requires that you learn a whole new set of class hierarchies. (Of course, Java saves you from being engulfed in the search for "a pointer from hell" as in C++.) When you consider all the methods and properties that you must learn to be proficient, it's quite an undertaking. But, on the other hand, if you've been using C++ and constructed an OCX, then you already know most of the basic concepts. Unfortunately, ActiveX Controls are not constructed using Microsoft Foundation Classes. Instead, Microsoft has made the ActiveX Template Library (ATL) available to help developers build ActiveX Controls.

Integration with Applications

Because ActiveX Controls are based upon the OLE 2.0 specification, the potential for ActiveX Controls to interact with other applications like word processing, spreadsheets, and presentations opens many possibilities. Although stand-alone applications can be constructed using Java, Java does not really offer the same potential interaction with other existing applications yet.

Employing Containers in Web Pages and Other Containers

As mentioned previously, Java can be used to produce other stand-alone applications. However, Java applets are intended to execute in a Web browser and not as controls in other applications. The Internet ActiveX Control Pack demonstrates the value of ActiveX in other development environments like Visual C++, Delphi, Visual Basic, and MS-
Access. Microsoft's use of the OLE 2.0 specification as the basis for ActiveX Controls and its use in these other environments provide additional interoperability characteristics.

Of course, there are a couple of problems with the use of ActiveX Controls. You'll want to consider the following concerns:

Why are these disadvantages important? Let's take a moment and discuss each problem briefly.

Netscape Support. If Netscape continues to dominate the browser market and ActiveX is slow to take off, there is little advantage for Netscape in supporting ActiveX. Netscape provides support for Java and sees Microsoft as a significant competitive threat. However, Microsoft will probably provide a plug-in to allow support for ActiveX. So it is unlikely that this potential disadvantage will significantly affect the long-run viability of ActiveX.

UNIX Support. Many computers connected to the Internet are UNIX-based machines. Unfortunately, Microsoft has made no significant effort to deploy Microsoft technology to the UNIX platform. The Internet has thrived on the concept of open platform support. That is, most major Internet applications work on a diverse set of platforms. In fact, much of the Internet's recent surge in popularity is due to the platform-independent nature of Web pages. With so many Internet users relying on UNIX machines, failure to support ActiveX on UNIX might seriously hamper market acceptance. However, Microsoft has indicated that ActiveX will be supported in the UNIX environment.

ActiveX Scripting Services

Netscape added another highly useful feature to Navigator called JavaScript. JavaScript provides a simple mechanism for placing conditional logic and user interface elements in Web pages without CGI applications. Basically, the Web browser provides an interpreter platform for this script. ActiveX provides a similar scripting service for MSIE 3.0.

But the ActiveX scripting service is a more general service than that offered by Netscape. The ActiveX scripting service empowers you to add scripting and OLE Automation capabilities to programs. ActiveX scripting provides a platform for developing script engines. The script language, syntax, and execution model can vary based upon the design of the script language developer. There are two types of ActiveX scripting components:

The following sections take a look at these components.

ActiveX Scripting Hosts

An ActiveX scripting host provides a platform on which to run the ActiveX scripting engine. The principle ActiveX scripting host is MSIE 3.0. However, under ActiveX there are a number of potential script hosts:

ActiveX Scripting Engines

An ActiveX scripting engine is basically the language to be executed on the ActiveX scripting host. The first ActiveX scripting engine is VBScript, a subset of the popular Visual Basic 4.0 development environment. However, ActiveX provides any number of potential script engine environments such as the following:

ActiveX Documents

An existing application that doesn't need to be embedded in a Web page can be converted to an ActiveX document. Documents that conform to the ActiveX standard can be opened within other ActiveX document containers including:

ActiveX documents are based upon a more general abstraction called DocObjects. The DocObjects technology is a set of extensions to OLE documents, the compound document technology of OLE. As with OLE documents, the DocObjects standard requires a container to provide the display space for a DocObject. This technology allows the browser to present documents from Office and Office-compatible applications. Such functionality might allow any kind of document to be displayed within the Web browser.

Recall the OLE convention that an embedded object is displayed within the page of its owner document. Embedded objects do not, however, control the page on which they appear. These types of objects are usually quite small and hold very little persistent data. A spreadsheet with a few columns and rows, for instance, might be included in a Word document.

ActiveX documents, on the other hand, provide a fully functional document space. ActiveX documents also control the page in which they appear (called a DocObject container). This means that ActiveX documents can be considerably more feature-rich than the related embedded object.

One of the reasons for the rise of the Internet is the way that the Web has created an environment where every document is viewable in a single application. The ActiveX document standard aims to take those features another step beyond. ActiveX documents make the technology to use the Web as a vehicle for distribution of application specific documents. Microsoft's Internet Explorer 3.0 is an excellent example of an ActiveX document hosting engine.

Internet ActiveX Control Pack

The Internet ActiveX Control Pack (ICP) is not really ActiveX, per se. ICP is, instead, an application of ActiveX. But don't let that stop you. With ICP, it's easy to integrate ActiveX Controls into your Visual Basic programs. The ICP contains controls for most of the major Internet services you'll want to integrate into your own applications.

The TCP Control

The Transmission Control Protocol (TCP) is the first of two principle methods for transmitting data over the Internet today. TCP is a connection-oriented protocol most often used for transmitting Internet Protocol (IP) packets over a network. Connection-oriented protocols like TCP are responsible for ensuring that a series of data packets sent over a network all arrive at the destination and are properly sequenced. That's why you'll frequently see the moniker "TCP/IP." The ActiveX TCP control allows you to easily handle TCP data packets in your applications without knowing much about the details of the TCP protocol.

The UDP Control

The User Datagram Protocol (UDP) is the second of two principle methods for transmitting data over the Internet today. UDP is a connectionless protocol regularly used for transmitting Internet Protocol (IP) packets over a network. Unlike TCP and other
connection-oriented protocols, UDP doesn't care about the sequence of data packets. A UDP packet must stand on its own. The UDP control allows you to handle UDP data packets in your applications without knowing much about the details of the UDP protocol.

The FTP Client Control

The File Transfer Protocol (FTP) is probably the second most popular application used on the Internet today. FTP allows Internet users to upload and download files across the network. FTP also provides a mechanism to obtain filenames, directory names, attributes, and file size information. As with most Internet-based applications, FTP employs the client/server paradigm. The FTP server responds to requests for files from an FTP client. You'll use the FTP client control when your applications need to transfer text and binary files from FTP servers somewhere on the network.

The HTTP Client Control

The HyperText Transfer Protocol (HTTP) is absolutely the most popular application on the Internet. HTTP governs the interaction between an HTTP server and the Web browser. The HTTP client control allows you to directly retrieve HTTP documents. You'll use the HTTP control to create applications like HTML browsers.

The HTML Client Control

Programming Web content requires Hypertext Markup Language (HTML) programming. Typically the job of a Web browser parses and renders the HTML. HTML describes the placement and size of text and graphics. You'll use the HTML control to parse and layout HTML data, as well as provide a scrollable view of the selected HTML page. Unfortunately, the HTML client control only supports HTML 2.0 and not the evolving HTML 3.2 standard. The HTML control lets you implement an HTML viewer, with or without automatic network retrieval of HTML documents, into any application.

The SMTP Control

Many users find e-mail to be a convenient and easy way to exchange personal and corporate information. Electronic mail finds its way over the Internet using the Simple Mail Transfer Protocol (SMTP). The SMTP client control sends Internet mail messages to SMTP servers. The SMTP control supports all SMTP commands used in sending out a mail message. So integrating e-mail directly into new and existing applications is easy.

The POP Client Control

E-mail is typically stored on the SMTP server and then distributed to the actual recipient via the Post Office Protocol (POP). The POP control provides access to Internet mail servers using the POP3 protocol. If your applications need to retrieve and delete messages from Internet mails servers, the POP client control makes it easy.

The NNTP Control

UseNet newsgroups are distributed over the Internet via the Network News Transmission Protocol (NNTP). The NNTP CLIENT control enables interaction with newsgroups on the net. With this control, you'll connect to a news server, retrieve a list of available newsgroups and their descriptions, and view news messages. Newsgroups contain a wealth of information on an extremely diverse set of topics, so you may have many
applications that require scanning of news group posts.

ActiveX Server Framework

The ActiveX Server Framework provides an alternative to the Common Gateway Interface method of executing applications on a Web server and interacting with the Web browser dynamically. There are two major types of applications that can be developed using the ActiveX Server Framework:

The following sections take a look at the these types of applications.

ISAPI Applications

Web servers spawn Common Gateway Interface applications in separate processes with a separate environment. The Internet Server Application Programming Interface (ISAPI) specification provides an alternative to CGI programs with potentially higher performance type capabilities for the Microsoft Internet Information Server (IIS). ISAPI allows Web developers to build applications that execute in the same process space as the Web server.

Applications written using ISAPI should be faster simply because the operating system does not have to duplicate the environment and spawn a new process as is required
by CGI.

ISAPI applications are actually Dynamic Link Libraries (DLLs). Note that operating in the server's process space carries higher risk while providing somewhat higher performance. Since the ISAPI application is loaded in the same process as the HTTP server, an access violation by the ISAPI application may crash the HTTP server.

ISAPI Filters

The Internet Survey Application Programming Interface (ISAPI) also provides a mechanism for modifying the behavior of the server in specific ways. You'll employ ISAPI filters in cases where the default behavior of the server is inappropriate for the application. ISAPI filters can modify the behavior of the following server functions:

The following sections take a look at these server functions.

Authentication. If you've been surfing the Web, you've probably come across Web sites with pages that require a user name and password. Web site managers may want to control access to Web pages for any number of reasons. For instance, you might want to sell subscriptions to valuable content on your Web site. By default, most Web servers provide a basic authentication scheme. Usually this is a simple user name and password verification step.

With ISAPI, you can replace this basic authentication with a customized authentication process. Perhaps your environment requires that all user names and passwords for all systems be verified with a centralized database (so-called Single Sign On procedures). ISAPI filters provide a mechanism to accomplish this goal.

Compression. Sufficient bandwidth is perhaps the greatest inhibitor to complex content on the Internet. With an ISAPI filter, you can provide custom compression filters to improve throughput in high-end custom applications of Web technology.

Encryption. Many believe that commerce, the buying and selling of goods and services, will largely take place over the Internet. Because commerce requires the exchange of information (such as credit card numbers) that creates a tasty target for hackers, encryption is a key enabling technology. Encryption may be important in other applications as well. For instance, a company may want to transmit sensitive data to customers or suppliers. Encryption protects the data while it is in transit from source to destination. You can implement encryption to protect your data using an ISAPI filter.

Logging. When a Web server services a request for a Web page, the server makes an entry in the access log file. The access log file indicates which Web page, CGI, or ISAPI application was accessed. If the user has authenticated via the Web servers built-in authentication, the access log also contains the user name in access record. Date, time, and some other information is also recorded in the log as well.

One of the ways Web site operators make money is through advertising sales. Advertisers buy ad space based upon how many people will see their ad. So reporting information about how and by whom Web pages are accessed is extremely critical. You'll customize logging functionality using ISAPI filters.

Traffic Analysis. You may want to handle requests for a specific URL differently. For instance, you might want to catch all http://www.yourhost.com/../../etc/passwd requests and handle them in a certain way. You might want to examine other details of the transactions between Web browsers and your server. You'll use ISAPI filters to engage in traffic analysis.

Under the Hood of ActiveX

Microsoft has consolidated all its OLE and OCX technologies under the heading of "ActiveX." ActiveX defines a new specification for OLE controls which allows them to be much smaller and more efficient. New OLE interfaces are also specified, which addresses the problem of data and property management. Controls that are built using the new ActiveX lightweight control class are smaller than their Visual C++ Control Wizard-generated counterparts, and they can use the new interfaces to function efficiently and cooperatively with control containers in the Internet environment.

The OLE Control and Control Container Guidelines V2.0 defines a control as a COM software component that is self-registering and implements the IUnknown interface. In order to support self-registration, the control must export the DLLRegisterServer and DLLUnRegisterServer function calls. All the OLE interfaces that were previously mandatory are now optional. Controls are free to implement as many or as few of the standard interfaces as they require.

This leads to the first question with ActiveX Controls. Previously, a control container could depend on functionality being present in the control because of the mandatory OLE interfaces. If a control only implements the IUnknown interface, how does a control container, such as a browser or authoring tool, know or find out what a control's functionality is? The answer is component categories.

Component Categories

Component categories describe different prescribed areas of functionality. Each component category is identified by a Globally Unique Identifier (GUID) and each defines a set of standards that a control must meet in order to be part of that category. Component categories are stored as entries in the system registry with GUIDs and human readable keys.

Previously, when a control was registered on a client machine it also registered the keyword Control under its CLSID. This keyword advertised the control's suitability for insertion into container applications like Access and Visual Basic. The Control keyword is now obsolete, but it remains for the benefit of older applications that do not understand component categories.

Component categories are a natural extension of this process. They allow a control to describe its functionality in far more detail than plain OLE interface signatures. When a control self-registers in the system registry, it adds entries under its CLSID for the GUID for a control, the GUID for each category that it supports, and the GUID of each category that it requires support for from a container in order to function properly. Additionally, it registers its own CLSID under each category registry entry.

Until now, when an application wanted to find out if a particular control supported a piece of functionality, the application had to instantiate the control and use QueryInterface. If a valid pointer to a new interface was returned, then the application knew that the control supported the desired functionality.

This is a very expensive and cumbersome operation. Using categories and new OLE interfaces in the OLE libraries that allow categories to be registered/unregistered, enumerated, and queried means that an application does not have to instantiate a control any more. It can get information about controls from the system registry through these new interfaces in one of two ways. If a control's CLSID is known to the application, then the application can retrieve the category GUIDs under the control's registry entry to find out the functionality of the control. If a specific area of functionality is required, then the application can go to the registry entry for the category and retrieve a list of the controls on the machine that have registered support for that functionality. It can then go to each control's registry entry and determine if it can host the control. The list can then be presented to the user of the application via an application or system user interface and the user can choose which control to use.

Management of Data and Properties

The major difference between controls designed for use on the desktop and controls that are Internet-aware is the management of data and properties. A control may have any or all of the following types of data, which needs to be stored such that it can be easily retrieved by a control container when it recreates the control. These types do not imply any form of structure or storage location. A control's properties and BLOB data collectively make up its state. The data types are shown in Table 29.1.

Table 29.1  ActiveX Data Types
Data TypeSize Purpose
Class Identifier (CLSID)16 bytes The CLSID of the control class that can read the data that follows.
PropertiesAround 10k to 30kStandard and custom property values.
Binary Large Objects (BLOB)Arbitrary size Any number of large binary files. These files may be in any format, e.g. bitmaps, multimedia files, etc.

If a control has no persistent state, then none of the above will be present in an HTML document. The control container will retrieve the CLSID of the control class directly from the CLSID attribute of the HTML <OBJECT> tag or indirectly from the CODE attribute. The control can then be instantiated and no further initialization is required.

When the user of an application that is hosting a control gives the command to save, the control container calls QueryInterface on the control for a persistent storage interface and the control serializes its state through it. Similarly, when a control is recreated, it retrieves its state through a persistent storage interface. Where the application stores the control's state is up to the user of the application that is hosting the control. The control is not concerned. It may be embedded within the HTML document or in a separate file that is linked to the HTML document. This linking and embedding mechanism is familiar territory to anyone with knowledge of OLE compound documents.

Although the control is not concerned with the actual storage of its state, it is concerned with the interfaces through which its state is saved and retrieved. One of the goals Microsoft had when creating the ActiveX specification was to introduce as little new technology as possible. However, the existing persistence interfaces used in the current OLE compound document architecture are potentially unsuitable for Internet-aware controls.

Problems with the Current Implementation of OLE Compound Documents

In OLE compound documents, an object and its native data can be stored in two ways. They can be embedded in the document or linked to the document. In the embedding case, the object's CLSID, its native data, and a presentation cache are stored within the document. In the linking case, a moniker and a presentation cache are stored within the document. The moniker points to a file which contains the object's CLSID and native data.

The problems with this architecture are as follows:

The problem of the presentation cache was eliminated for the embedding scenario in the first release of the OLE control specification in 1994. Controls could implement a new lightweight interface called IPersistStreamInit, which can be used in preference to IPersistStorage. IPersistStreamInit allows all properties and BLOBs to be channeled into one stream and stored by the application in the document. This eliminated the cache as the data could simply and quickly be reloaded into the control when the document was loaded and the control was instantiated and initialized. In the linking case, because the objects data and properties were stored locally in files and could be retrieved quickly, the presentation cache was also eliminated.

Because of the shortcomings of the existing persistence mechanisms, Microsoft has developed new persistence mechanisms and monikers that extend the concept of linking and embedding beyond the OLE Compound Document architecture. These new mechanisms also allow for asynchronous retrieval of properties and BLOBs from remote sites.

Persistent Embedding. The control's CLSID, properties, and BLOBs are stored within the HTML document itself. This is really only useful where the aggregate size of this information is small. It is not suitable for large amounts of data as the time taken to download the page and make it active would be unacceptable.

Persistent Linking. A single URL moniker is stored in the HTML document. This moniker points to a file on a remote site that contains the CLSID, properties, and BLOBs for the control.

An important point to note is that the specification of embedding and linking in OLE compound documents entails adherence to certain user interface standards. Specifically, linked objects may not be in-place activated. Persistent linking and embedding are not concerned with user interface and the standards are not relevant. Their sole function is for storage management of properties and BLOBs. Controls that are in-place activated, therefore, can still work with persistently linked data.

The persistent interface mechanisms that can now be used by a control are summarized in the Table 29.2.

Table 29.2  Persistent Interface Mechanisms

UseMechanism Comments
Embedding/linkingIPersistStorage Standard persistence mechanism used in OLE compound documents. The container supplies an IStorage pointer to a storage object. The control may create any data structure within that object for its state.
Embedding/linkingIPersistStreamInit This is a lightweight alternative to IPersistStorage. All of the control's state can be serialized into one stream.
Embedding/linkingIPersistMemory The container defines a fixed size block of memory into which a control saves or retrieves its state. The control must not try to access memory outside the block.
EmbeddingIPersistPropertyBag The container and control exchange property/value pairs in Variant structures.
LinkingIPersistFile The container gives the control a UNC filename and is told to save or retrieve its state from that file.
LinkingIPersistMoniker The control is given a moniker. When the control reads or writes its state, it may choose any storage mechanism (IStorage, IStream, ILockBytes, etc.) it wants. If the storage mechanism chosen by the control is asynchronous, then IPersistMoniker must support asynchronous transfer.

For each mechanism that a control implements, the control container must provide the appropriate support.

A control container that wants to support embedding must provide the appropriate support for the persistence interfaces exposed by the control, as in the following table:

Control Persistence InterfaceContainer Supplied Support
IPersistStreamInit IStream
IPersistStorage IStorage
IPersistMemory Memory (*void)
IPersistPropertyBag IPropertyBag

A control container that wants to implement linking must use a moniker that can supply support for the persistence interfaces exposed by the control. At the time of writing, the only available moniker is the URL moniker.

If a control implements the IPersistMemory or the IPersistFile mechanism, then it should also implement one other interface as both of these require that the data be present locally. These mechanisms do not work well with asynchronous downloads of properties and BLOBs.

Controls are free to implement as many of these new persistence mechanisms as the developer of the control sees fit. For maximum flexibility, therefore, a control container should implement support for as many of these interfaces as possible. This will ensure that it can work with a wide range of controls which may not implement all of the new persistence mechanisms.

These new persistence mechanisms define the protocol through which the container and the control exchange information. What happens when an application decides to save a control's state (perhaps in response to a user request) depends on the application's (user's) preferences for storage. It can either be embedded in the HTML document or in a separate file and linked to the document.

When embedding is used, the control container chooses which persistence interface to use. The sequence in which a container looks for persistence interfaces is generally up to the designer of the container. However, IPersistMemory and IPersistStreamInit may be given precedence over IPersistProperyBag and IPersistStorage as they will generally produce the smallest amount of data. Note that it is perfectly acceptable for a container to have a control save its state in one location and then copy it to some other location. All that is required is that the container be able to retrieve the saved state and give it back to the control via the same interface. For example, a container could ask a control to save its state in a memory block. The container may then save the contents of that memory block in a storage location of its choosing. When the control is initialized, the container must retrieve the saved state and give it back to the control via a memory block.

When linking is used, the container is not concerned with any of the persistence interfaces. The container must store and interact with an URL moniker. The moniker takes care of all the interface querying. URL monikers query for persistence interfaces in the following order:

  1. IPersistMoniker
  2. IPersistStreamInit
  3. IPersistStorage
  4. IPersistMemory
  5. IPersistFile

In both linking and embedding, the container is responsible for the asynchronous transfer of data from the remote site. For more information on this, see the "Compound Files on the Internet" document supplied as part of the Sweeper SDK. All the persistence interfaces with the exception of IPersistMoniker are synchronous in operation. When a control receives a call to the Load member of one of its persistence interfaces, it expects all of the data to be available.

Data Paths. Data paths serve two purposes. They allow a control to store its BLOBs separately from its properties and they solve the problem of embedded links. Controls may have links to BLOBs buried away in their native data that only they know about. This prohibits the container from participating in the retrieval of these BLOBs. One solution to this is data path properties. Data path properties are properties that hold text string values. These string values are simply URL file names. Data path properties can be used with either persistent linking or persistent embedding.

In a control's type library, data path properties must be marked as [bindable] and [requestedit]. This allows container applications to update these properties through its own user interface. These properties may also be updated through the control's property sheet. They are also tagged with a special custom attribute which identifies them as data path properties. The custom attribute is called GUID_PathProperty. It has its own GUID. Additionally, a control's coclass entry in its type library is also tagged with a special attribute which signifies that it has data path properties. This attribute is called GUID_HasPathProperties and it too has its own GUID.

Note
Applications such as authoring tools and Web site management tools can query controls for data path properties and use them to perform link management or other tasks.

When a control wants to retrieve the file named by a data path property, it gives the URL to the container and asks it to create a moniker for the URL. The moniker is created in the implementation of the IBindHost interface. This interface is supplied as a service by the container site's IServiceObject implementation. In order for the control to call members of IBindHost, the control must provide a way for the container to pass a pointer that identifies the IServiceObject interface. A control could implement the IOleObject interface in order to achieve this.

This interface has a function called SetClientSite that allows a container to pass the pointer to the control. The IOleObject interface, however, is a large interface. All its functionality may not be required by a small control. A smaller interface called IObjectWithSite can be implemented. It has just two member functions, one of which, SetSite, allows the container to pass the required pointer.

Note
Any control that uses data path properties must support a siting mechanism. Either IOleObject or IOleObjectWithSite. This is a requirement of the specification.

In order to get the IBindHost interface, two steps are required. The control calls QueryInterface on the site pointer for the IServiceProvider interface. Then the control calls QueryService on the IServiceProvider interface for the IBindHost interface.

In order to get a moniker for the file and data path property names, the control calls the ParseDisplayName function of the IBindHost interface. The data path may be either an absolute path name or a path name relative to the location of the document. Either way, a moniker is returned which the control can use to retrieve data.

When downloading data, the control should be as cooperative as possible with the container and other controls by supporting asynchronous retrieval of data. This allows the user interface to remain active while data trickles down in the background.

Before initiating a retrieval operation, a control should check to see if the moniker that it is supplied with is an asynchronous one. It does this by calling QueryInterface on the moniker for the IMonikerAsynch interface. If this interface is not present, then the moniker is synchronous and the control has to bind directly to the storage identified by the moniker by creating a bind context and calling the BindToStorage member of the moniker.

If the moniker is asynchronous, then the control should get its bind context from the container through the GetBindCtx member of IBindHost. By obtaining it this way, the container has a chance to register itself as an interested party in the download process. It can monitor the download and display some sort of progress indicator for the user's convenience or perhaps allow the user to cancel the download.

Once a control has the bind context, it registers its own FORMATETC enumerator and a pointer to its IBindStatusCallBack interface in the bind context. The control initiates an asynchronous download in the Load member of a persistence interface. In this function, another asynchronous stream should be obtained so that the moniker and the bind context can be released. This allows the Load function to return immediately and execution control can return to the container. When data arrives, the OnDataAvailable member of the IBindStatusCallBack interface will be called. The control should obtain the data exclusively through this function.

For detailed information on how the control, the container and the moniker interact in asynchronous downloads, see the "Asynchronous Monikers" specification in the Sweeper SDK.

Data transfer may be aborted by a call to the OnStopBinding member of the IBindStatusCallBack interface. If a control receives such a call, then there are two possibilities. If the control has received all its data, then the call is merely a notification that transfer is complete; otherwise, the data transfer has been aborted for some reason.

A control may abort the data transfer by calling the Abort member of the IBinding interface. The control receives a pointer to this interface through the IStartBinding member of the IBindStatusCallBack interface.

Since the container has control and data is trickling down in the background, how does a container know when a control is ready to begin full interaction? One way is to return a new code, E_PENDING, from member functions of the control when the control is not yet ready to fully interact. When this code is not returned, the control may be ready to interact. This however does not allow for progressive changes in a control's ability to interact with the application and/or the user. Microsoft solved this problem by defining a new standard property, ReadyState, and a new standard event, OnReadyStateChanged. When the control's ready state changes, the new standard event is fired with the value of the ReadyState property to notify the container. The ReadyState property may progressively have the following values:

UninitializedThe control is waiting to be initialized through the Load member of a persistence interface.
LoadingThe control is synchronously retrieving its properties. Some may not yet be available.
Loaded/Can RenderThe control has retrieved its properties and is able to draw something through the Draw member of the IViewObject2 interface.
InteractiveThe control may interact with user in a limited way. It has not yet received all its data from the asynchronous download.
CompleteThe control is completely ready.

The control does not have to support all of the previous states. It only has to support as many as it needs.

Object Persistence and Data Path Properties

When a control is requested to save its state by a call to the Save member of a persistence interface, it saves all of its properties-including data path properties as strings-through the interface and then saves all the BLOBs referred to by any data path properties. It does this by obtaining a moniker for each data path through the container's IBindHost as described previously and synchronously saving the BLOB. When the Save function returns, a control is assumed to have saved all of its state.

Instantiation of a Control

The instantiation and initialization sequence for a control is described in the following paragraphs. The assumption is made that the control is already on the client machine and properly registered.

The application obtains the CLSID of the control from the CLSID attribute of the HTML <OBJECT> tag and instantiates the control.

The DATA attribute will contain either the property data encoded in MIME or an URL which names a file on a remote site that contains the property data.

If the DATA attribute contains the property data, the container obtains a persistence interface on the control and calls the Load member with a stream containing the property data.

If the DATA attribute contains an URL, then the container makes an URL moniker and calls the IBindToObject member of the IMoniker interface in order to retrieve the property data from a remote site. Inside this function, the URL moniker attempts to get an IPersistMoniker interface on the control. If it succeeds, it passes a pointer to itself to the Load member of this interface. The control then has complete control over retrieval of its properties from the remote site.

Note
Because properties are usually very small amounts of data, measured in hundreds of bytes or so, asynchronous retrieval may not be the best method. Synchronous retrieval may be a better option as it may allow the control to become interactive sooner.

If it cannot get the IPersistMoniker interface, it gets another persistence interface. It then retrieves the property data, wraps it up in an IStream object if necessary, and calls the Load member function of the interface with a pointer to the object. The control then retrieves its property data from the IStream object.

Inside the Load member of the persistence interface, the control will also initiate any asynchronous download of BLOBs. It asks the container to make URL monikers so that the container may also bind to them and participate in the download process. The control binds to each moniker and registers its IOnBindStatusCallback interface in order to receive data. Control is then returned to the container.

As BLOBs trickle down in the background, the control chang