Displaying the Results

As long as we get file names to consider for the final Scriptlet packaging, we store them in a listbox, whose reference we're passing in and out through the various subroutines. In particular, we're using a specialized function to add a new file name to the list. Before adding the name, this function performs some actions. For example, it checks whether the name already exists, and whether the file name is an HTML document. In this case, it adds the name to the list but runs a recursive routine to process its content.

Public Const LB_FINDSTRINGEXACT = &H1A2
Declare Function SendMessageString Lib "user32" Alias "SendMessageA" ( _
           ByVal hwnd As Long, _
           ByVal wMsg As Long, _
           ByVal wParam As Long, _
           ByVal lParam As String _
        ) As Long

' Add subroutine
Private Sub Add(ByVal list As ListBox, ByVal s As String)
  Dim errCode As Integer
    
  errCode = SendMessageString(list.hwnd, LB_FINDSTRINGEXACT, -1, s)
  If errCode = -1 Then
    list.AddItem s
    If InStr(1, s, ".htm") > 0 Then
       If InStr(1, s, "/") = 0 Or InStr(1, s, "\") = 0 Then
         s = App.Path + "\" + s
       End If
       WebBrowser2.Navigate s
    End If
    
  End If
End Sub

By means of the LB_FINDSTRINGEXACT message we can check whether the specified string already exists or not in the listbox. To do so, we make use of a specialized version of the Win32 API function SendMessage. In this case, we redeclared its fourth argument, and transformed it in As String instead of As Any. To avoid conflicts, we also declared an alias for this function.

Declare Function SendMessageString Lib "user32" Alias "SendMessageA" ( _
           ByVal hwnd As Long, _
           ByVal wMsg As Long, _
           ByVal wParam As Long, _
           ByVal lParam As String _
        ) As Long

This normally occurs in Visual Basic programming, and represents the Visual Basic counterpart of a well-known mechanism called "type-casting".

Using the LB_FINDSTRINGEXACT message means that you must specify a couple of parameters. The first one—known as wParam—is the starting position for the search. If you pass –1 then the search begins from the first item in the listbox. The second argument—usually referred to as lParam—is now the string to search for. The function returns –1 if fails. A failure means that the specified item doesn't exist in the listbox, so we can add it safely.

Applying Recursion

Immediately after inserting a new item into the listbox, we check the file name for a substring like .htm. In practice, we try to find out whether the file is an HTML document. If it is, then we need to scan it too, in a recursive manner.

If InStr(1, s, ".htm") > 0 Then
     If InStr(1, s, "/") = 0 Or InStr(1, s, "\") = 0 Then
         s = App.Path + "\" + s
     End If
     WebBrowser2.Navigate s
End If

As shown in the above listing, we apply recursion by using a second but hidden WebBrowser control. In the example, we add the current directory to the file name. This is needed to enable the WebBrowser to successfully navigate to the URL. While this is quite rare, however, you ought to make sure that the file name doesn't already include a path. To test whether a path is included, we must verify if a slash or a backslash is present somewhere in the string.

The application's current path is given by App.Path. You could also use the Win32 API function GetCurrentDirectory to find out about the current system directory.

Path and Protocol in File Names

You should consider that even if the HTML source code doesn't include a path, when accessing an element through the Dynamic HTML object model you find it, and a protocol prefix too!

For example, let's look at the following HTML code snippet:

<BODY>
This is a reference to <a href="testflex.htm">a new HTML file</a>.
</BODY>

This page includes a link to the local file testflex.htm. As you can see, there is no path and no protocol inside the file name. However, when you load the page through WebBrowser, and access its object model, the document.links collection returns

file:///c:/path/testflex.htm

as its first element. Note that the file name now includes the full original path and even a string denoting the protocol to access it. In this case, since it is a local file, we have file://. In addition, note that the slash replaced all the backslashes that are more usual in a path name.

This kind of processing takes place for all the elements recognized through the Dynamic HTML object model. Everything but the Scriptlets. In fact, if your page includes a Scriptlet then the data attribute that stores the name of the component remains unchanged.

This is the reason we sometimes need to add a path, as shown above, before instantiating a new WebBrowser control.

WebBrowser Must Be Visible

This second browsing object might not necessarily be visible. However, it's better to avoid using the most natural approach to hide a control. In fact, if you hide a WebBrowser control by setting its Visible property to False, then you won't be able to access its document object model.

To make it invisible you need to place it outside the visible portion of the form that actually contains it, or put the WebBrowser below another control.

© 1997 by Wrox Press. All rights reserved.