Browse DevX
Sign up for e-mail newsletters from DevX


Add a Touch of Web to Your Windows Applications  : Page 3

Learn to use the WebBrowser control to add Web-style navigational features to your Windows applications and access files on remote Web servers.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Building a Custom Browser in VB
The code in the sample OnLine Form resides in several event handlers. When a user selects a URL from the ComboBox control at the top of the form, the event handler executes the following statements to navigate to the selected site:

Private Sub Combo1_Change() If Combo1.ListIndex > -1 Then Screen.MousePointer = vbHourglass WebBrowser1.Navigate2 (URLs(Combo1.ListIndex)) End If End Sub

The Form's Load event handler populates the ComboBox control with the friendly names stored in the array named URLs. The code changes the cursor to an hourglass before calling the Navigate2 method. Subsequently, the control's NavigateComplete2 event handler (which fires when the load completes) resets the cursor to its normal shape:

Private Sub WebBrowser1_NavigateComplete2( _ ByVal pDisp As Object, URL As Variant) Screen.MousePointer = vbDefault End Sub

The form displays the document download progress on a Label control at the top of the form. The WebBrowser control's StatusTextChange event handler updates the Label caption. The WebBrowser fires the event every time the download status changes (this is the same text you see on the browser's status bar while a document is downloaded).

The Scrape Document button on the form demonstrates how to access various properties of the Document object. The code behind this button iterates through the elements of the Links collection and displays them in the Immediate window. It also iterates through the Images collection and downloads each image.

Downloading Remote Files
To download the images, the program uses the INet Control, which is the second of the Internet controls that come with VB6. Programming this control is fairly straightforward. You set its Protocol property to the desired protocol (usually HTTP for files on Web servers) and then call its OpenURL method to download the response into a Byte array:

<span class="pf">Inet1.Protocol = icHTTP Inet1.URL = WebBrowser1.Document.images.Item(i).href b() = Inet1.OpenURL(, icByteArray)</span>

The first argument of the OpenURL method is optional, because it's the URL of the document you want to view. In the preceding example the URL has already been specified with the URL property so there's no need to repeat it in the OpenURL method. After the array is populated with the remote file's bytes, you can store it to a local file. See the sample project's listing for the complete code that stores the image's bitmap to a file.

The Scrape Document button's Click event handler should not be reentrant (it shouldn't be invoked before it has terminated). In addition, users shouldn't click this button before the requested page has been completely downloaded. You can disable the button when the handler starts executing and enable it before exiting the handler. The sample application examines the value of the WebBrowser1.Busy and Inet1.StillExecuting properties. If either property is True, the code exits immediately.

Rendering HTML Documents on the Fly
Every time you navigate to a new HTML document with the WebBrowser control, it automatically renders the document. To render a document on the fly, you simply assign the appropriate text to the control's Document property. To do so, use the Document object's Write and WriteLine methods. For example to render the text entered by the user in the TextBox1 control, you can use the following statements:

HTMLString = TextBox1.Text WebBrowser1.Document.script.Document.Clear WebBrowser1.Document.script.Document.Write HTMLString WebBrowser1.Document.script.Document.Close

An interesting feature of the Browser form is that you can change the relative sizes of the TextBox and WebBrowser controls to make more room for one of them. Actually all the forms of the sample application are resizable. You can find the necessary code in the Resize event handler of each form.

Creating a Data-Bound HTML Form
The most practical use of the WebBrowser control is to create HTML interfaces for your Windows applications. These interfaces can include rich graphical elements, hyperlinks, and even multiple frames. You can place practically any HTML document on a form with the help of this control. One way to interact with users is to intercept clicks on hyperlinks in the HTML document from within your VB code, and that's exactly what you'll see how to do in this section. When a user clicks a hyperlink in the WebBrowser control, the control fires the BeforeNavigate2 event. You can then handle the click by inserting the appropriate code in the event's handler.

Creating the data-bound form of Figure 3 is quite trivial if you've ever written an ASP script to display a Recordset as an HTML document. Basically, you map each row of the Recordset to a new row in an HTML table and map each field in the current record to a cell in the table row. The following code shows the outline of the code to display Recordset contents in an HTML table:

Dim iCol As Integer Output("<TABLE>") RS.MoveFirst While Not RS.EOF For iRow = 0 To Rows -- 1 Output("<TR>") For iCol = 0 To RS.Fields.Count -- 1 Output("<TD>") Output(RS.Fields(ICol).Value) Output("<\TD>") Next Output("<\TR>") RS.MoveNext Next Output("<\TABLE>")

The procedure Output() renders its argument on the control's surface by calling the Document object's Write method.

The sample code uses a method similar to the preceding code to render each category as a hyperlink. The hyperlink's destination (its href attribute) is CATEGORYID and the ID of the selected category is embedded into the hyperlink as a parameter value. Here's what the category hyperlinks look like in the document as rendered in the form's left pane:


You don't need to use a parameter name, because the hyperlinks don't reference a URL on a Web server; instead, they're intercepted by the project's code, from within the BeforeNavigate2 event handler of the first WebBrowser control. That event handler (shown in Listing 1) extracts the ID of the selected category from the URL, retrieves the matching rows from the Products table and then renders them as a table in the second WebBrowser control on the form.

You can examine the complete code that populates the two WebControls on the form in the sample project, but the most interesting part is how the code formats the Sales hyperlink. Again, the link doesn't lead to another document, instead, when the user clicks the Sales hyperlink, the code must intercept the event and update the contents of the two TextBox controls at the bottom of the form. Here's the string sent to the Document object's Write method to generate the hyperlink:

HTMLText = HTMLText & _ "<TD><A HREF=ShowSales?" & _ RS.Fields(0).Value & _ ">Sales</A></TD>"

The preceding code creates a hyperlink to the "ShowSales" URL. When these statements are executed, they will generate a hyperlink like the following (the code shown below corresponds to the Sales hyperlink in front of the product "Rossle Sauerkraut"):

<TD><A HREF=ShowSales?28> <FONT FACE='VERDANA' SIZE=2>Sales</FONT></A></TD>"

Clicking a hyperlink causes the browser to request the URL specified in the link's href attribute. But you don't want the browser to make the request, because that URL doesn't exist—it's not a "real" URL. To intercept the browser from within your code before it makes a Web request, use the BeforeNavigate2 event and extract the destination of the hyperlink. Because you're going to provide the browser with content via your code, you can cancel the browser navigation by setting the Cancel parameter to True within the body of the event handler. Listing 1 shows how to intercept a request

The event handler then calls the ShowSales() subroutine, which executes the ProductSales stored procedure and updates the two TextBox controls at the bottom of the form. The code below shows the ProductSales stored procedure.

Author Note: You must create the ProductSales stored procedure in your Northwind database before using it in your code.

CREATE PROCEDURE dbo.ProductSales @ProductID int, @Units int OUTPUT, @Revenue decimal(12,2) OUTPUT, @Name varchar(100) OUTPUT AS DECLARE @ProdName varchar DECLARE ProductSales CURSOR KEYSET FOR SELECT SUM([Order Details].Quantity), SUM([Order Details].UnitPrice* [Order Details].Quantity* (1-[Order Details].Discount)), Products.ProductName FROM [Order Details] INNER JOIN Products ON Products.ProductID = [Order Details].ProductID WHERE [Order Details].ProductID=@ProductID GROUP BY ProductName OPEN ProductSales FETCH FIRST FROM ProductSales INTO @Units, @Revenue, @Name

As you can see it's very easy to take advantage of the functionality of the WebBrowser control in your Windows forms and exploit the Web navigational model in your Windows applications. If you've ever written ASP applications, and most of us have, you can apply your knowledge to VB applications. Notice that you're not limited to HTML tables. The WebBrowser control can display any HTML document, which means you can add create image hyperlinks, image maps, you can even embed scripts in your VB applications.

You can use any ActiveX control—including the WebBrowser control—on a .NET form. When you select an ActiveX control to add to the Toolbox, the .NET Common Language Runtime (CLR) creates a wrapper for the ActiveX control. You can then use it with the new Windows Form Designer, placing the WebBrowser control on a Windows form and programming its navigational methods in much the same manner as described in this article. However, the WebBrowser control delivered with VB6 doesn't fire the BeforeNavigate2 event, which is crucial for programming the control on a Windows form. Fortunately, this is a known problem and you can find a fix for it here: BUG: The BeforeNavigate2 Event of the WebBrowser Control Does Not Fire If Hosted in a Visual Basic .NET Application

Evangelos Petroutsos  is a long-time VB developer. When he's not writing code, he writes programming books and articles. His most recent title is Mastering Visual Basic .NET, published by Sybex. You can reach him at pevangelos@yahoo.com.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date