Figure 1   Usage Demo

 <package>
 <job id="Phonebook">
 <script language="JScript" src="usage.js"/>
 <script id="UsageDemo" language="JScript">
 
 // Core functions
 function main()
 {
     init();
     var args = WScript.Arguments;
 
     if (args.length < 1)
     {
         myWSH.ShowUsage();
         WScript.Quit();
     }
 
     switch (args(0))
     {
         case "-A" : 
         case "-a" : 
             if (args.length < 3)
             {
                 myWSH.ValError(
                 "Adding to the phonebook requires both a name and a phone number.");
                 WScript.Quit();
             }
             WScript.Echo(args(1) + " has been added to your phonebook"); 
             break;
         case "-D" : 
         case "-d" : 
             if (args.length < 2)
             {
                 myWSH.ValError("Deleting from the phonebook requires a name.");
                 WScript.Quit();
             }
             WScript.Echo(args(1) + " has been deleted from your phonebook"); 
             break;
         case "-L" : 
         case "-l" : 
             WScript.Echo("Phone: " + genPhone()); 
             break;
         case "-h" :
         case "-H" :
         case "/h" :
         case "\\h":
         case "-?" :
         case "/?" :
         case "\\?":
         case "?"  :
             myWSH.ShowUsage();
             break;
     }
 }
 
 function init()
 {
     myWSH.AddParameter(ptFlag, "-H", "Show this message and quit", true, 1, 1);
     myWSH.AddParameter(ptFlag, "-A", "Adds a Name", false, 2, 2);
     myWSH.AddParameter(ptString, "name", "The name to process", true, 2, 5);
     myWSH.AddParameter(ptPhoneNum, "num", "The phone number", true, 2, 6);
     myWSH.AddParameter(ptFlag, "-D", "Deletes a Name", false, 3, 3);
     myWSH.AddParameter(ptFlag, "-L", "Looks up a Name (default)", false, 3, 4);
     myWSH.AddParameter(ptString, "name", "The name to process", true, 3, 5);
     myWSH.fConsoleRequired = false;
     myWSH.strUsageDefault = "-H";
 
     myWSH.Validate();
 }
 
 function genPhone()
 {
     var str = "";
 
     for (var i = 0; i < 12; i++)
     {
         if (3 == i || 7 == i)
         {
             str += "-";
         }
         else
         if (0 == i || 4 == i)
         {
             str += new String(Math.floor(Math.random() * 8) + 2); 
             // First nums shouldn't be 0 or 1
         }
         else
         {
             str += new String(Math.floor(Math.random() * 10));
         }
     }
 
     return str;
 }
 
 // Let's run this puppy!
 main();
 
 </script>
 </job>
 </package>


Figure 2   Handling Standard Streams


 <package>
 <job id="js">
 <script language="JScript" src="menus.js"/>
 <script language="JScript" src="..\Example 1\usage.js"/>
 <script language="JScript">
 
 // Declare globals
 var MainMenu;
 var AddMenu;
 var DelMenu;
 var LookupMenu;
 var dataObj;
 
 // Core functions
 function main()
 {
     init();
     MainMenu.Activate();
 }
 
 function init()
 {
     myWSH.fConsoleRequired = true;
     myWSH.Validate();
 
     init_MainMenu();
     init_AddMenu();
     init_DelMenu();
     init_LookupMenu();
 
     dataObj = new DataObj();
 }
 
 // Create the menus
 function init_AddMenu()
 {
     AddMenu = new Menu("Add a Name", 
                 "Phonebook", 
                 AddMenuInit, 
                 "Items marked with a * are required but not completed");
 
     AddMenu.AddItem("N", "Enter the name", AddMenuGetName);
     AddMenu.AddItem("P", "Enter the phone number", getPhone);
     AddMenu.AddItem("A", "Enter the street address", getAddress);
     AddMenu.AddItem("C", "Enter the city", getCity);
     AddMenu.AddItem("S", "Enter the state", getState);
     AddMenu.AddItem("Z", "Enter the zip code", getZip);
     AddMenu.AddItem("Q", "Quit and Save data", AddMenuSaveData);
     AddMenu.AddItem("X", "Cancel (Data will not be saved)", cancel);
 }
 
 function init_DelMenu()
 {
     DelMenu = new Menu("Delete a Name", "Phonebook");
 
     DelMenu.AddItem("N", "Enter a name to delete", DelMenuGetName);
     DelMenu.AddItem("Q", "Quit to Main Menu", cancel);
 }
 
 function init_LookupMenu()
 {
     LookupMenu = new Menu("Lookup a Name", "Phonebook");
     LookupMenu.AddItem("N", "Enter a name to lookup", LookupMenuGetName);
     LookupMenu.AddItem("Q", "Quit to Main Menu", cancel);
 }
 
 function init_MainMenu()
 {
     MainMenu = new Menu("Main Menu", "Phonebook");
     MainMenu.AddItem("A", "Add a Name", DoAddMenu);
     MainMenu.AddItem("D", "Delete a Name", DoDelMenu);
     MainMenu.AddItem("L", "Lookup a Name", DoLookupMenu);
     MainMenu.AddItem("Q", "Quit Phonebook", cancel);
 }
 
 // AddMenu Specific functions
 
 function AddMenuInit()
 {
     AddMenu.MarkItem("N");
     AddMenu.MarkItem("P");
 }
 
 function AddMenuGetName()
 {
     dataObj.name = getInput("Enter the name: ");
     if (dataObj.name != "")
     {
         return "unmark";
     }
     return "mark";
 }
 
 function AddMenuSaveData()
 {
     if (AddMenu.MarkedItems())
     {
         WScript.StdOut.WriteLine("There are still required fields that are blank");
         return true;
     }
 
     WScript.StdOut.WriteLine(dataObj.name + " has been added to the phonebook.");
     return false;
 }
 
 // DelMenu Specific functions
 
 function DelMenuGetName()
 {
     dataObj.name = getInput("Enter the name: ");
     if (dataObj.name != "")
     {
         WScript.StdOut.WriteLine(dataObj.name + " has been removed from the phonebook");
     }
     return true;
 }
 
 // LookupMenu Specific functions
 
 function LookupMenuGetName()
 {
     dataObj.name = getInput("Enter the name: ");
     if (dataObj.name != "")
     {
         WScript.StdOut.WriteLine(dataObj.name + "'s phone number is " + genPhone());
     }
     return true;
 }
 
 // MainMenu Specific functions
 
 // Note: By calling these here, rather than doing direct calls to the Activate 
 //       functions, we can safely create the menus in any order. We also gain local 
 //       control if we quit out of the Main Menu or not - something we need.
 
function DoAddMenu() 
 { 
     AddMenu.Activate(); 
     return true; 
 }
 
function DoDelMenu() 
 { 
     DelMenu.Activate(); 
     return true; 
 }
 
 function DoLookupMenu() 
 { 
     LookupMenu.Activate(); 
     return true; 
 }
 
 // General Menu Functions
 
 function getPhone()
 {
     dataObj.phone = getInput("Enter the phone number: ");
     if (dataObj.phone != "")
     {
         return "unmark";
     }
     return "mark";
 }
 
 function getAddress()
 {
     dataObj.address = getInput("Enter the street address: ");
 }
 
 function getCity()
 {
     dataObj.city = getInput("Enter the city: ");
 }
 
 function getState()
 {
     dataObj.state = getInput("Enter the state: ");
 }
 
 function getZip()
 {
     dataObj.zip = getInput("Enter the zip code: ");
 }
 
 function cancel()
 {
     return false;
 }
 
 // Data
 
 // Data Handler
 function DataObj()
 {
     this.name = "";
         this.phone = "";
     this.address = "";
     this.city = "";
     this.state = "";
     this.zip = "";
 }
 
 // Utilities
 
 function getInput(prompt, val)
 {
     var notdone = true;
     var data;
 
     while (notdone)
     {
         WScript.StdOut.WriteLine();
         WScript.StdOut.Write(prompt);
         data = WScript.StdIn.ReadLine();
         if (null != val)
         {
             if (val(data))
             {
                 notdone = false;
             }
             else
             {
                 WScript.StdOut.WriteLine("Error - Invalid Data");
                 WScript.StdOut.Write("Try again? (Y/N) > ");
                 var yn = WScript.StdIn.Read();
                 if (yn.toUpperCase() == "N")
                 {
                     data = "";
                     notdone = false;
                 }
             }
         }
         else
         {
             notdone = false;
         }
     }
     return data;
 }
 
 function genPhone()
 {
     var str = "";
 
     for (var i = 0; i < 12; i++)
     {
         if (3 == i || 7 == i)
         {
             str += "-";
         }
         else
         if (0 == i || 4 == i)
         {
             // First nums shouldn't be 0 or 1
             str += new String(Math.floor(Math.random() * 8) + 2); 
         }
         else
         {
             str += new String(Math.floor(Math.random() * 10));
         }
     }
 
     return str;
 }
 
 // Let's run this puppy!
 main();
 
 </script>
 </job>
 </package>

Figure 3   Phonebook with GUI


 <?XML version="1.0"?>
 <package>
 <job id="js">
 
 <comment>
 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 Program: PhoneBook3
 Author : Michael Whalen
 Date   : August 27, 1999
 
 This is the PhoneBook3 Example, written for Microsoft Internet 
 Developer Magazine. There are two other examples written for the 
 same article, but they are not as complete as this one. This example 
 contains primitive data handling methods, a simple entry form and 
 it demonstrates more of the XML syntax needed for WSF files.
 
 An even more complete implementation of this program would use a 
 more flexible database system - an XML text file, for instance.
 However, for the sake of simplicity, this code uses a simple text
 file with hardcoded data positions.
 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 </comment>
 
 <comment>****** FILE NAMES ******</comment>
 <resource id="sDataFileName">phonebook3.dat</resource>
 <resource id="sHTMLFileName">phonebook3.htm</resource>
 
 <comment>****** ERROR MESSAGES ******</comment>
 <resource id="errMissingName">You must enter a name</resource>
 <resource id="errMissingPhone">You must enter a phone number</resource>
 <resource id="errMissingAddress">You must enter an address</resource>
 <resource id="errMissingCity">You must enter a city</resource>
 <resource id="errMissingState">You must enter a state</resource>
 <resource id="errMissingZip">You must enter a zip code</resource>
 <resource id="errInvalidStateLen">State field should be 2 letters long</resource>
 <resource id="errInvalidZipLen">Zip code should be 5 numbers long</resource>
 
 <comment>****** TITLES ******</comment>
 <resource id="ttlMain">Enter data now</resource>
 <resource id="ttlStored">Data stored</resource>
 <resource id="ttlCleared">Data cleared</resource>
 <resource id="ttlRestored">Data has been restored</resource>
 <resource id="ttlRecordNum">Record number </resource>
 <resource id="ttlNewRecord">New record added at end of list</resource>
 <resource id="ttlDelRecord">Record deleted</resource>
 <resource id="ttlErrDirty">Error: Data has changed - Accept or Cancel changes first</resource>
 <resource id="ttlErrInvalid">Invalid data entered - </resource>
 
 <comment>****** MISC ******</comment>
 <resource id="defColor">Blue.... No! Yellaaaaaaaaaaaaaaaaaaaaaaa</resource>
 
 <script language="JScript">
 <![CDATA[
 
 // Declare Globals
 var fso, ie, doc, keep_going;
 var data;
 var rootdir;
 var errmessage;
 
 var datafile;
 var htmlfile;
 
 // Core Functions
 function main()
 {
     init();
     ie.Navigate(rootdir + htmlfile);
 
     while (keep_going)
     {
         WScript.Sleep(100); 
     }
 }
 
 function init()
 {
     fso = WScript.CreateObject("Scripting.FileSystemObject");
     ie  = WScript.CreateObject("InternetExplorer.Application", "ie_");
 
     // Initialize our form
     ie.AddressBar = false;
     ie.FullScreen = false;
     ie.MenuBar    = false;
     ie.Resizable  = false;
     ie.StatusBar  = false;
     ie.ToolBar    = false;
 
     // Set the size
     ie.Height = 270;
     ie.Width = 780;
 
     // Get file paths
     rootdir = WScript.ScriptFullName;
     rootdir = rootdir.substring(0, rootdir.lastIndexOf("\\") + 1);
     datafile  = getResource("sDataFileName");
     htmlfile  = getResource("sHTMLFileName");
 
     // Don't stop 
     keep_going = true;
 }
 
 // Data Object
 function DataObj(fin)
 {
     this.name       = "";
     this.phone      = "";
     this.address    = "";
     this.city       = "";
     this.state      = "";
     this.zip        = "";
     this.color      = "";
 
     if (null != fin)
     {
         this.LoadData(fin);
     }
 }
 
 function DataObj_Validate()
 {
     // All fields are required - make sure they're all there first
     // We're gonna fudge on the color though....
     if ("" == this.name){
         errormsg = getResource("errMissingName");
         return false;
     }
 
     if ("" == this.phone){
         errormsg = getResource("errMissingPhone");
         return false;
     }
 
     if ("" == this.address){
         errormsg = getResource("errMissingAddress");
         return false;
     }
 
     if ("" == this.city){
         errormsg = getResource("errMissingCity");
         return false;
     }
 
     if ("" == this.state){
         errormsg = getResource("errMissingState");
         return false;
     }
 
     if ("" == this.zip){
         errormsg = getResource("errMissingZip");
         return false;
     }
 
     if ("" == this.color){
         this.color = getResource("defColor");
     }
 
     // Okay... the fields are there... now let's check validity.
     // State should be two letters
     if (2 != this.state.length)
     {
         // If we want to get fancier, we probably should check that it's actually 
         // a legal state code.
         errormsg = getResource("errInvalidStateLen");
         return false;
     }
 
     // Zip should be 5 characters
     if (5 != this.zip.length)
     {
         // If we want to get fancier, we could cross check this with the state and 
         // city, or even fill them in based on the zip... 
         // we'd need a database of zip codes, of course
         errormsg = getResource("errInvalidZipLen");
         return false;
     }
 
     // Everything we care about is good, let's return true
     return true;
 }
 DataObj.prototype.Validate = DataObj_Validate;
 
 function DataObj_LoadData(fin)
 {
     var InputString = fin.ReadLine();
     var InputArray = InputString.split(";");
 
     this.name       = InputArray[0].UnEncode();
     this.phone      = InputArray[1].UnEncode();
     this.address    = InputArray[2].UnEncode();
     this.city       = InputArray[3].UnEncode();
     this.state      = InputArray[4].UnEncode();
     this.zip        = InputArray[5].UnEncode();
     this.color      = InputArray[6].UnEncode();
 }
 DataObj.prototype.LoadData = DataObj_LoadData;
 
 function DataObj_StoreData(fout)
 {
     var OutputArray = new Array(
         this.name.Encode(),
         this.phone.Encode(),
         this.address.Encode(),
         this.city.Encode(),
         this.state.Encode(),
         this.zip.Encode(),
         this.color.Encode());
 
     var OutputString = OutputArray.join(";");
 
     fout.WriteLine(OutputString);
 }
 DataObj.prototype.StoreData = DataObj_StoreData;
 
 function DataObj_LoadDialog()
 {
     // Copy from dialog
     doc.all.txtName.value       = this.name;
     doc.all.txtPhone.value      = this.phone;
     doc.all.txtAddr.value       = this.address;
     doc.all.txtCity.value       = this.city;
     doc.all.txtState.value      = this.state;
     doc.all.txtZip.value        = this.zip;
     doc.all.txtColor.value      = this.color;
 }
 DataObj.prototype.LoadDialog = DataObj_LoadDialog;
 
 function DataObj_StoreDialog()
 {
     // Store the old values
     var old = new DataObj();
     old.Copy(this);
 
     // Copy from dialog
     this.name       = doc.all.txtName.value;
     this.phone      = doc.all.txtPhone.value;
     this.address    = doc.all.txtAddr.value;
     this.city       = doc.all.txtCity.value;
     this.state      = doc.all.txtState.value;
     this.zip        = doc.all.txtZip.value;
     this.color      = doc.all.txtColor.value;
 
     // Are they good?
     if (!this.Validate())
     {
         // Bad data - restore data and return
         this.Copy(old);
         return false;
     }
     return true;
 }
 DataObj.prototype.StoreDialog = DataObj_StoreDialog;
 
 function DataObj_Copy(from)
 {
     this.name      = from.name;
     this.phone     = from.phone;
     this.address   = from.address;
     this.city      = from.city;
     this.state     = from.state;
     this.zip       = from.zip;
     this.color     = from.color;
 }
 DataObj.prototype.Copy = DataObj_Copy;
 
 // Data Handler Object
 function DataHandler()
 {
     this.Data = new Array();
     this.CurRecord = 0;
     this.Dirty = false;
 }
 
 function DataHandler_ReadData()
 {
     if (!fso.FileExists(rootdir + datafile))
         return;
 
     var fin = fso.OpenTextFile(rootdir + datafile);
     while (!fin.AtEndOfStream)
     {
         this.Data[this.Data.length] = new DataObj(fin);
     }
     fin.Close();
 }
 DataHandler.prototype.ReadData = DataHandler_ReadData;
 
 function DataHandler_SaveData()
 {
     var fout = fso.OpenTextFile(rootdir + datafile, 2);
     for (var i = 0; i < this.Data.length; i++)
     {
         this.Data[i].StoreData(fout);
     }
     fout.Close();
 }
 DataHandler.prototype.SaveData = DataHandler_SaveData;
 
 function DataHandler_LoadDialog()
 {
     this.Data[this.CurRecord].LoadDialog();
 }
 DataHandler.prototype.LoadDialog = DataHandler_LoadDialog;
 
 function DataHandler_StoreDialog()
 {
     if (this.Data[this.CurRecord].StoreDialog())
     {
         this.Dirty = false;
         return true;
     }
     return false;
 }
 DataHandler.prototype.StoreDialog = DataHandler_StoreDialog;
 
 function DataHandler_NextRecord()
 {
     if (this.CurRecord < this.Data.length - 1)
     {
         this.CurRecord++;
     }
 }
 DataHandler.prototype.NextRecord = DataHandler_NextRecord;
 
 function DataHandler_PreviousRecord()
 {
     if (this.CurRecord > 0)
     {
         this.CurRecord--;
     }
 }
 DataHandler.prototype.PreviousRecord = DataHandler_PreviousRecord;
 
 function DataHandler_FirstRecord()
 {
     this.CurRecord = 0;
 }
 DataHandler.prototype.FirstRecord = DataHandler_FirstRecord;
 
 function DataHandler_FinalRecord()
 {
     this.CurRecord = this.Data.length - 1;
 }
 DataHandler.prototype.FinalRecord = DataHandler_FinalRecord;
 
 function DataHandler_NewRecord()
 {
     this.Data[this.Data.length] = new DataObj();
     this.FinalRecord();
 }
 DataHandler.prototype.NewRecord = DataHandler_NewRecord;
 
 function DataHandler_DelRecord()
 {
     if (1 == this.Data.length)
     {
         // Clear the data
         var obj    = this.Data[0];
         obj.name   = "";
         obj.phone  = "";
         obj.addr   = "";
         obj.city   = "";
         obj.state  = "";
         obj.zip    = "";
         obj.color  = "";
         
         obj.LoadDialog();
         return;
     }
     
     if (this.CurRecord == this.Data.length - 1)
     {
         // Simple amputation
         this.Data.length--;
         this.CurRecord--;
         return;
     }
     
     for (var i = this.CurRecord; i < this.Data.length - 1; i++)
     {
         this.Data[i].Copy(this.Data[i + 1]);
     }
     this.Data.length--;
         
 }
 DataHandler.prototype.DelRecord = DataHandler_DelRecord;
 
 // IE Events
 function ie_DocumentComplete()
 {
     // Let's create some data, shall we?
     data = new DataHandler();
     data.ReadData();
 
     // Set up the document - title, events, etc.
     doc = ie.Document;
     doc.title = getResource("ttlMain");
 
     // Button Events
     doc.all.btnAccept.onclick    = btnAccept_OnClick;
     doc.all.btnClear.onclick     = btnClear_OnClick;
     doc.all.btnCancel.onclick    = btnCancel_OnClick;
     doc.all.btnFirst.onclick     = btnFirst_OnClick;
     doc.all.btnPrevious.onclick  = btnPrevious_OnClick;
     doc.all.btnNew.onclick       = btnNew_OnClick;
     doc.all.btnDelete.onclick    = btnDelete_OnClick;
     doc.all.btnNext.onclick      = btnNext_OnClick;
     doc.all.btnFinal.onclick     = btnFinal_OnClick;
 
     // Text Box Events
     doc.all.txtName.onchange     = txtBoxOnChange;
     doc.all.txtPhone.onchange    = txtBoxOnChange;
     doc.all.txtAddr.onchange     = txtBoxOnChange;
     doc.all.txtState.onchange    = txtBoxOnChange;
     doc.all.txtCity.onchange     = txtBoxOnChange;
     doc.all.txtZip.onchange      = txtBoxOnChange;
     doc.all.txtColor.onchange    = txtBoxOnChange;
 
     // What if there's no data?
     if (data.Data.length < 1)
     {
         data.AddRecord();
     }
     data.CurRecord = 0;
     data.LoadDialog();
 
     // Show the world our creation
     ie.Visible = true;
 }
 
 function ie_OnQuit()
 {
     keep_going = false;
     data.SaveData();
 }
 
 // Button Events
 function btnAccept_OnClick()
 {
     if (!data.StoreDialog())
     {
         doc.title = getResource("ttlErrInvalid") + errormsg;
     }
     else
     {
         doc.title = getResource("ttlStored");
     }
 }
 
 function btnClear_OnClick()
 {
     // Clear the dialog
     doc.all.txtName.value    = "";
     doc.all.txtPhone.value   = "";
     doc.all.txtAddr.value    = "";
     doc.all.txtCity.value    = "";
     doc.all.txtState.value   = "";
     doc.all.txtZip.value     = "";
     doc.all.txtColor.value   = "";
 
     doc.title = "Data Cleared";
 
 }
 
 function btnCancel_OnClick()
 {
     data.LoadDialog();
     doc.title = getResource("ttlRestored");
 }
 
 function btnFirst_OnClick()
 {
     if (data.Dirty)
     {
         doc.title = getResource("ttlErrDirty");
         return;
     }
     data.FirstRecord();
     data.LoadDialog();
     doc.title = getResource("ttlRecordNum") + (data.CurRecord + 1);
 }
 
 function btnPrevious_OnClick()
 {
     if (data.Dirty)
     {
         doc.title = getResource("ttlErrDirty");
         return;
     }
     data.PreviousRecord();
     data.LoadDialog();
     doc.title = getResource("ttlRecordNum") + (data.CurRecord + 1);
 }
 
 function btnNew_OnClick()
 {
     if (data.Dirty)
     {
         doc.title = getResource("ttlErrDirty");
         return;
     }
     data.NewRecord();
     data.LoadDialog();
     doc.title = getResource("ttlNewRecord");
 }
 
 function btnDelete_OnClick()
 {
     data.DelRecord();
     data.LoadDialog();
     doc.title = getResource("ttlDelRecord");
 }
 
 function btnNext_OnClick()
 {
     if (data.Dirty)
     {
         doc.title = getResource("ttlErrDirty");
         return;
     }
     data.NextRecord();
     data.LoadDialog();
     doc.title = getResource("ttlRecordNum") + (data.CurRecord + 1);
 }
 
 function btnFinal_OnClick()
 {
     if (data.Dirty)
     {
         doc.title = getResource("ttlErrDirty");
         return;
     }
     data.FinalRecord();
     data.LoadDialog();
     doc.title = getResource("ttlRecordNum") + (data.CurRecord + 1);
 }
 
 // Text Box Events
 function txtBoxOnChange()
 {
     data.Dirty = true;
     doc.title = getResource("ttlMain");
 }
 
 // String Extensions
 function String_Encode()
 {
     return this.replace(new RegExp("#","g"), "#0").replace(new 
                         RegExp(";","g"), 
 "#1");
 }
 String.prototype.Encode = String_Encode;
 
 function String_UnEncode()
 {
     return this.replace(new RegExp("#1","g"), ";").replace(new 
                         RegExp("#0","g"), "#");
 }
 String.prototype.UnEncode = String_UnEncode;
 
 // Let's run this puppy!
 main();
 
 ]]>
 </script> </job> </package>

Figure 4   Scripting Internet Explorer

Events
Description
BeforeNavigate2
This fires before the WebBrowser is about to navigate to a new site. If you have a page with links, you can use this event to validate the data before the next page loads, even canceling the load if the data doesn’t pass.
DocumentComplete
Fires when the page is fully loaded and displayed. At this point, it’s safe to modify the page.
DownloadBegin
If you have a complicated page that takes a while to load, throw up a progress dialog when this event fires.
DownloadComplete
Kill that progress dialog from the DownloadBegin event.
OnQuit
The browser quit, so the dialog is finished. Get your script moving again.
Methods
Description
Navigate
Directs the browser to a page. This is a basic command that you’ll need every time.
Stop
Stops everything without quitting. Good for progress dialogs when the main page finishes faster than expected.
Quit
Stops everything and quits. Good for getting out of the program when the user cancels the operation.
Properties
Description
Height, Width
Control the size of the dialog.
Top, Left
Control the placement of the dialog.
Visible
The browser control is initially invisible by default. You’ll need this property to show your work.
AddressBar, MenuBar, StatusBar, ToolBar
These aren’t needed by most dialogs, but the status bar can be useful.
FullScreen
For those really big forms.
Resizable
For those really big forms that want to stay big, or the really small ones that want to stay small.