[ Go to June 1997 Table of Contents ]|
Clearing a Programmer's Obstacle Course
Programming a Web page raises a new set of barriers.
While programming a Web page recently, I ran into a series of obstacles I had never seen before. To overcome them, I had to explore new ground and find new tools.
When I completed my Pinger object last month (see Programming Windows, May), I said a number of things to myself, two of which can be repeated in print: "That was a lot harder than it needed to be," and "I'm almost done with this project now."
I was one for two.
It was much harder than necessary, because Microsoft's tools to support COM object creation in Visual C++ 4.2 and ActiveX Template Library (ATL) 1.1 were primitive. But now I have Visual C++ 5.0, which includes ATL 2.1 and makes COM object and ActiveX control creation much easier. As a bonus, Visual C++ 5.0 makes the resulting objects much smaller.
However, I wasn't anywhere near done with the project after completing the Pinger object; I wasn't even half done. The script that created the round-trip time table that you previously saw took more time to build than did the Pinger object. You can visit that table and test your own Internet connection by browsing www.winmag.com/people/mheller/pinger.htm with Internet Explorer (IE) 3.x. To see the script, use IE's View Source command.
An exercise in frustration
I underestimated the time needed to develop this page. I reasoned that VBScript is a subset of Visual Basic, and since I know Visual Basic, I thought the script development would go fairly quickly. Wrong. I forgot the importance of the Visual Basic environment to productivity; I failed to understand the impact of VB features missing from VBScript; and I didn't understand the full complexity and scope of the interaction between HTML, scripting languages and ActiveX controls.
I switched to Microsoft Word 95 with Internet Assistant and generated a table in HTML. I could fill in the row labels easily enough, but I had no idea how to get an HTML table entry to update dynamically from a script. I saved the document as HTML from Word and loaded it into the ActiveX Control Pad.
I could have used HTML form elements, probably either text elements or button elements, as dynamic table entries. HTML forms and form elements are accessible from scripts by name or by array index; their value properties can be altered by scripts at any time. The only drawback of form text elements is that the user can change them. The drawback of form button elements is I didn't really want anything to happen if the user clicked on a button.
However, I didn't use HTML form elements. The natural thing to do from ActiveX Control Pad is to insert an ActiveX control. I started by using the Microsoft IE30 Label Control. I fooled with its properties until it finally looked right. When I went to do a second control, I realized that it's awkward to get a whole table full of controls in the same size and shape using the ActiveX Control Pad's visual control editor. Instead, I saved the page with one control and started to copy and paste blocks of control definition object tags. I then realized how limited text editing is in ActiveX Control Pad. I saved the HTML document again and reopened it from Visual J++ on another network machine. At this point, I wasn't very happy, because I was on my third tool and hadn't even begun writing the page's script portion.
After editing the object tags for the table, I tried viewing my handiwork in IE. Unfortunately, I discovered that my second machine didn't have the Microsoft IE30 Label Control installed-probably because it came with IE 3.01. I took the page back to the first machine, saw that it looked fine, then went back into the ActiveX Control Pad and replaced the first Microsoft IE30 Label Control with a Microsoft Forms 2.0 Label.
I did another mass edit back on the second machine in Visual J++ and wound up with a table full of Microsoft IE30 Label Controls. This time the resulting page displayed properly on both machines, with default captions in all the table's controls. Finally, I could write the actual script.
Objects, scripts and events
I named my controls using numbers to designate their location in the table. The first row had IDs of Label10 to Label14, the second row had IDs of Label20 to Label24 and so on. I think it would have been much better if there were some equivalent to Visual Basic's control arrays, or if my grid control idea had worked. With these labels, I couldn't just write a loop referring to Label(i).Caption or Label(i,j). Caption. I had to explicitly refer to Label42.Caption, which meant writing many more lines of code.
I wrote all my code, in-line, using those Caption properties as variables, with lavish use of copy and paste. I couldn't stand the script, and rewrote it several times. My final script has array variables to hold the minimum, maximum and average round-trip time for each site being tested, along with the site names and IP addresses. It also uses Functions, Subs and select case statements. It's about as structured as possible, given the limitations of the language.
Initially, I put all the scripting in Function window_onLoad(), which runs when the page loads. I found that none of the results displayed until the script completed. The wait for my initial table of nine sites to be tested was quite annoying. "Oh, no problem," I said to myself, "I'll just sprinkle some DoEvents() calls through the script." Wrong again. VBScript lacks a DoEvents() function or an equivalent.
I had to add a timer and put most of my processing in the timer-handler routine. However, VBScript lacks a timer statement. I was basically tearing my hair out in despair when WINDOWS Magazine executive editor Dave Methvin suggested that I use a Timer Object-something I'd overlooked. With that extra COM object in place, the page started working, much as you see it today.
The added feature of color-coded results was another suggestion by Methvin. It wasn't much trouble for me to write a ColorVal function that returns green for good values, yellow for okay values and red for unusually high values of the round-trip time, and put the results into the BackColor property of the appropriate label control.
Again, to see the code, you can browse http://www.winmag.com/people/mheller/pinger.htm with IE and view the source.
The final touch for the page was to add codebase specifications for the two Microsoft controls used. Codebase is an optional part of the HTML object tag that tells the browser where it can find the object if it's not already installed. Finding the correct location was a real pain-it was in a FAQ buried somewhere in the unchartered gigabytes of Microsoft's Web site.
Growing pains and tool troubles aside, this exercise showed me component-based programming is finally starting to make sense. With Nashville on the horizon offering HTML as one of the native views in the Windows Explorer, you have compelling reasons to think about Program=HTML+ scripting+ActiveX controls as an architectural alternative to the conventional Windows formula of Program=EXE+DLLs.
I've resisted the overhead of OLE and COM, and have only recently warmed to the idea of little components tied together with little scripts. I feel a little bit like one of the pigs in Animal Farm sneaking into the barn at night to cross out "bad" and scribble in "better."
I'm waiting for the day when I can pencil in "good."
Martin Heller writes about and does Windows programming from Andover, Mass. Contact Martin at his Web page at www.winmag.com/people/ mheller/, via e-mail at email@example.com or at the e-mail addresses here.