It's helpful to put ActiveX documents within the context of COM and
OLE, which you already understand if you've read the other chapters in this book.
You can, however, get started with ActiveX document servers without fully
understanding all the COM concepts covered in Part VI.
ActiveX Document Servers vs. OLE Embedded Servers
As you saw in Chapter 28, an OLE embedded server program runs in a child window of an OLE container application and occupies a rectangular area in a page of the container's document (see Figure 28-1). Unless an embedded server program is classified as a mini-server, it can run stand-alone also. In embedded mode, the server program's data is held in a storage inside the container application's file. The embedded server program takes over the container program's menu and toolbar when the user activates it by double-clicking on its rectangle.
In contrast to an embedded server, an ActiveX document server takes over a whole frame window in its container application, and the document is always active. An ActiveX server application, running inside a container's frame window, runs pretty much the same way it would in stand-alone mode. You can see this for yourself if you have Microsoft Office 97. Office includes an ActiveX container program called Binder (accessible from the Office shortcut bar), and the Office applications (Microsoft Word, Microsoft Excel, and so on) have ActiveX server capability. Figure 36-1 shows a Word document and an Excel chart inside the same binder.
Figure 36-1. A Word document and an Excel chart inside a Microsoft Office Binder window.
Like an embedded server, the ActiveX document server saves its data in a storage inside the ActiveX container's file. When the Office user saves the Binder program from the File menu, Binder writes a single OBD file to disk; the file contains one storage for the Word document and another for the Excel spreadsheet. You can see this file structure yourself with the DFVIEW utility, as shown in Figure 36-2.
Figure 36-2. A file structure displayed by the DocFile Viewer.
Running an ActiveX Document Server from Internet Explorer
Running an ActiveX document server from Internet Explorer is more fun than running one from Microsoft Office Binder (Internet Explorer refers to Internet Explorer 3.0 or greater). Rather than load a storage only from an OBD file, the server program can load its storage from the other side of the world. You just type in a URL, such as http://www.DaliLama.in/SecretsOfTheUniverse.doc, and a Microsoft Word document opens inside your Browse window, taking over the browser's menu and toolbar. That's assuming, of course, that you have installed the Microsoft Word program. If not, a Word document viewer is available, but it must be on your hard disk before you download the file.
An ActiveX document server won't let you save your changes back to the Internet host, but it will let you save them on your own hard disk. In other words, File Save is disabled but File Save As is enabled.
If you have Microsoft Office, try running Word or Excel in Internet
Explorer now. The EX34A server is quite capable of delivering documents
or worksheets to your browser, assuming that they are accessible from its
home directory. Note that Internet Explorer recognizes documents and
worksheets not by their file extensions but by the CLSID inside the files. You can prove
this for yourself by renaming a file prior to accessing it.
ActiveX Document Servers vs. ActiveX Controls
Both ActiveX document servers and ActiveX controls can run with and without the Internet. Both are compiled programs that can run inside a browser. The following table lists some of the differences between the two.
ActiveX Document Server | ActiveX Control | |
Module type | EXE | Most often a DLL |
Can run stand-alone | Yes | No |
Code automatically downloaded and registered by a WWW browser | No | Yes |
Can be embedded in an HTML file | No | Yes |
Occupies the entire browser window | Yes | Sometimes |
Can be several pages | Yes | Not usually |
Can read/write disk files | Yes | Not usually |
ActiveX document servers implement the same interfaces as OLE embedded servers, including IOleObject, IOleInPlaceObject, and IOleInPlaceActiveObject. ActiveX document containers implement IOleClientSite, IOleInPlaceFrame, and IOleInPlaceSite. The menu negotiation works the same as it does for Visual Editing.
Some additional interfaces are implemented, however. ActiveX document servers implement IOleDocument, IOleDocumentView, IOleCommandTarget, and IPrint. ActiveX document containers implement IOleDocumentSite. The architecture allows for multiple views of the same documentsort of like the MFC document-view architecturebut most ActiveX document servers implement only one view per document.
The critical function in an OLE embedded server is IOleObject::DoVerb, which is called by the container when the user double-clicks on an embedded object or activates it through the menu. For an ActiveX document server, however, the critical function is IOleDocumentView::UIActivate. (Before calling this function, the container calls IOleDocument::CreateView, but generally the server just returns an interface pointer to the single document-view object.) UIActivate finds the container site and frame window, sets that window as the server's parent, sets the server's window to cover the container's frame window, and then activates the server's window.
It's important to realize that the COM interaction takes place between the container program (Internet Explorer or Binder) and the ActiveX document server (your program), which are both running on the client computer. We know of no cases in which remote procedure calls (RPCs) are made over the Internet. That means that the remote host (the server computer) does not use COM interfaces to communicate with clients, but it can deliver data in the form of storages.
MFC allows you to create your own ActiveX document server programs. In addition, Visual C++ 6.0 now allows you to write ActiveX document containers. To get a server program, create a new MFC AppWizard EXE project and then check the Active Document Server check box, as shown in Figure 36-3. To create a container program, just make sure the Active Document Container check box is marked.
Figure 36-3. Step 3 of the MFC AppWizard.
Here's a rundown of the classes involved in MFC's ActiveX Document
Server Architecture.
COleServerDoc
As it is for any COM component, your ActiveX document server's document class is derived from COleServerDoc, which implements IPersistStorage, IOleObject, IDataObject, IOleInPlaceObject, and IOleInPlaceActiveObject.
The COM interfaces and MFC classes discussed here were named before Microsoft introduced ActiveX technology. An ActiveX document server was formerly known as a document object server or a doc object server, so those are the names you'll see in the source code and in some online documentation.
This class is derived from the
COleServerItem class used in embedded
servers. Your ActiveX document server program has a class derived from
CDocObjectServerItem, but that class isn't used when the program is running in
ActiveX document mode.
CDocObjectServer
This class implements the new ActiveX server interfaces. Your application
creates an object of class CDocObjectServer and attaches it to the
COleServerDoc object. If you look at
COleServerDoc::GetDocObjectServer in your derived
document class, you'll see the construction code. Thereafter, the document
object and attached CDocObjectServer object work together to provide ActiveX
document server functionality. This class implements both
IOleDocument and IOleDocumentView, which means that you can have only one view per document
in an MFC ActiveX document server. You generally don't derive classes from
CDocObjectServer.
COleDocIPFrameWnd
This class is derived from COleIPFrameWnd. Your application has a frame window class derived from COleDocIPFrameWnd. The framework constructs an object of that class when the application starts in embedded server mode or in ActiveX document server mode. In ActiveX document server mode, the server's window completely covers the container's frame window and has its own menu resource attached, with the identifier IDR_SRVR_INPLACE (for an SDI application).