Chapter 24

ActiveX Documents and the Internet


CONTENTS

I read through the documentation on ActiveX documents several times trying to understand the implications of this technology. But it wasn't until I actually used these documents that I began to realize the possibilities. In this chapter, my intent is not so much to tell you about ActiveX documents, as it is to show you. To do this, I had the pleasure of inventing a fictitious real estate company. I hope you enjoy its site, which makes extensive use of ActiveX documents. However, I encourage you to use extreme caution before sending a check or your credit card number there!

The Realty ActiveX Document

Really Realty Services Inc. is a small fictitious outfit with big goals. They don't want to just display properties on the Web. They want to display the current information about a property along with an interactive program that allows potential customers to calculate their mortgage payments and even submit online bids. They could come up with some sophisticated form-based Web pages to do this, but they've figured out that there is no reason to tie up their server with tasks such as calculating loans. It's much better to have those types of programs just run on the client machine.

Besides, they are Visual Basic programming wizards and don't know much about complex form-based HTML code and server-side programming. By using an ActiveX document, they are able to use the full resources of the local system. They're not quite sure what to do with that capability yet, but they know it will come in handy in the future.

Figure 24.1 shows the page they've created to display information about a property. There is a Picture Box that will contain a picture of the property, a Label to show the current asking price, and a Text Box that will display the current property description.

Figure 24.1 : Design-time view of the realty.dob ActiveX document.

The ActiveX document has three properties: Price, Picture, and Description. The property procedures for these properties and persistence functions are shown below:

' Guide to the Perplexed
' Realty Example
' Copyright © 1997 by Desaware Inc. All Rights Reserved.
' Really Realty Services Inc. is a fictional company, and
' any resemblance to a real company is entirely unintentional
Option Explicit

Dim m_Price As Currency


Public Property Get Picture() As Picture
   Set Picture = Picture1.Picture
End Property

Public Property Set Picture(ByVal vNewValue As Picture)
   Set Picture1.Picture = vNewValue
   PropertyChanged "Picture"
End Property

Public Property Get Price() As Currency
   Price = m_Price
End Property

Public Property Let Price(ByVal new_Price As Currency)
   If new_Price < 0 Then Exit Property
   m_Price = new_Price
   lblPrice.Caption = Format$(m_Price, "Currency")
   PropertyChanged "Price"
End Property

Public Property Get Description() As String
   Description = txtDescription.Text
End Property

Public Property Let Description(new_Description As String)
   txtDescription.Text = new_Description
   PropertyChanged "Description"
End Property

Private Sub UserDocument_InitProperties()
   cmdEdit.Visible = True
   cmdNew.Visible = True
End Sub

Private Sub UserDocument_ReadProperties(PropBag As PropertyBag)
   txtDescription.Text = PropBag.ReadProperty("Description")
   m_Price = PropBag.ReadProperty("Price")
   lblPrice.Caption = Format$(m_Price, "Currency")
   Set Picture1.Picture = PropBag.ReadProperty("Picture")
End Sub

Private Sub UserDocument_WriteProperties(PropBag As PropertyBag)
   Call PropBag.WriteProperty("Description", txtDescription.Text)
   Call PropBag.WriteProperty("Price", m_Price)
   Call PropBag.WriteProperty("Picture", Picture1.Picture)
   ' Once data is written, this page is not editable
   cmdEdit.Visible = False
   cmdNew.Visible = False
End Sub

There are also four buttons. The Bid button is used to bring up a bid submission form, which is a separate Visual Basic modal form that not only allows the client to submit bids on the property, but to perform any other tasks they decide will be related to submitting a bid. The Back button is just a navigation aid to allow the client to return to the previous browser page without having to use the browser toolbar or menu.

This ActiveX document is designed to work in two modes. When the browser opens an empty .VBD file, the InitProperties event is triggered and the Edit and New buttons are made visible (they are invisible by default). This is done in the following code:

Private Sub UserDocument_InitProperties()
   cmdEdit.Visible = True
   cmdNew.Visible = True
End Sub

This mode is intended for their own use when developing the site. They use Microsoft's Internet browser to open the empty RealtyDoc.vbd file, then use the Edit and New buttons to create new VBD documents that have the picture, price, and description properties set. When those documents are loaded, the ReadProperties event will be triggered, which does not make the Edit and New buttons visible. These two buttons are also hidden after the WriteProperties event occurs, to prevent the pages from being edited again. (Note that the RealtyDoc.vbd file has been renamed ReltyDoc.vbd in the CH24 sample directory in order to fit within the 8.3 filename format required by the CD-ROM.)

Editing the current page is a simple task. A separate form named frmEdit is used to edit the document's properties. It is brought up using the following code when the Edit button is clicked. The Edit form is shown in Figure 24.2.

Figure 24.2 : The document editing form.

Private Sub cmdEdit_Click()
      Set frmEdit.OwnerDoc = Me
      frmEdit.Show vbModal
      Set frmEdit = Nothing
End Sub

This form has a preview window to display a picture of the property. It has two text boxes for editing the price and the description, and it uses a common dialog control to load the picture file. The code for this form is shown below:

Option Explicit

Public OwnerDoc As RealtyDoc

Private Sub cmdCancel_Click()
   Unload Me
End Sub

Private Sub cmdLoadImage_Click()
   Dim newfile$
   CmnDialog1.ShowOpen
   If CmnDialog1.FileTitle = "" Then Exit Sub
   newfile = CmnDialog1.filename
   On Error GoTo badimage
   Set Picture1.Picture = LoadPicture(newfile)
   Exit Sub
badimage:
End Sub

Private Sub cmdOk_Click()
   OwnerDoc.Price = txtPrice.Text
   OwnerDoc.Description = txtDescription.Text
   Set OwnerDoc.Picture = Picture1.Picture
   Unload Me
End Sub

Private Sub Form_Load()
   txtPrice.Text = OwnerDoc.Price
   txtDescription.Text = OwnerDoc.Description
   Set Picture1.Picture = OwnerDoc.Picture
End Sub

The OwnerDoc variable is a public property of the form that is set by the realty Document object before the form is shown. This allows the form to access the public properties of the document. You can also access Friend properties and methods of the Document object, though this is not shown in this particular example.

If you look at the settings for the common dialog control, you'll find that its filter property is set to Pictures (*.bmp;*.ico;*.wmf;*.gif). WMF? That's a Windows metafile. Since when can a Web browser download and display a Windows metafile? Well, most of them can't. But it doesn't matter. You see, the Web browser does not download and display the metafile. It downloads the VBD ActiveX document file. That document file contains the metafile, and Visual Basic knows how to read and display metafiles in picture boxes.

Does this mean that ActiveX documents can allow you to potentially handle any file format or even create custom file formats of your own that you can edit and display, regardless of the capabilities of the browser? Yes. In fact, this example uses metafile pictures for all of its graphics. A complete discussion of metafiles is beyond the scope of this book but, in short, they differ from bitmaps in two major characteristics:

The Edit button edits the current document. But you don't want to edit the empty RealtyDoc document. You need to keep it around as a blank template for other documents. For this reason, it should be set to read-only. Instead, there needs to be a way to create new documents.

One method to do so is shown below in the cmdNew_Click command code:

Private Sub cmdNew_Click()
   Dim newname$
   Dim newpath$, oldpath$
   Dim searchloc&, curloc&, curchar$
   newname$ = InputBox("Enter new document name", "New")
   If newname$ = "" Then Exit Sub
   oldpath = Parent.locationname
   newpath = oldpath
   curloc = Len(newpath)
   Do While curloc > 0
      curchar$ = Mid$(newpath, curloc, 1)
      If curchar = "/" Or curchar = "\" Then
         newpath = Left$(newpath, curloc)
         Exit Do
      End If
      curloc = curloc - 1
   Loop
   newpath = newpath & newname$ & ".vbd"
   ' Add test for existing file here
   FileCopy oldpath, newpath
   m_HyperLinked = True
   Hyperlink.NavigateTo "file://" & newpath
End Sub

The Parent object's Locationname property provides the document name. You can't use the App.Path property in Visual Basic because it gives you the location of the server, not the current document.

The document name is assumed to be on the local system. If you loaded it through a Web site, this code will fail with an error. But in this particular application, it is assumed that new properties will only be defined on the local system. The routine strips the final document name from the path and appends in a new document name that is entered using an input box. The name should be added without an extension; a more robust example would verify this. The FileCopy command is used to create the new document file. Note that this will be a blank document.

The next step is to navigate to the new document. This is done by setting a global variable called m_HyperLinked to True. This variable is used to indicate to a newly loaded document that it has been loaded as a result of a New operation and to tell it to bring up its edit form during the Show event. The Hyperlink object is then used to navigate to the new page.

The m_HyperLinked variable is defined in a standard form so it will be global to all document objects. If it is True, the edit form is shown, as you can see below:

Private Sub UserDocument_Show()
   If m_HyperLinked Then
      m_HyperLinked = False
      Set frmEdit.OwnerDoc = Me
      frmEdit.Show vbModal
      Set frmEdit = Nothing
   End If
End Sub

The ActiveX document includes an About Box implemented in the usual way as shown below: The document has a menu that includes both a Help and an About command. The Negotiate attribute for the menu is set so it will be merged with the container's menu.

Private Sub mnuAbout_Click()
   frmAbout.Show vbModal
End Sub

A text box is used for the description because it supports scrolling. However, the document does not allow editing of the description on the document page itself. In order to prevent editing, keypresses are intercepted to block editing and deleting in the text box, as shown below:

Private Sub txtDescription_KeyDown(KeyCode As Integer, Shift As Integer)
   If KeyCode = vbKeyDelete Then
      KeyCode = 0
   End If
End Sub

Private Sub txtDescription_KeyPress(KeyAscii As Integer)
   KeyAscii = 0
End Sub

Implementing the Back browser command is trivial:

Private Sub cmdBack_Click()
   Hyperlink.GoBack
End Sub

The Bid form is brought up using the following code:

Private Sub cmdBid_Click()
   Set frmBid.OwnerDoc = Me
   frmBid.Show vbModal
   Set frmBid = Nothing
End Sub

The form is shown in Figure 24.3.

Figure 24.3 : The Bid form at design time.

Right now the form does nothing with the information that is entered. But this is a standard Visual Basic form, so you can do anything you want at this point. You could generate an e-mail message with the bid. You could calculate a loan payment and send information based on the results. You could allow the user to record an audio message and upload it to an FTP site somewhere.

This brings up an important point. Standard Web sites are designed to accept small amounts of data from the client while sending large amounts of data back to the client. Relatively short text command lines are used in HTML to request information from a server. Once in Visual Basic, you have a great deal more flexibility for sending information to the server. You could, for example, upload data to an FTP site, then send a command with the name of the file. Or use a separate direct Internet connection using a Winsock control. ActiveX documents may prove to be an excellent solution for this type of situation. For example: If the fictitious folks that run Really Realty Services, Inc. ever go out of business, they could set up an ActiveX document-based dating service, where you can use a VB form to submit your picture and perhaps a short video clip directly to the services computer systems via the Internet.

Now let's take a look at what it takes to make this document work on a Web site.

ActiveX Documents and HTML

The process of setting up an ActiveX document for Internet distribution is identical to that of ActiveX controls and will not be repeated here. The only difference is that what you are distributing is the document server, not the document itself.

If you look at the Setup subdirectory under the Chapter 24 sample directory on the CD-ROM that comes with this book, you will find the file Realty.htm HTML page that is created by the Visual Basic setup wizard.

<HTML>
<OBJECT ID="RealtyDoc"
CLASSID="CLSID:18C62902-7B03-11D0-91BB-00AA0036005A"
CODEBASE="realty.CAB#version=1,0,0,1">
</OBJECT>

<SCRIPT LANGUAGE="VBScript">
Sub Window_OnLoad
      Document.Open
      Document.Write "<FRAMESET>"
      Document.Write "<FRAME SRC=""RealtyDoc.VBD"">"
      Document.Write "</FRAMESET>"
      Document.Close
End Sub
</SCRIPT>
</HTML>

The Object tag should be familiar to you from the ActiveX control example. The .CAB file can be signed just as it was in the ActiveX control example. The servers within the file can be marked as safe for initialization and safe for scripting using either the registry technique or the IObjectSafety technique described in Chapter 21. Note that this sample code does use scripting and thus will generate a warning message if the component is not marked as safe for scripting.

Speaking of scripting, what is the script that appears below the Object tag? When this HTML page is loaded by the browser, it will first verify that the object is present on the system, downloading it if necessary. It will then run the VB Script code shown. This code opens the current page and starts writing new HTML code into the page. It first writes a <FRAMESET> tag, which defines what follows as being a frame that takes over the entire browser window. It then specifies that the frame should be loaded with the ActiveX document, in this case, the default RealtyDoc.VBD file. Finally it closes the frameset and the document. In effect, it tells the browser to load the .VBD file and display it.

The page shown here will, in fact, download a document server if necessary and then display a document. However, it is somewhat misleading. I'm afraid that many ActiveX document developers will get the idea that this is the only way to display an ActiveX document and that each ActiveX document requires its own HTML page to load and display. That may be true if you are using a single ActiveX document, but if your site uses many documents, it is terribly inefficient.

The programmers at the Really Realty Services company knew better. You can see their handiwork by opening the default.htm file in Chapter 24 on the CD-ROM with Microsoft Internet Explorer. This page is shown below:

<!DOCTYPE HTML PUBLIC "-//W3O/DTD HTML//EN">

<html>
<OBJECT ID="RealtyDoc"
CLASSID="CLSID:18C62902-7B03-11D0-91BB-00AA0036005A"
CODEBASE="realty.CAB#version=1,0,0,1">
</OBJECT>
<head>
<title>mainpage</title>
<meta name="FORMATTER" content="Microsoft FrontPage 1.1">
</head>
<frameset rows="23%,77%">
    <frame src="frbanner.htm" name="banner" marginwidth="1"
    marginheight="1">
    <frameset cols="30%,70%">
        <frame src="frconten.htm" name="contents" marginwidth="1"
        marginheight="1">
        <frame src="frmain.htm" name="main" marginwidth="1"
        marginheight="1">
    </frameset>
    <noframes>
    <body>
    <p> </p>
    <p>This web page uses frames, but your browser doesn't
    support them.</p>
    </body>
    </noframes>
</frameset>
</html>

This is the root page for the site. The company expects everyone viewing the site to go through this page at least the first time they access the site. Thus, the document server download takes place at this time. The page has a banner frame with the company name at the top and a list of properties on the left. The main portion of the page, on the right, contains an introductory text at first. The contents page, frconten.htm, contains jumps that go directly to the ActiveX documents. For example, the line:

<h3><a href="bigben.vbd">Big Ben</a></h3>

will appear as Big Ben on the Web page in blue text (or whichever color your browser is using to indicate a jump). When you click on the link, the browser will download file bigben.vbd from the site. It examines the file and sees that it is a structured storage file that meets the standard of ActiveX documents. It extracts the CLSID identifier of the server and checks the server, to find that it is registered to realty.dll, which was downloaded earlier. The browser then asks the server to create a RealtyDoc object. The object's ReadProperties event is then triggered, allowing it to read the property information from file bigben.vbd, which had just been downloaded. The browser then displays the ActiveX document in the main frame, which is the default target for all links on the current page.

It is conceivable that a client will run into trouble if they set bookmarks directly to one of these documents and lose access to their server, but if this occurs they will be notified by the browser. All they need to do is go back to the home page to reload the document server. The contents page code is shown below.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

<html>

<head>
<title>Table of Contents Frame in mainpage</title>
<meta name="GENERATOR" content="Microsoft FrontPage 1.1">
<base target="main">
</head>

<body>
<h3>Choose from among <br>
these fine properties:</h3>
<h3><a href="bigben.vbd">Big Ben</a></h3>
<h3><a href="capitol.vbd">U.S. Capitol</a></h3>
<h3><a href="eiffel.vbd">Eiffel Tower</a></h3>
<h3><a href="empire.vbd">Empire State</a></h3>
<h3><a href="sydney.vbd">Opera House</a></h3>
<h3><a href="tajmahal.vbd">Taj Mahal</a></h3>
</body>

</html>

It is up to you whether you want to have a separate HTML page for each ActiveX document or implement direct links as shown here. The end result can be seen in Figure 24.4.

Figure 24.4 : Sample page from the Realty site.

I encourage you to explore this small site and to create some documents of your own. This concludes our coverage of ActiveX documents. Are they the future of Internet and intranet Web sites? Or are they a solution to a problem that doesn't really exist? Or perhaps a good idea that just won't catch on. Time will tell.