This chapter discusses how to add Internet features to your control. The Internet features I address fall into two broad categories:
Whether your control is appropriate to use in an EXE or a Web
page context, or both, will depend on
its functionality, as well as safety issues discussed in Chapter
13. This chapter will discuss both types of controls. In addition,
we'll tie in the topics of distributing your control and using
your ActiveX control in a Web context that we covered in Chapters
12 and 13.
NOTE |
A few of the examples in this chapter require Microsoft Internet Explorer. You can download Internet Explorer free from the Microsoft Web site at http://www.microsoft.com/ie/download/. |
One of Visual Basic 5.0's new features is the ability of ActiveX controls to asynchronously download property values. This feature enables your control to read a property from a remote source-generally, the Internet. The fact that the download is asynchronous means that your application does not have to wait for the download to complete before proceeding with other processing. Because files can take a while to be transmitted over the Internet, the asynchronous download feature is very useful indeed.
The HappyHour control, comprised of a constituent PictureBox and Label controls, was introduced earlier in this book. Because it is designed to display a different picture and text message depending on the time of day, it is an ideal demonstration of the power of asynchronous download over the Internet.
This new version of the HappyHour control has the following programmable interface:
In order to access the graphics denoted by the HappyHourYesURL and HappyHourNoURL properties, your control will need to download them. You use the UserControl object's AsyncRead method to do this. Because AsyncRead is an asynchronous process, as soon as you call this method, processing continues while the property downloads in the background. This processing could include, for example, additional input by the user or even the download of additional data from another source, since you can have a hypothetically unlimited number of downloads going at the same time. Even if you don't plan on enabling your control to perform other actions while it's asynchronously downloading a property value, it's a good idea to asynchronously download properties your control gets from the Internet, since you often have no control over how long something takes to download over the Internet.
The syntax of the AsyncRead method is:
UserControl.AsyncRead strURL, lngAsyncType, [Property]
The argument strURL is the target URL from which to download the property. The lngAsyncType argument is an enumeration that specifies what kind of property is being downloaded. The legal values for this argument are:
The Property argument is an optional identifier. It does not assign the download to a property, as you might think it would. Instead, it gives a name to the download so you can cancel it later if you need to. (You would use the CancelAsyncRead method to cancel the download.) The property name you assign here is also used to assign the downloaded data to a property; this is done in the AsyncReadComplete event, which is fired after the download is complete.
To see how this works, begin by opening the version of the HappyHour control in the Chapter 14\HappyHour4\Before folder in the CD-ROM that accompanies this book. The project group file is HappyHour.vbg.
In the previous iteration of this control, the HappyHour control raised a HappyHour-Changed event when it was time for happy hour. This new iteration of the control continues to raise this event but also adds two new properties, HappyHourYesURL and HappyHourNoURL. These two URLs point to graphic files on the Internet that are loaded when the HappyHourChanged event is triggered. When it's happy hour, the graphic located at HappyHourYesURL is loaded. When it's not happy hour, the graphic located at HappyHourNoURL is loaded.
To enable these new properties, do the following:
' Properties (in declarations section) Private mdatHappyHourBegin As Date Private mdatHappyHourEnd As Date Private mstrHappyHourYesURL As String Private mstrHappyHourNoURL As String
' Internal variables Private mvHappyHour As Variant
' Events Public Event HappyHourChanged(HappyStatus As Variant)
Private Sub UserControl_ReadProperties(PropBag As PropertyBag) On Error Resume Next mstrHappyHourYesURL = PropBag.ReadProperty("HappyHourYesURL", "") mstrHappyHourNoURL = PropBag.ReadProperty("HappyHourNoURL", "") Caption = PropBag.ReadProperty("Caption", Extender.Name) mdatHappyHourBegin = PropBag.ReadProperty("HappyHourBegin") mdatHappyHourEnd = PropBag.ReadProperty("HappyHourEnd") End Sub Private Sub UserControl_WriteProperties(PropBag As PropertyBag) PropBag.WriteProperty "HappyHourYesURL", mstrHappyHourYesURL, "" PropBag.WriteProperty "HappyHourNoURL", mstrHappyHourNoURL, "" PropBag.WriteProperty "Caption", Caption, Extender.Name PropBag.WriteProperty "HappyHourBegin", mdatHappyHourBegin PropBag.WriteProperty "HappyHourEnd", mdatHappyHourEnd End Sub
Public Property Get HappyHourYesURL() As String HappyHourYesURL = mstrHappyHourYesURL End Property Public Property Let HappyHourYesURL(ByVal strNewValue As String) mstrHappyHourYesURL = strNewValue If mvHappyHour Then HappyHourLoadGraphic True End If PropertyChanged "HappyHourYesURL" End Property Public Property Get HappyHourNoURL() As String HappyHourNoURL = mstrHappyHourNoURL End Property Public Property Let HappyHourNoURL(ByVal strNewValue As String) mstrHappyHourNoURL = strNewValue If Not(mvHappyHour) Then HappyHourLoadGraphic False End If PropertyChanged "HappyHourNoURL" End Property
The LoadHappyHourGraphic subroutine, called from the Property Let procedures of the new properties, initiates the asynchronous download. The code for this subroutine looks like this:
Private Sub LoadHappyHourGraphic(HappyStatus) ' Loads the appropriate happy hour graphic If HappyStatus = True Then AsyncRead mstrHappyHourYesURL, vbAsyncTypePicture, _ "asyncHappyHourYes" Else AsyncRead mstrHappyHourNoURL, vbAsyncTypePicture, _ "asyncHappyHourNo" End If End Sub
Putting the AsyncRead in its own subroutine helps you to avoid duplicating code in your project, since (as you'll see) the AsyncRead method must be called in several different places. Although the AsyncRead method reads the property from the Net, the property can't be assigned until the download is complete. This assignment takes place in the AsyncReadComplete event.
In order to assign the downloaded data to a property, the AsyncReadComplete event of the UserControl is passed an AsyncProperty object. The AsyncProperty object represents the property that was downloaded. This object has three properties of its own:
To handle an incoming asynchronously downloaded property, enter the following code:
Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty) If AsyncProp.AsyncType = vbAsyncTypePicture Then Picture1.Picture = AsyncProp.Value End If End Sub
This code is simple because there are only two types of asynchronous downloads handled by the HappyHour control-one that downloads the Happy Hour graphic, the other that downloads the "Get back to work" graphic-and they are both assigned to the same thing (the Picture property of Picture1).
However, if your control had to download many different kinds of files over the Net, you'd have to set up a Select Case based on AsyncProp in the AsyncReadComplete event. The code would look like this:
Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty) Select Case AsyncProp.PropertyName Case "asyncHappyHourYes" ' assign AsyncProp.Value to the property Case "asyncHappyHourNo" ' assign AsyncProp.Value to the property Case "asyncSomethingElse" ' and so forth End Select End Sub
Finally, in order to cause the control to download the property at happy hour, change the Timer event of the constituent Timer control to call the same LoadHappyHourGraphic subroutine you called in the control's Property Let procedures. The code for the Timer event should look like this:
Private Sub Timer1_Timer() ' Raise the appropriate event based on ' whether it's happy hour or not ' happy hour hasn't been set yet If mdatHappyHourBegin = 0 Or mdatHappyHourEnd = 0 Then Exit Sub End If Select Case mvHappyHour Case Empty ' i don't know whether it's happy hour or not If Time > mdatHappyHourBegin And _ Time < mdatHappyHourEnd Then mvHappyHour = True Else mvHappyHour = False End If LoadHappyHourGraphic mvHappyHour RaiseEvent HappyHourChanged(mvHappyHour) Case True ' it was happy hour a second ago If Time > mdatHappyHourBegin And _ Time < mdatHappyHourEnd Then ' it's still happy hour; do nothing Else mvHappyHour = False LoadHappyHourGraphic (False) RaiseEvent HappyHourChanged(False) End If Case False ' it was not happy hour now a second ago If Time > mdatHappyHourBegin And _ Time < mdatHappyHourEnd Then ' it's now happy hour mvHappyHour = True LoadHappyHourGraphic (True) RaiseEvent HappyHourChanged(True) Else ' do nothing End If End Select End Sub
There's nothing particular tricky about this event procedure; all of the work is done in the subroutines you entered previously.
The code in the Timer event first checks the variables that store happy hour's begin and end times. If either of these is set to zero (that is, it has not yet been initialized), then the event bails out, because it would make no sense to proceed if the control didn't know when happy hour is. Note that if mdatHappyHourBegin and mdatHappyHourEnd were Variant instead of Date values, you'd instead use the IsEmpty function to determine if the variables had not yet been initialized.
Once the procedure has determined when happy hour is, it compares that value to one of three previous states for happy hour: True, False, or uninitialized (Empty). This comparison takes place in the Select Case in the Timer event.
Based on this comparison, the procedure either raises the HappyHourChanged event and downloads the appropriate graphic, or (if the state of happy hour has not changed), does nothing.
Now that you've set up the new asynchronous download properties, you can test the control. To do this:
You can include an Internet control as a constituent control in order to give your project Internet capabilities. Internet controls handle such tasks as sending e-mail and transferring files (using file transfer protocol, or FTP). There are also Internet controls that give you direct access to Net connections, so-called socket controls that enable you to build your own Internet-aware application from scratch without having to worry about how the network transport works.
In this demonstration, you'll build a control that will act as
a custom technical support request interface. This control could
be used in situations where you need to deploy one or more applications
that supply a tech support e-mail feature. Providing an ActiveX
control to enable users to send e-mail to tech support would not
only be useful in a number of different applications, but it would
also provide a consistent interface across those different apps.
NOTE |
The Internet control I used for this demonstration is a shareware mail control produced by Mabry Software. There are a few suites of Internet controls on the market; I chose Mabry's because I like their liberal shareware policy-and they make good stuff. You can find Mabry on the web at http://www.mabry.com. In 1996 Microsoft briefly made a set of Internet controls available called Internet Control Pack. These controls have since been "transferred" to NetManage, and you can find them on the Web at http://www.netmanage.com. |
You can obtain a shareware version of the Internet mail control used in the following demonstration. This control is available as part of the Mabry Internet Pack, downloadable from Mabry Software's Web site at http://www.mabry.com. Information on the Internet Pack is at http://www.mabry.com/ipack.htm; the downloadable shareware version of the controls are at ftp://ftp.mabry.com/ipack.exe.
Once you've obtained ipack.exe and installed it on your system, the complete set of Mabry Internet controls is available on your system. You'll use one of these controls in the following demonstration.
To build the TechSupport control, do the following:
Next you'll add code to initialize the control. The idea here is to give the user the ability to send a tech support request to any one of a number of tech support departments. To do this:
Private Sub UserControl_Initialize() lstDepartment.AddItem "Hardware Support" lstDepartment.AddItem "Software Support" lstDepartment.AddItem "Athletic Support" End Sub
Next, you'll put code in the command button's Click event to validate that the tech support message has been created correctly. To do this:
Private Sub cmdSend_Click() If lstDepartment.ListIndex = -1 Then MsgBox "Please choose a tech support department " & _ "from the list.", vbExclamation, "Tech Support" lstDepartment.SetFocus Exit Sub End If If txtMessage.Text = "" Then MsgBox "Please type a message.", vbExclamation, "Tech Support" txtMessage.SetFocus Exit Sub End If ' OK to send the message SendMessage End Sub
Private State As EmailState Enum EmailState StateSending = 1 StateConnecting = 2 StateDisconnecting = 3 End Enum
Now you're ready to add the mail control and write the code that will drive it. To do this:
NOTE |
The nag screen appears because this control, like many ActiveX controls, is distributed as shareware. Shareware means that you can try the software before you purchase it; if you use it, you're expected to pay the author for it. Additionally, if you register the control by purchasing it, the nag screen goes away. Mabry Software has a very liberal shareware policy; all of their controls are available for download as shareware. |
NOTE |
The best way to test an application like this is to set it up to send e-mail messages to yourself (as opposed to, for example, me). Be sure to replace those bogus e-mail addresses with your own, so that when you're testing this control you'll actually get some mail. |
Private Sub SendMessage() ' Sends an email message Select Case lstDepartment.Text ' For testing purposes, you'll want ' to replace one or all of these ' email addresses with real Internet addresses. Case "Hardware Support" ' replace with your email address mMail1.To = "hardware@support.com" Case "Software Support" ' replace with your email address mMail1.To = "software@support.com" Case "Athletic Support" ' replace with your email address mMail1.To = "athletic@support.com" End Select mMail1.Subject = "Tech Support Request" mMail1.From = "Hapless User <hapless@user.com>" ' Replace the value in the next line with your ' internet service provider's email server; usually ' "mail.yourisp.com". mMail1.Host = "mail.your_internet_service_provider.com" ' Replace the value in the next line with the ' name of your email account. This value will not ' appear in the email message; it's used to log in ' to your outgoing email server (if the server ' requires such a login). mMail1.EMailAddress = "<your_account@yourisp.com>" mMail1.Body(0) = txtMessage.Text Screen.MousePointer = 11 State = StateConnecting mMail1.Action = MailActionConnect If (mMail1.Blocking = True) Then mMail1_Done End If End Sub
The important part of this code is toward the end of the procedure. This code calls the Done event of the mail control three times, once for each stage of the e-mail session (sending, connecting, and disconnecting).
To finish the project, put the following code in the mail control's Done event:
Private Sub mMail1_Done() Screen.MousePointer = 0 Select Case State Case StateConnecting State = StateSending mMail1.Flags = MailDstIsHost mMail1.Action = MailActionWriteMessage If (mMail1.Blocking = True) Then mMail1_Done End If Case StateSending State = StateDisconnecting mMail1.Action = MailActionDisconnect If (mMail1.Blocking = True) Then mMail1_Done End If Case StateDisconnecting 'do nothing; let it finish End Select End Sub
You can see that this event procedure can do three things depending on the state of the session with the mail server. If the event is raised after the control has finished connecting with the server (the StateConnecting case), the procedure changes the State flag to Sending, then sends the message. If the event is raised after the control has sent the message (the StateSending case), the event procedure changes the State flag to Disconnecting and disconnects from the server. If the event is raised after the control has disconnected (the StateDisconnecting case), then the procedure does nothing, because its work is done.
This control project now has all it needs to blanket the world (or you, at least) with useless e-mail. To test the control, do the following:
Although this is an extremely simple example of sending Internet e-mail, the fact that you have programmable control over the process opens up a number of interesting possibilities. You could write a control that polls a database once per hour, notifying a system administrator when a query retrieved a particular set of results. Or you could modify the control to generate a mass mailing to everyone in your company once per day, thereby introducing you to the exciting and dynamic world of independent consulting.
Any Windows application that does anything with the Internet does so through a networking API known as Winsock. Winsock implementations have existed for every version of Windows since 16-bit Windows 3.1.
In this chapter, I wanted to include an example of how to write a Winsock control using native Winsock API calls, but I quickly realized that such a project could very well take up a book of its own-and, in fact, somebody else has already written that book. The book is Michael Marchuk's Building Internet Applications With Visual Basic (Que, 1995), and it's definitely one of a kind. This book will really give you an insight into how to get to the Internet from Visual Basic. Its only problem from the perspective of a Visual Basic control creator is that all the examples and API declarations are geared toward the 16-bit implementation of Winsock.
In order to appreciate how much functionality is encapsulated by the mail control, you might find it helpful to see the actual text of the conversation it has with the server when it sends your e-mail message. You can get a look at the conversation the mail control has with the mail server by activating its debug mode. To do this:
Private Sub mMail1_Debug(ByVal Message As String) Debug.Print Message End Sub
OnSend 220-mail1.sirius.com Sendmail 8.6.12/960710 ready at Mon, 23 Dec 1996 12:10:50 -0800 220 ESMTP spoken here HELO bedrock 250 mail1.sirius.com Hello ppp011-sf1.sirius.com [205.134.227.11], pleased to meet you MAIL FROM:"Skippy" <skippy@sirius.com> 250 "Skippy" <skippy@well.com>... Sender ok RCPT TO:skippy@sirius.com 250 skippy@sirius.com... Recipient ok DATA 354 Enter mail, end with "." on a line by itself 250 MAA19061 Message accepted for delivery quit 221 mail1.sirius.com closing connection
NOTE |
This is roughly what I get when I send mail through my Internet service provider (ISP), anyway. The exact words you'll see will depend on how your ISP's mail server is configured. |
From looking at the debug information, you can see that the mail control really works on two levels. It handles the Winsock connectivity behind the scenes, acting as a wrapper around the Winsock API calls and encapsulating the Internet mail protocol, known as Simple Mail Transfer Protocol (SMTP). This protocol governs the way applications send mail through Internet mail servers. Again, it isn't strictly necessary for you to know how this works to add Internet mail functionality to your application, but it might prove helpful if you ever wanted to write your own Internet mail control.
Although there are a few ActiveX controls on the market that enable Web browsing and downloading of Internet data, none are likely to have an interface as rich (or well-supported) as that of Microsoft Internet Explorer. So it's fortuitous that Internet Explorer is a free download. Someday (hopefully soon) ActiveX will be supported on all operating system platforms, so you'll be able to activate Web browsers everywhere.
Internet Explorer's object interface can be used by Visual Basic applications in two ways: as an ActiveX control (the WebBrowser control) and as an Automation object. We'll take a look at both of these techniques in the remainder of this chapter. Then, in Chapter 16, "Object-Oriented Programming," you'll see how to put these technologies to work in the form of a custom Web-browsing Hotlist control.
One of the neat things about Microsoft Internet Explorer is the
fact that it is built around an ActiveX control. This means you
can use Internet Explorer as a constituent control in your applications;
the only requirement is that your users have Internet Explorer
installed on their computers-not a particularly
steep requirement, since it's a free download.
NOTE |
The full documentation of the object model of the WebBrowser control is available on the Microsoft Web site at http://www.microsoft.com/intdev/sdk/docs/iexplore/. It's definitely worth downloading if you plan on building a control based on the WebBrowser object. There are separate versions of the documentation geared toward Visual Basic and C/C++ developers. |
The ActiveX implementation of the WebBrowser control is in a file
called shdocvw.dll; it is registered in the list of ActiveX components
as Microsoft Internet Controls.
NOTE |
In order to keep you on your toes, Microsoft did not give the WebBrowser ActiveX control an .OCX extension as you'd expect; it is a .DLL file. But you knew already from your diligent reading of the previous chapters of this book that .OCX files are really just special types of .DLL files. You weren't confused by that, were you? Of course not. |
In order to see an example of the WebBrowser control in a control project, you'll build a control that will display Web pages automatically, one after the other, in a slide show format. To do this:
NOTE |
In the beta version of Visual Basic 5.0 used to develop the examples in this book, the WebBrowser control did not repaint itself or display its borders correctly at design time. This was probably just a quirk in the beta of VB 5.0; it's likely that this will have been fixed by the time you read this. This problem does not affect the control's functionality, at any rate. |
Private Sub UserControl_Resize() WebBrowser1.Move 0, 0, ScaleWidth, ScaleHeight If mstrFirstURL > "" Then WebBrowser1.Navigate mstrFirstURL End If End Sub
Public Property Get TimerInterval() As Integer TimerInterval = Timer1.Interval / 1000 End Property Public Property Let TimerInterval(ByVal lngNewValue As Integer) If lngNewValue > 0 And lngNewValue < 60 Then Timer1.Interval = lngNewValue * 1000 End If End Property
' Declarations Private mstrFirstURL As String Private mstrSecondURL As String Private mbURLFlag As Boolean ' specifies which URL is current Public Property Get FirstURL() As String FirstURL = mstrFirstURL End Property Public Property Let FirstURL(ByVal strNewValue As String) mstrFirstURL = strNewValue WebBrowser1.Navigate strNewValue End Property Public Property Get SecondURL() As String SecondURL = mstrSecondURL End Property Public Property Let SecondURL(ByVal strNewValue As String) mstrSecondURL = strNewValue WebBrowser1.Navigate strNewValue End Property
Private Sub Timer1_Timer() ' Only rotate slides at run time. If Ambient.UserMode = True Then If mbURLFlag Then If mstrFirstURL > "" Then WebBrowser1.Navigate mstrSecondURL mbURLFlag = False End If Else If mstrSecondURL > "" Then WebBrowser1.Navigate mstrFirstURL mbURLFlag = True End If End If End If End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag) mstrFirstURL = PropBag.ReadProperty("FirstURL", "") mstrSecondURL = PropBag.ReadProperty("SecondURL", "") Timer1.Interval = PropBag.ReadProperty("TimerInterval", 0) * 1000 End Sub Private Sub UserControl_WriteProperties(PropBag As PropertyBag) PropBag.WriteProperty "FirstURL", mstrFirstURL, "" PropBag.WriteProperty "SecondURL", mstrSecondURL, "" PropBag.WriteProperty "TimerInterval", Timer1.Interval / 1000, 0 End Sub
NOTE |
A more elegant way to implement the URL properties of this control might be through the use of a collection. That way, rather than limiting the number of Web pages to two, you could display a (theoretically) unlimited number of Web pages by adding each new Web page to a collection of URLs. For more information on how to implement collections, see Chapter 16, "Object-Oriented Programming." |
You can use the Internet Explorer object model to control a Web browser from an ActiveX control contained in the browser.
For example, consider a large Web site with large pages containing lots of links. Such sites often contain HTML hyperlinks that say Back, which is the link that takes you back to the page where you came from. But how does the page know exactly which page you came from? The answer is: it doesn't. It assumes you followed the hierarchy the Web site designer set up for you. But we all know the Web doesn't always work that way. You could have come to the site from a search engine or typed in the URL manually.
In order to have a true Back button, your control would need information about which URL the user had been previously viewing. Internet Explorer conveniently stores that information in a place called the history list. You can move through the URLs in the browser's history list by using the GoForward and GoBack methods of the WebBrowser control.
To see how this works, you'll set up a custom command button that acts as a Back button. The advantage of this control over a Back hyperlink is that it will always take the user back to the previous URL viewed. Another advantage is that it will always work, no matter which Web page you use it in. To set up this control:
Private Sub Command1_Click() On Error Resume Next Hyperlink.GoBack End Sub
NOTE |
You include the On Error Resume Next in case some wisenheimer tries to put the control in a Visual Basic form; since only Web pages support the GoBack method, this control is only appropriate for use in a Web page. |
In the Click event procedure, you use the Hyperlink object (an element of the UserControl object) to navigate through the Web browser container's history list. The Hyperlink object has three methods:
To finish this control and prepare it for testing, include the standard code for resizing and initializing the control's Caption property:
Private Sub UserControl_InitProperties() On Error Resume Next Caption = Extender.Name End Sub Private Sub UserControl_Resize() Command1.Move 0, 0, ScaleWidth, ScaleHeight End Sub Public Property Get Caption() As String Caption = Command1.Caption End Property Public Property Let Caption(ByVal strNewValue As String) Command1.Caption = strNewValue End Property
Now you're in a funny situation, because at this point you want to test the control. But you don't want to go to the trouble of testing the control on a Web page, because then you'd have to compile it and write an HTML test page for it. I thought about creating an EXE test form with a Web browser control on it, then making the Web browser control the container of the BackButton control. But that doesn't work (because the Web browser control doesn't contain controls in the traditional sense; it can contain controls, but only if those controls are embedded into the HTML).
So for now, you're stuck with compiling and writing an HTML test page for the BackButton control in order to test it. To do this:
NOTE |
See Chapter 13 for more information on how to use the ActiveX Control Pad. |
NOTE |
If at this point you wish to go back and enhance the control you're working on, be sure to check the Binary Compatibility option (in Project Properties) before you recompile. If you don't do this, you'll need to recreate your test HTML page, because the control's GUID will change when it is recompiled. |
You can launch an instance of Microsoft Internet Explorer using a technology known as Automation (formerly known as OLE Automation). Automation is an object technology, related to but different from ActiveX control objects. Automation objects have the following distinguishing characteristics:
You can use Internet Explorer as an Automation server to provide additional Internet features to your control project in situations where you would rather not use the WebBrowser control. To see an example of how to do this:
Private Sub UserControl_Initialize() lstURL.AddItem "General Help Topics" lstURL.AddItem "Printing" lstURL.AddItem "Saving Your Work" End Sub
Private Sub UserControl_Resize() lstURL.Move 0, 0, ScaleWidth, ScaleHeight End Sub
Private Sub lstURL_DblClick() Screen.MousePointer = vbHourglass Dim objExplorer As Object Set objExplorer = CreateObject("InternetExplorer.Application") Select Case lstURL.Text Case "General Help Topics" objExplorer.Navigate "http://www.microsoft.com/kb/" Case "Printing" objExplorer.Navigate "c:\work\print.html" Case "Saving Your Work" objExplorer.Navigate "c:\work\save.html" Case Else ' whoops! do nothing Exit Sub End Select ' Setting explicit Left and Top values ' ensures that IE will always appear in ' a full window even if the user has an ' existing instance minimized objExplorer.Left = 10 objExplorer.Top = 10 objExplorer.Visible = True Screen.MousePointer = vbArrow End Sub
As you've probably surmised, this code launches Internet Explorer, tells it to navigate to a particular URL, then makes the application visible. (Most Automation servers are initially invisible by default.)
The code creates an instance of Internet Explorer by using the CreateObject function. Using the CreateObject function to create an instance of an Automation server is not unlike creating a control on a form in Visual Basic, except that Automation takes place in code; there is no visual component to it. Once you've created an instance of Internet Explorer (represented in this code by the object variable objExplorer), you can execute its methods (such as its Navigate method) and alter its properties (such as its Left, Top, and Visible properties).
Once the instance of Internet Explorer is visible, users are free to use Internet Explorer's user interface to do whatever they want, saving you a heap of trouble in the area of user-interface design and event handling.
To test the capabilities of the code you just entered, do the following:
If this were a real control project, you'd want to insert an error
trap to handle the situation where a URL didn't exist or couldn't
be opened by Internet Explorer. See Chapter 15 for more information
on how to do this. A more elegant version of this control will
be presented in Chapter 16, as you learn how to use Visual Basic's
object-oriented programming features to create a working Internet
Hotlist control project.
NOTE |
There is an article on the Microsoft Web site that gives a code example of how to launch Internet Explorer from Visual Basic. The code example provided in the Microsoft article is incorrect, at least as of this writing. This article is in the Microsoft Knowledge Base; its article ID is Q160976. You can access the Microsoft Knowledge base on the Web at http://www.microsoft.com/kb/. |
In this chapter, we explored a number of Internet-related topics, including downloading property values, sending Internet mail and controlling Microsoft Internet Explorer. It's good to get a handle on these technologies-even if you're not doing Internet stuff right now, chances are in the coming years you'll be called upon to do so.
In the next chapter, we'll jump into the infinitely sublime topic of handling errors and debugging your control projects.