Home » July 2013
Visual Basic 24a - Changing The Style Of Html Elements

New project.

Main form size around 670, 420
Add a button on the top-left of the form, text: Change
Add a button to the right of the previous one, text: Active
Add a webbrowser to the form below the button, size 615, 230,  anchor: Top, Bottom, Left, Right
Below the webbrowser, add a textbox, multiline: yes,  size: 615, 50,   anchor: Bottom, Left, Right,   scrollbars: Vertical

If you have done example 24 then you can use the same html file for this example too. Otherwise, open notepad, insert the html code present on the bottom of the Visual Basic 24 post, and save as "Elements.html" to your hard drive. Double click on the file, load in defaul browser and copy the file address from the browser's address bar.

On the design page, double click on the main form and insert:
WebBrowser1.Navigate("")
- inside the quotation marks paste the file address. You can always use a website if you prefer it instead.

Double click on the "Change" button, add this inside:
WebBrowser1.Document.Body.Style = "background-color:green"

Double click on the "Active" button, add this to the sub:
TextBox1.Text = WebBrowser1.Document.ActiveElement.Style

- start program,  click the "Change" button, the background color of the html's body should change.
Click on the page's background, then click the "Active" button. You should get "BACKGROUND-COLOR: green" into the textbox. If an element does have a specific style written in the html code, then the "style" property will retrieve it, otherwise you'll get nothing.

We can't use this line directly:
WebBrowser1.Document.GetElementsByTagName("div").Style  - because GetElementsByTagName takes a group of elements, not a specific single one we would like to change.

Change the content of the button1 sub into this:
WebBrowser1.Document.GetElementById("885037_gm4").Style = "background-color:blue"

- the "GetElementById" method points to a single element determined by it's id, that's why the "style" property will work. If you want to know all the possible styles you can set for a web page, look for "CSS" in google. CSS stands for: "Cascading Style Sheet". CSS Resource Page.  It's standardly used in the html code to change the display of html elements. It is also used to reduce the repetitive code of html elements.

(If you are navigating a website, you will have to find an id in the source code to test the above line)

This would also work:
WebBrowser1.Document.GetElementsByTagName("input").Item(1).Style = "background-color:blue"
- the second "input" element is going to be changed

Change the code of the button1 sub again:
For Each i In WebBrowser1.Document.GetElementsByTagName("input")
i.Style = "border: 2px solid rgb(255,0,0)"
If i.GetAttribute("id") = "885037_gm4" Then
i.Style = "background-color:yellow"
End If
Next

- start program, press "Change" button. All the "input" elements will get their background changed. Also, when the "id = "885037_gm4" is found, then the old styling of that element removed and the new will be inserted. This happens because we don't append to the new style, so we end up replacing it.

In order to add a new style to the old one, take this line from the "For Each" loop:
i.Style = "background-color:yellow"
and change it into this:
i.Style = i.Style & ";background-color:yellow"

- now the "input" element will get the new style while keeping the old one. Remember to write the semi-colon sign ";" when appending.  After clicking the "Change" button, click into the input box and press the "Active" button.

Why it's better to append?
If the element doesn't have any CSS code, then giving it a complete new style rather than appending it will not make any difference: the html element will just receive the new style.
If we are only changing the background color and the only styling code that the element has is the background color, then everything is fine again: we will just set a new background color.
The problem starts when the element has more CSS style elements than the ones we are trying to change, or if it has different ones than the ones we are trying to change.
for example, a html element might have a style set for the border, margin, padding, font and display while we are just trying to change it's background with: i.Style = "background-color:yellow" -> this will erase all the previous style code and only insert the background-color: yellow inside. That's why it's better to use: i.Style = i.Style & ";background-color:yellow"  in order to add the new style to the previous ones or to only change the background, if it's already present, without erasing everything else.

Add another button to the form on the right of the "Active" button, text: "Active Change", add this:
WebBrowser1.Document.ActiveElement.Style = "border: 2px dashed #31D4B8; background-color:MediumSeaGreen; font-family:Century Gothic"

- click on an element and then press the button. This is how we add more styles to the element with one single code line. You can use hexadecimal codes for colors as well, google: "hex color picker". The CSS language already has a number of color variants stored under very creative names: Check This Page.

Since not all elements in the source code have a defined style, it would be nice to find out the ones which do.

Add a button on the right of the "Active Change" button, text: Check For Styles, add this inside:
For Each i In WebBrowser1.Document.All
If Len(i.Style) > 0 Then
TextBox1.Text = TextBox1.Text & "Name: " & i.TagName & ", Style Length: " & Len(i.Style) & vbCrLf
End If
Next

- start the program, press the "Change" button, press the "Active Change" button and then press the "Check For Styles" button. Make the textbox larger if necessary.
This will give you the name and the style length of the elements that do have a style code. This loop might take it's time when used on websites with a high amount of data. The "Len" function returns the length of a string even if the value of the string is null (length will be zero).
You can't change the condition of the "if" statement to:  i.Style.Length > 0  ->  because when a null string is encountered, the "Length" property will not be able to process it and that will crash the program.
vbCrLf - is a visual basic constant for the new line, same as: "vbnewline"

Another variation of the above code would be:
For Each i In WebBrowser1.Document.All
If String.IsNullOrEmpty(i.Style) = False Then
TextBox1.Text = TextBox1.Text & "Name: " & i.TagName & ", Style Length: " & i.Style.Length & vbCrLf
End If
Next

- if the "Style" string is not null, then take the length of "Style" and insert it into the textbox.
We could have also used:  
If i.Style IsNot Nothing Then ...
or
If i.Style <> Nothing Then ...
or:   
If IsNothing(i.Style) = False Then ...

Erasing all the CSS style code from the html elements can be done this way:
If Len(i.Style) > 0 Then
i.Style = Nothing
End If
- using: i.Style = "" also works. Actually, inserting anything that is not a proper CSS style code into the ".Style" string will erase the whole styling code of the element. example: i.Style = "some random words"

We know now how to add a value to an element without any style code (adding with equality or appending), how to add a new value to an element that already has other style sets (append), how to change the value of an already present style set without erasing everything else (append), how to find which elements do have some styling code rather than none, how to erase the style code.

Once we have found the elements that do have the CSS code in them, we can search their strings for what we need. We might be looking for a certain style change in all of them like "background-color" (for any color) or a style change with a specified value like "background-color: red".

Add another button to the form, text: Change If Green, add this to the sub:
For Each i In WebBrowser1.Document.All
If IsNothing(i.Style) = False Then
If i.Style.Contains("BACKGROUND-COLOR: mediumseagreen") = True Then
i.style = i.style & "; background-color: red"
TextBox1.Text = i.style
End If
End If
Next

- press the "Active Change" button to change the background color then press this button.
- first "if" statement: we only check the elements that have the style code, second "if" statement: we use the "contains" function to find what we need within the string, if it's found, then the style is changed by appending the new one in.
It's very important to have the right character casing inserted into the "contains" function, otherwise we won't get what we want. The style property, on the left, has to have uppercase letters while the value of the property has to have lowercase letters. There is one colon and a space symbol between them.

Instead of using:
i.style = i.style & "; background-color: red"
we could have used the "Replace" function for changing strings:
i.Style = i.Style.Replace("BACKGROUND-COLOR: mediumseagreen", "BACKGROUND-COLOR: red")

Let's retrieve the value of a specified style element out of all the html elements.
Between the buttons on your from and the webbrowser, make some space for a textbox, no multilne is required, size around: 270, 20.

On the right of the textbox, add a button, text: Find, double click on it, add this:
Dim gg
Dim aa As String = ""
TextBox1.Clear()

For Each i In WebBrowser1.Document.All
If i.Style <> Nothing Then
gg = InStr(1, i.style, "BACKGROUND-COLOR")
If gg > 0 Then
gg = InStr(gg, i.style, " ") + 1

While Mid(i.style, gg, 1) <> ""
If Mid(i.style, gg, 1) = ";" Then
Exit While
End If
aa = aa & Mid(i.style, gg, 1)
gg = gg + 1
End While

TextBox1.Text = TextBox1.Text & "Element Name: " & i.tagname & ",  Value found: " & aa & vbCrLf
aa = ""
gg = 0
End If
End If
Next

- start program, press the "Change" button, click on an "input" element without any background color, press the "Active Change" button, just make sure you have a few elements with background color changed, press the "Find" button. We used two functions for changing strings in this sub: InStr (Resource) and Mid (Resource).

First we declared the "gg" variable which contained the value 0, then we declared"aa" which had to have at least an empty value stored inside since we add characters to it later on. The "For Each" loop checks all elements, while the first "if" statement allows only the ones with the style code through.

gg = InStr(1, i.style, "BACKGROUND-COLOR")  - InStr returns an integer value (a number). In our case, InStr starts at string index "1" (it must be at least 1, zero is not acceptable), it checks the "i.style" string and looks for the background term present as the third parameter. When that term is found, the index of the first character of the term ("B") inside the string will be returned. We store that number in "gg".
If the third parameter is not found, InStr will return zero.

If gg > 0 Then   -  the condition of this statement is only true if a background color has been previously found.
gg = InStr(gg, i.style, " ") + 1   - the new InStr function starts at the index position of the first character of "background-color" inside the string, then it looks for the next "space" symbol in the "i.style" string, once it's found, we get the index of that symbol and we raise the "gg" variable by 1. example: BACKGROUND-COLOR: red - the index will now be set to the "r" character, which is the beginning of the style value.

While Mid(i.style, gg, 1) <> ""  - we use the Mid function to retrieve a certain amount of characters from a string right after the specified index position. In this case, we search the "i.style" string, we start at the beginning of the style value and we are taking only "1" character with the function. If the found character becomes "" -> which means empty, then the while loop stops. The value only becomes empty when we reach the end of the "i.style" string.
If Mid(i.style, gg, 1) = ";" Then  - Exit While    ->  stops the loop if the semi-colon is found. If there are additional style changes in the html element after the onw we were looking for, the semi-colon will be found between those style sets. example:  ... BACKGROUND-COLOR: red; FONT.FAMILY: arial; BORDER-TOP: solid;  ...
aa = aa & Mid(i.style, gg, 1)  - this will add the characters of the value we were searching for into a word.
gg = gg + 1  - raises the index number for the Mid function, giving us a new character every time

After that, we store the name of the element and the style value into the textbox. "aa" and "gg" are reset to their starting positions.

Instead of using:
gg = InStr(gg, i.style, " ") + 1
we could have used:
gg = gg + "BACKGROUND-COLOR: ".Length

"BACKGROUND-COLOR: ".Length  - the "Length" property will calculate the number of characters present inside the quotation marks.

Inside the button6 sub, just below this declaration:
Dim aa As String = ""
add this:
Dim bb As String = TextBox2.Text
If bb = "" Then
Exit Sub
End If
bb = UCase(bb)
bb = Trim(bb)

Also, change this code line inside the "for each" loop:
gg = InStr(1, i.style, "BACKGROUND-COLOR")
into:
gg = InStr(1, i.style, bb)

- we store the content of the new textbox we added into "bb". If there was nothing written in the textbox - exit the sub. We change the casing of the text to uppercase ("Ucase(bb)") and also we remove all the potential "space" symbols at the beginning and at the end of the textbox text ("Trim(bb)").

Start the program. Change the style of a few html elements and then write into the new textbox something like this:
        background-color
- lowercase, no colon sign, add spaces at the beginning and at the end. Press the "Find" button. Should work.

The problem is that we have to specify the exact name of the style, for example: border-bottom instead of just: border. Also, If we write, for example, "top" it will still give us the values of all the codes that contain the "top" term.  This sub still needs some modifications to work properly.

Perhaps adding "-" at the end if there is no such symbol found in the textbox. Then we should retrieve all the instances of the "(one word)-" in the style code, determine the properties and also get their values.

Code:

    Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    WebBrowser1.Navigate("file:///D:/Elements.html")
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    For Each i In WebBrowser1.Document.GetElementsByTagName("input")
    i.Style = "border: 2px solid rgb(255,0,0)"
    If i.GetAttribute("id") = "885037_gm4" Then
    i.Style = i.Style & ";background-color:yellow"
    End If
    Next
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    TextBox1.Text = WebBrowser1.Document.ActiveElement.Style
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    WebBrowser1.Document.ActiveElement.Style = "border: 2px dashed #31D4B8; background-color:MediumSeaGreen; font-family:Century Gothic"
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    For Each i In WebBrowser1.Document.All
    If String.IsNullOrEmpty(i.Style) = False Then
    TextBox1.Text = TextBox1.Text & "Name: " & i.TagName & ",  Style Length: " & i.Style.Length & vbCrLf
    End If
    Next
    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
    For Each i In WebBrowser1.Document.All
    If IsNothing(i.Style) = False Then
    If i.Style.Contains("BACKGROUND-COLOR: mediumseagreen") = True Then
    i.style = i.style & "; background-color: red"
    'i.Style = i.Style.Replace("BACKGROUND-COLOR: mediumseagreen", "BACKGROUND-COLOR: red")
    TextBox1.Text = i.style
    End If
    End If
    Next
    End Sub

    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
    Dim gg
    Dim aa As String = ""
    Dim bb As String = TextBox2.Text
    If bb = "" Then
    Exit Sub
    End If
    bb = UCase(bb)
    bb = Trim(bb)
    TextBox1.Clear()

    For Each i In WebBrowser1.Document.All
    If i.Style <> Nothing Then
    gg = InStr(1, i.style, bb)
    If gg > 0 Then
    gg = InStr(gg, i.style, " ") + 1
    While Mid(i.style, gg, 1) <> ""
    If Mid(i.style, gg, 1) = ";" Then
    Exit While
    End If
    aa = aa & Mid(i.style, gg, 1)
    gg = gg + 1
    End While
    TextBox1.Text = TextBox1.Text & "Element Name: " & i.tagname & ",  Value found: " & aa & vbCrLf
    aa = ""
    gg = 0
    End If
    End If
    Next
    End Sub

    End Class


Visual Basic 23a - More On Website Data Retrieval

New project.

Main form size: 840, 440. windowstate: Maximized
Add a textbox on top. Size around 300, 20
Add a button on the right of the textbox. Text: Navigate
Add a webbrowser below the first textbox,  size: 750, 160,  anchor: Top, Bottom, Left, Right
Add another textbox below the first webbrowser. size around 750, 100,  anchor: Bottom, Left, Right,   scrollBars: Vertical

You can use the wikipedia homepage as the testing website.

Double click the navigate button:
WebBrowser1.Navigate(TextBox1.Text)
TextBox2.Clear()

Double click on the webbrowser, add this:
For Each i In WebBrowser1.Document.All
If i.getattribute("classname").Length > 0 Then
TextBox2.AppendText(i.getattribute("classname") & vbNewLine)
End If
Next

- this will give you all the values for the "class" attribute.
After using it, turn this code (webbrowser sub) into comments with the ' symbol.

Add another button on the right of the "Navigate" button, text: Active Element. Resize the button to fit the name inside. Double click the button, add this:
MsgBox(WebBrowser1.Document.ActiveElement.TagName)

- start program, navigate to a site, click on various parts of the site to move the focus around and press the button. You should get the name of the html element.

Add 2 more buttons to the right of the "Active Element" button, text of the first button: "OuterHtml", text of the second button: "InnerHtml"

Double click on button3, named "OuterHtml", insert into the sub:
MsgBox(WebBrowser1.Document.ActiveElement.OuterHtml)

Double click on the "InnerHtml" button:
MsgBox(WebBrowser1.Document.ActiveElement.InnerHtml)

- click on various parts of the navigated website and press those buttons. If the specific html section you have chosen is large, you might have to wait a while for the webbrowser to pickup the html code.

You should notice that the innerhtml contains the same code that the outerhtml has except for the first parent element.
For example:
<li  various attributes> <a various attributes> Some text here </a> </li>

- <li> will be the "parent" html element of <a>, while <a>, and all the other elements in <a>, are regarded as the "children" of <li>. If you try to get the inner and outer html for the same focused location, then the "innerhtml" will be missing it's first parent, that's what the "inner" represents.

Try to press and hold the left mouse button on a link, move away from the link with the cursor without pressing it down and then release it. Press the "OuterHtml" and "Innerhtml" buttons.

Go to the "Innerhtml" button sub and add another msgbox alert below the first one:
MsgBox(WebBrowser1.Document.ActiveElement.InnerText)

- "innertext" doesn't take the html code, only the textual content present on the site. This option is very good for those who just want to retrieve the readable sections of a website and store them into a textbox or a file. A good idea would be downloading the latest news from a news site, or the latest site updates.

Let's retrieve all the focusable elements from a webpage.

Above the webbrowser sub, in the declaration area, insert this:
Dim g

Go to the webbrowser sub, below the previous comments add:
For Each i In WebBrowser1.Document.All
i.focus()
g = g + 1
TextBox2.Text = TextBox2.Text & "Name: " & WebBrowser1.Document.ActiveElement.TagName & vbNewLine
Next
WebBrowser1.Document.ActiveElement.RemoveFocus()
MsgBox(g)

- start the program and try the button. The problem with this "for each" loop is that it will get the name of all elements rather than the focusable elements only. There is much more elements present on the page than the ones you can focus on (switch to with the tab key). So, the first html element appears in the loop, we switch to it's focus location, the loop goes forward to the next element, we focus again but the focus goes to the same location as before, this can happen a couple of times until it finally moves to a new location.

Inside the webbrowser sub, at the start, declare this:
Dim kk As New Point

- New Point holds two integer values that represent the "x" and "y" coordinates on the screen, since we haven't put anything in the brackets during declaration, the default location is going to be (0,0). So, the "kk" variable carries the (0, 0) coordinates at the moment. 

Take all the content of webbrowser sub and put it inside this "if" statement:
If g = 0 Then
End If

- if the navigated website is triggering the webbrowser sub more than once this will stop it. The webbrowser code will obviously only go through once when the program is started, after that, "g" will be higher than 0. You will have to add  "g = 0" to the "navigate" button and press it again for the code to do this part again. Also you should clear the textbox there.

Inside the webbrowser select this 2 lines:
g = g + 1
TextBox2.Text = TextBox2.Text & "Name: " & WebBrowser1.Document.ActiveElement.TagName & vbNewLine
and and paste this over them:
If WebBrowser1.Document.ActiveElement.OffsetRectangle.Location <> kk Then
g = g + 1
TextBox2.Text = TextBox2.Text & "Name: " & WebBrowser1.Document.ActiveElement.TagName & vbNewLine
TextBox2.Text = TextBox2.Text & "Location: " & WebBrowser1.Document.ActiveElement.OffsetRectangle.Location.ToString & vbNewLine
TextBox2.Text = TextBox2.Text & "Element Size: " & WebBrowser1.Document.ActiveElement.OffsetRectangle.Size.ToString & vbNewLine
TextBox2.Text = TextBox2.Text & "Focused Element Number: " & g & vbNewLine & vbNewLine
End If
kk = WebBrowser1.Document.ActiveElement.OffsetRectangle.Location

- what the new "if" statement does: it compares the location of the current html element which the "for each" loop has taken with the location of the previously taken element (although the first "kk" location is 0,0) -> if they are different -> then write the attributes of the new element into the textbox.
Below the "if" statement we update the "kk" variable with the location of the new element.
WebBrowser1.Document.ActiveElement.OffsetRectangle - this method holds the location and the size of the currently active element.
- we retrieve the location and size here, but we could have specified and taken x, y, height or width instead.

Start the program and navigate to a website. The "g" value should now be lower than before.
Technically, there might repetition of the same focusable elements because that's just how some web pages tend to be structured, if you keep pressing the "tab" key on your keyboard you might eventually come back to an already focused location.

Let's get the attribute of an element we hover over with the mouse pointer.

For the sake of time, go to the webbrowser sub and turn the event it has:
Handles WebBrowser1.DocumentCompleted
into a comment:
'Handles WebBrowser1.DocumentCompleted

- this will disable the sub, you should re-enable it at the end of this post.

Below the button4 sub, declare this:
Dim g1

Add a button below the "Navigate" button, text: Start hover.  Double click on this button, add this:
If g1 = 1 Then
RemoveHandler WebBrowser1.Document.MouseOver, AddressOf aa1
Button5.Text = "Start Hover"
g1 = 0
Exit Sub
End If
AddHandler WebBrowser1.Document.MouseOver, AddressOf aa1
Button5.Text = "End Hover"
g1 = 1

- we add the mouseover event to our webbrowser document. The sub that will be handling the event will be "aa1". The first click on the button adds the event, the second click stops the process.

Create the "aa1" sub below the previous sub:
Private Sub aa1(ByVal sender As Object, ByVal e As System.Windows.Forms.HtmlElementEventArgs)
TextBox2.Clear()
TextBox2.Text = WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).TagName & vbNewLine
TextBox2.Text = TextBox2.Text & WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).GetAttribute("href")
End Sub

- this sub will only do it's job once we add the mouseover event by pressing the "Start Hover" button.
We can hover over a html element, get it's name and also get the link it holds (if it has one).
WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition) - this allows us to retrieve data from a html element by using the mouse position. If you wanted to get the name of an element resting on some specific coordinates you knew, like: 50, 70,  you would have written:
MsgBox(WebBrowser1.Document.GetElementFromPoint(New Point(50, 70)).TagName)

Below the aa1 sub declare this:
Dim g2

Add another button on the right of the "Start Hover" button, text: Start Click, double click on it:
If g2 = 0 Then
TextBox2.Clear()
AddHandler WebBrowser1.Document.Click, AddressOf aa2
WebBrowser1.AllowNavigation = False
Button6.Text = "End Click"
g2 = 1
Exit Sub
End If
RemoveHandler WebBrowser1.Document.Click, AddressOf aa2
WebBrowser1.AllowNavigation = True
Button6.Text = "Start Click"
g2 = 0

- this button will add the click event to the "aa2" sub and stop all navigation. This allows us to click on links without moving away from the main page.

Create the "aa2" sub:
Private Sub aa2(ByVal sender As Object, ByVal e As System.Windows.Forms.HtmlElementEventArgs)
If WebBrowser1.Document.ActiveElement.GetAttribute("href").Length > 0 Then
TextBox2.Text = TextBox2.Text & WebBrowser1.Document.ActiveElement.GetAttribute("href") & vbNewLine
End If
End Sub

- we collect the link of every element that has one into the textbox.

Code:


    Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Navigate(TextBox1.Text)
    End Sub

    Dim g

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    If g = 0 Then
    Dim kk As New Point

    'For Each i In WebBrowser1.Document.All
    'If i.getattribute("classname").Length > 0 Then
    'TextBox2.AppendText(i.getattribute("classname") & vbNewLine)
    'End If
    'Next

    For Each i In WebBrowser1.Document.All
    i.focus()
    If WebBrowser1.Document.ActiveElement.OffsetRectangle.Location <> kk Then
    g = g + 1
    TextBox2.Text = TextBox2.Text & "Name: " & WebBrowser1.Document.ActiveElement.TagName & vbNewLine
    TextBox2.Text = TextBox2.Text & "Location: " & WebBrowser1.Document.ActiveElement.OffsetRectangle.Location.ToString & vbNewLine
    TextBox2.Text = TextBox2.Text & "Element Size: " & WebBrowser1.Document.ActiveElement.OffsetRectangle.Size.ToString & vbNewLine
    TextBox2.Text = TextBox2.Text & "Focused Element Number: " & g & vbNewLine & vbNewLine
    End If
    kk = WebBrowser1.Document.ActiveElement.OffsetRectangle.Location
    Next
    WebBrowser1.Document.ActiveElement.RemoveFocus()
    MsgBox(g)
    End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    TextBox2.Text = WebBrowser1.Document.ActiveElement.TagName
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    MsgBox(WebBrowser1.Document.ActiveElement.OuterHtml)
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    MsgBox(WebBrowser1.Document.ActiveElement.InnerHtml)
    MsgBox(WebBrowser1.Document.ActiveElement.InnerText)
    End Sub

    Dim g1

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
    If g1 = 1 Then
    RemoveHandler WebBrowser1.Document.MouseOver, AddressOf aa1
    Button5.Text = "Start Hover"
    g1 = 0
    Exit Sub
    End If
    AddHandler WebBrowser1.Document.MouseOver, AddressOf aa1
    Button5.Text = "End Hover"
    g1 = 1
    End Sub

    Private Sub aa1(ByVal sender As Object, ByVal e As System.Windows.Forms.HtmlElementEventArgs)
    TextBox2.Clear()
    TextBox2.Text = WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).TagName & vbNewLine
    TextBox2.Text = TextBox2.Text & WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).GetAttribute("href")
    End Sub

    Dim g2

    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
    If g2 = 0 Then
    TextBox2.Clear()
    AddHandler WebBrowser1.Document.Click, AddressOf aa2
    WebBrowser1.AllowNavigation = False
    Button6.Text = "End Click"
    g2 = 1
    Exit Sub
    End If
    RemoveHandler WebBrowser1.Document.Click, AddressOf aa2
    WebBrowser1.AllowNavigation = True
    Button6.Text = "Start Click"
    g2 = 0

    End Sub

    Private Sub aa2(ByVal sender As Object, ByVal e As System.Windows.Forms.HtmlElementEventArgs)
    If WebBrowser1.Document.ActiveElement.GetAttribute("href").Length > 0 Then
    TextBox2.Text = TextBox2.Text & WebBrowser1.Document.ActiveElement.GetAttribute("href") & vbNewLine
    End If
    End Sub

    End Class


Start the program, navigate to a site. See how the buttons work.

Visual Basic 24 - Changing The Attributes Of Html Elements

New project.

Add a button on top of your main form. Text: Navigate.
Add a web browser to your form, make it large enough.

Go to your hard drive and create a new text document: Right mouse click -> New -> Text Document.
Open the document and insert this inside:
<html>
<body>

<input name="input1box" size="20" maxlength="24">

</body>
</html>

Go to File -> Save As -> Change "Save as Type" to: All Files -> "Filename": Elements.html  -> Save.
Double click on the new "Elements.html" file to open it in your default web browser.
One input box should be the only thing appearing in the html page.
Copy the address from the address bar of your web browser.

Go to design page, double click on the "Navigate" button, and write this inside:
WebBrowser1.Navigate("")

- inside the quotation marks paste your "Elements.html" address.
Start the program, press the button and see if the html input textbox is there.
Go to your hard drive, right click on the "Elements.html" file and choose "Notepad", if this choice is not present in your context menu, click "choose default program" and find "Notepad.exe" in C:\windows.
Keep the html file opened.

We can see that the textbox has 3 attributes: name, size and maxlength. It doesn't have to have any, it could simply be written: <input>. If we don't change any attributes, they will be set to their default value.
The attribute called "value" in the html code is like the "text" property in visual basic. When we change it, we change the text of an input box or a button or anything else. In this example, the value attribute is not determined, so the input box is empty.

Double click on the Web Browser control in the design page, insert this:
For Each i In WebBrowser1.Document.All
If i.GetAttribute("name") = "input1box" Then
i.SetAttribute("value", "Something")
End If
Next

- we look through all the elements of the html page, if we find one that has a "name" equal to "input1box" then we change it's "value" attribute to "Something".
We could have looked for the element by using any of the attributes that are present in it's code, and then set a new value to any of the attributes that the input box can have. (Resource) 

Go to your Elements.html file, change this line:
<input name="input1box" size="20" maxlength="24">
into this:
<input name="input1box" size="20" maxlength="24"> </br>
<input id="885037_gm4" name="box2" size="26">

- save the .html file. We should now have two textboxes when we navigate to our "elements" file.
</br> adds a new line. The new input box has the "id" attribute, which is also found in source codes of many websites. It must have a unique value on the web page, and because of that we have a method that can help us search elements through it and change their attributes.

Inside the webbrowser sub, below "next", add this:
WebBrowser1.Document.GetElementById("885037_gm4").SetAttribute("value", "the new text")

- we find the element by it's unique id and change one of it's attributes.

Change the .html code again, add this below the previous one:
<input id="885037_gm7"class="textbox" placeholder="search" tabindex="1"></br>
<input type="submit" onclick="alert('Clicked')"> </br>

- adds another input box and a button created with the "input" tag.

Go to the web browser sub, inside the "for each" loop, below the previous "if" statement add this:
If i.GetAttribute("id") = "885037_gm7" Then
i.Focus()
End If

- start program, click the "navigate" button, the third input box will have the blinking text cursor placed inside.

Add another "if" statement below the previous one:
If i.GetAttribute("type") = "submit" Then
i.InvokeMember("click")
End If

i.InvokeMember("click") - this is the code we will use to click on a html button element.
onclick="alert('Clicked')" - will confirm to us that the button has been clicked.
Using the message box might remove the focus from the previous html textbox.

Go to the html file again, add this:
<button onclick="alert('Clickerr')"> Press </button> </br>

<select id="sel_44313">
  <option value="first">First</option>
  <option value="second">Second</option>
  <option value="third">Third</option>
  <option value="fourth">Fourth</option>
</select></br>

<select id="new id 553">
  <option value="1">Car</option>
  <option value="2">Tree</option>
  <option value="3">Person</option>
  <option value="4">Dog</option>
</select>

- save file. This will add a regular html button to the html page, and 2 comboboxes with choices.

Inside the "for each" loop of the webbrowser sub, add this:
If i.InnerText = "Press" Then
i.SetAttribute("innertext", "Click instead")
i.Focus()
SendKeys.Send("{ENTER}")
End If

- we find the element by it's inner text and then we modify it. We also transfer the cursor focus to the button and send the "enter" key to press on it, instead of using a mouse click.

Below the "for each" loop insert this:
For Each i In WebBrowser1.Document.GetElementsByTagName("select")
If i.GetAttribute("id") = "sel_44313" Then
i.SetAttribute("value", "third")
ElseIf i.GetAttribute("id") = "new id 553" Then
i.SetAttribute("value", 4)
End If
Next

- we find the comboboxes by their "id" numbers, and change their selected item.

HTML code for "Elements.html":

    <html>
    <body>

    <input name="input1box" size="20" maxlength="24"> </br>
    <input id="885037_gm4" name="box2" size="26"></br>

    <input id="885037_gm7"class="textbox" placeholder="search" tabindex="1"></br>
    <input type="submit" onclick="alert('Clicked')"></br>

    <button onclick="alert('Clickerr')"> Press </button> </br>

    <select id="sel_44313">
     <option value="first">First</option>
     <option value="second">Second</option>
      <option value="third">Third</option>
    <option value="fourth">Fourth</option>
    </select></br>

    <select id="new id 553">
    <option value="1">Car</option>
    <option value="2">Tree</option>
    <option value="3">Person</option>
    <option value="4">Dog</option>
    </select>

    </body>
    </html>


Visual basic code:

    Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Navigate("file:///D:/Elements.html")
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    For Each i In WebBrowser1.Document.All
    If i.GetAttribute("name") = "input1box" Then
    i.SetAttribute("value", "Something")
    End If
    If i.GetAttribute("id") = "885037_gm7" Then
    i.Focus()
    End If
    If i.GetAttribute("type") = "submit" Then
    i.InvokeMember("click")
    End If
    If i.InnerText = "Press" Then
    i.SetAttribute("innertext", "Click instead")
    i.Focus()
    SendKeys.Send("{ENTER}")
    End If
    Next

    For Each i In WebBrowser1.Document.GetElementsByTagName("select")
    If i.GetAttribute("id") = "sel_44313" Then
    i.SetAttribute("value", "third")
    ElseIf i.GetAttribute("id") = "new id 553" Then
    i.SetAttribute("value", 4)
    End If
    Next

    WebBrowser1.Document.GetElementById("885037_gm4").SetAttribute("value", "the new text")

    End Sub
    End Class

Try navigating to a real website and change some of it's elements.

Modifying the values of elements with a web browser shouldn't be that difficult. The main thing is to be able to find the exact element we want in the source code.

Remember:
all the possible options that appear in the code after writing: "Webbrowser1.Document.Body." you can use in the "for each" loop for "i."  - although the menu might not appear there.
like:
MsgBox(i.OuterHtml)

If you knew the order number of an element in a group of elements of the same type, like "input", you could use the "item" property to change it's value. Let's say you wanted input box number 3:
WebBrowser1.Document.GetElementsByTagName("input").Item(2).SetAttribute("value", "thiss")
- this will change the third "input" element, the first one would be Item(0)



Visual Basic 23 - Retrieving Website Data With A WebBrowser

Add a textbox on top. Size around 450, 20
Add a button on the right of the textbox. Text: Navigate
Add another textbox below the first one, make it large. Size around 500, 220
Add a webbrowser on the right of the second textbox, resize it - make it small. Size: 115, 55

Double click on the button, add this:
WebBrowser1.Navigate(TextBox1.Text)
TextBox2.Clear()

Double click on the webbrowser, event should be: WebBrowser1.DocumentCompleted. Add inside:
TextBox2.Text = WebBrowser1.Url.ToString & vbNewLine & WebBrowser1.DocumentTitle
- navigate to a website. This gives us the url and title of the current website.

Change the above code into this:
TextBox2.Text = WebBrowser1.Document.Url.ToString & vbNewLine & WebBrowser1.Document.Title & vbNewLine
TextBox2.Text = TextBox2.Text & WebBrowser1.Document.Domain

- that's another way to get url and site title, also the domain name

Replace the above code into this:
TextBox2.Text = WebBrowser1.DocumentText

- after the page loads completely, you will get the source code of the website.

We could have used a streamreader instead to do this. At the start of the coding page, insert this namespace:
Imports System.IO

Change the webbrowser code into this:
Dim bb As New StreamReader(WebBrowser1.DocumentStream)
TextBox2.Text = bb.ReadToEnd()

- we store the website's stream of data into a streamreader ("bb") and then we read the streamreader into our textbox.

Code:

    Imports System.IO

    Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Navigate(TextBox1.Text)
    TextBox2.Clear()
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    Dim bb As New StreamReader(WebBrowser1.DocumentStream)
    TextBox2.Text = bb.ReadToEnd()
    End Sub

    End Class


If you go to a website with your default OS browser, you should be able to choose "View Page Source" after right-clicking on it. Inside the source code you will notice a lot of html elements that are displayed by their "tag name" which usually has a pink color, like: meta, link, img, div etc. Google: "Html element list"
Each element should have some attributes that describe them, like: alt, class, default, size, name, src. Attributes are usually followed by the equality sign and quotation marks which hold the value of the attribute.

Let's get all the hyperlinks present on a chosen site:
Dim aa As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("a")
For Each i In aa
TextBox2.Text = TextBox2.Text & i.getattribute("href") & vbNewLine
Next

- instead of writing: WebBrowser1.Document.GetElementsByTagName("a")   we could have written: WebBrowser1.Document.Links

Change the previous code into this:
For Each i In WebBrowser1.Document.GetElementsByTagName("img")
TextBox2.Text = TextBox2.Text & i.getattribute("src") & vbNewLine
Next

- this will give us all the image links from a site.
Instead of: WebBrowser1.Document.GetElementsByTagName("img")   we could have used: WebBrowser1.Document.Images

You can change the tag name inside the "For" loop as you like and then search for the desired attribute by modifying the getattribute method.

Change the code again:
For Each i In WebBrowser1.Document.All
If i.getattribute("src").Length > 0 Then
TextBox2.Text = TextBox2.Text & i.getattribute("src") & vbNewLine
End If
Next

- this might provide you more results for the "src" attribute then you would have gotten by only searching the <img> tag name. That's because the web page can have this attribute describing other elements as well, like <script>.
WebBrowser1.Document.All - considers all the elements on the web page.
The "if" statement is needed in order to avoid all the empty lines in the results.

If you want to find more attributes during one single search just add another "if" statement with another attribute inside the "For Each" loop.

If you wanted to find another attribute only after the first one was found, then you'd insert the second "if" statement inside the previous one:
If i.getattribute("src").Length > 0 Then
TextBox3.Text = TextBox3.Text & i.getattribute("src") & vbNewLine
If (i.getattribute("alt").Length > 0) Then
TextBox3.Text = TextBox3.Text & i.getattribute("alt") & vbNewLine
End If
End If

There might be occasions when the chosen website has an image slideshow displayed on the web page. Every time the display of the slideshow changes, the "WebBrowser1.DocumentCompleted" event will fire up the subroutine again. So the code might be repeated a couple of times. Other changing elements on a website could do this as well.

Above the button1 sub, in the declaration area, add:
Dim dd

Inside the button1 sub add:
dd = 0

Put the whole code of the webbrowser sub into this "if" statement:
If dd = 0 Then
End If

Also add this below the "if" statement:
dd = 1

- additional website loads will not be processed by the sub code now.


    Imports System.IO

    Public Class Form1

    Dim dd

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Navigate(TextBox1.Text)
    TextBox2.Clear()
    dd = 0
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    If dd = 0 Then
    For Each i In WebBrowser1.Document.All
    If i.getattribute("src").Length > 0 Then
    TextBox2.Text = TextBox2.Text & i.getattribute("src") & vbNewLine
    If (i.getattribute("alt").Length > 0) Then
    TextBox2.Text = TextBox2.Text & i.getattribute("alt") & vbNewLine
    End If
    End If
    Next
    End If
    dd = 1

    End Sub

    End Class


You can suppress script error notifications from your webbrowser if you ever encounter them.
Click on the WebBrowser control in your main form -> go to properties -> find: "ScriptErrorsSuppressed" -> change to: True

WebBrowser data:
MsgBox(WebBrowser1.Location.ToString)   - location is relative to the client area of the main form.
MsgBox(WebBrowser1.Size.ToString)   - size of the webbrowser in pixels
MsgBox(WebBrowser1.ClientRectangle.ToString) - webbrowser client area, the location is relative to the webbrowser itself so it's gonna be 0,0


Visual Basic 05b - Creating Message Boxes With Button Choices

Start new project.

Add 6 buttons to the form.
Button1 text: Ok
Button2 text: Ok / Cancel
Button3 text: Abort / Retry / Ignore
Button4 text: Yes / No / Cancel
Button5 text: Yes / No
Button6 text: Retry / Cancel

The standard way of creating a message box is: msgbox("Some text"). Some text can be anything and it can also be empty but we must have the quotation marks inside the brackets. Also we can insert a variable inside the message box. The displayed text is the first parameter of the message box and it's the required one. It can have 2 more parameters which are obviously optional. We divide the parameters with commas.
- 1. parameter: text content of the message box
- 2. parameter: the type of the message box
- 3. parameter: the title of the message box

Double click on the first button, insert this:
MsgBox("Press Ok", MsgBoxStyle.OkOnly, "This is an OK only box")

MsgBoxStyle.OkOnly - this style is the default style and we are not required to write it into the message box to get it. There is 5 more button styles. Resource page.

Instead of writing MsgBoxStyle.OkOnly we could use the visual basic constant for the OkOnly button style: vbOKOnly. Also we can use an integer value: 0.
In fact, we could say that the second parameter actually works with integer numbers, but we can use the textual names of the settings and constants that hold those integer values.

Button Style                                           Constants                                Value
MsgBoxStyle.OkOnly                                vbOKOnly                                   0
MsgBoxStyle.OkCancel                            vbOKCancel                                1
MsgBoxStyle.AbortRetryIgnore              vbAbortRetryIgnore                           2
MsgBoxStyle.YesNoCancel                     vbYesNoCancel                             3
MsgBoxStyle.YesNo                                 vbYesNo                                     4
MsgBoxStyle.RetryCancel                       vbRetryCancel                               5

Declare this below the button1 sub:
Dim aa

Go to the design page, double click on the second button, add this:
MsgBox("Choose between Ok and Cancel", MsgBoxStyle.OkCancel, "OK - Cancel box")

- start program, click on button2. We can store the returned value of the message box (the clicked button) into a variable. Turn the previous line into this:
aa = MsgBox("Choose between Ok and Cancel", MsgBoxStyle.OkCancel, "OK - Cancel box")
MsgBox(aa)

- choosing Ok should give you 1, while cancel should be 2.

Button Name                           Returned Value
OK                                                       1
Cancel                                                  2
Abort                                                    3
Retry                                                    4
Ignore                                                   5
Yes                                                      6
No                                                        7

-> for constants just attach "vb" at the front of the name

Double click on the third button, add this to the sub:
MsgBox("Choose: Abort, Retry or Ignore", MsgBoxStyle.AbortRetryIgnore, "Abort - Retry - Ignore choice")

- press the button.

Let's make some changes to the previous line:
If MsgBox("Choose: Abort, Retry or Ignore", MsgBoxStyle.Critical + MsgBoxStyle.AbortRetryIgnore, "Abort - Retry - Ignore choice") = DialogResult.Abort Then
MsgBox("Abort was selected")
Else
MsgBox("You didn't abort, good for you")
End If

MsgBoxStyle.Critical - this will add an icon to the message box, it also comes with a notification sound.
After you write: DialogResult.   -> you will be given a menu with all the possible buttons you can press, so you can then use "if" statements to give each possible choice a desired task
DialogResult.(Button)  - it stores the same integer value that is also returned by the message box when a button has been chosen. Try this: MsgBox(DialogResult.Cancel) 

Button Icon                                            Constants                         Value                            
MsgBoxStyle.Critical                                vbCritical                             16
MsgBoxStyle.Question                            vbQuestion                           32
MsgBoxStyle.Exclamation                      vbExclamation                       48
MsgBoxStyle.Information                         vbInformation                        64

Double click on the fourth button, add this inside the sub:
aa = MsgBox("Your choice: Yes, No or Cancel?", vbInformation + vbYesNoCancel, "Yes - No - Cancel message")
If aa = vbYes Then
MsgBox("yes was chosen", , "YES title")
ElseIf aa = vbNo Then
MsgBox("No has been selected", vbOKOnly, )
Else
MsgBox("Canceled", 0, 0)
End If

- this time we have used constants in the first message box.
The "if" statement compares the value of the starting message box to the constants of the buttons that were used, like "vbYes".
vbInformation + vbYesNoCancel - the value of "vbinformation" is 64, while the value of "vbYesNoCancel" is 3, so their sum is 67.

Let's only use numerical values in the fourth button:
aa = MsgBox("Your choice: Yes, No or Cancel?", 67, "Yes - No - Cancel message")
If aa = 6 Then
MsgBox("yes was chosen", , "YES title")
ElseIf aa = 7 Then
MsgBox("No has been selected", vbOKOnly, )
Else
MsgBox("Canceled", 0, 0)
End If
- everything should be the same as before.

If you were to use something like vbOkCancel + vbAbort   as the second parameter, you would just be adding together 1 + 3 and giving the message box: 4, so you would get a Yes / No message box (because it's integer value is 4).

Double click on the fifth button, add this:
MsgBox("Waiting for Yes or No", vbOKCancel + vbAbort + 32 + 256, "The Wait: Yes - No")

- 32 will give us the "MsgBoxStyle.Question" icon, while 256 makes the second button the default one, which means the second button will be highlighted (focused on) when the message box appears. By default, the button most left is the one selected.

Setting                                                     Constant                         Value
MsgBoxStyle.DefaultButton1                 vbDefaultButton1                        0
MsgBoxStyle.DefaultButton2                 vbDefaultButton2                      256
MsgBoxStyle.DefaultButton3                 vbDefaultButton3                      512

Double click the last button, add inside:
If MessageBox.Show("Box Name", "Box Title", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) = vbRetry Then
MsgBox("Retry selected")
End If

- "MessageBox.Show" must be used a little bit differently, you have to separate each type of message box setting with a comma, you can't add them together.
MessageBoxIcon - might offer you more icon settings than "MsgBoxStyle" did, but there is still only 4 different icons you can put in the message. "MessageBoxIcon" has repetition, for example, "error", "hand" and "stop" are exactly the same, they give you the "Critical" icon

Final code:

    Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    MsgBox("Press Ok", MsgBoxStyle.RetryCancel, "This is an OK box")
    End Sub

    Dim aa

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    aa = MsgBox("Choose between Ok and Cancel", MsgBoxStyle.OkCancel, "OK - Cancel box")
    MsgBox(aa)
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    If MsgBox("Choose: Abort, Retry or Ignore", MsgBoxStyle.Critical + MsgBoxStyle.AbortRetryIgnore, "Abort - Retry - Ignore choice") = DialogResult.Abort Then
    MsgBox("Abort was selected")
    Else
    MsgBox("You didn't abort, good for you")
    End If
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    aa = MsgBox("Your choice: Yes, No or Cancel?", 67, "Yes - No - Cancel message")
    If aa = 6 Then
    MsgBox("yes was chosen", , "YES title")
    ElseIf aa = 7 Then
    MsgBox("No has been selected", vbOKOnly, )
    Else
    MsgBox("Canceled", 0, 0)
    End If

    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
    MsgBox("Waiting for Yes or No", vbOKCancel + vbAbort + 32 + 256, "The Wait: Yes - No")
    End Sub

    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
    If MessageBox.Show("Box Name", "Box Title", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2) = vbRetry Then
    MsgBox("Retry selected")
    End If
    End Sub

    End Class



Visual Basic 22 - Using The WebBrowser

Start new project.

Main form size: 700, 380.  Main form windowstate: Maximized.
Add a combobox on top of the main form, size around 580, 21. Combobox anchor: Top, Left, Right.
Add a button on the right of the combobox, text: Navigate,   anchor: Top, Right.
Below the combobox and the button add a WebBrowser from the toolbox. Size around 660, 280
WebBrowser anchor: Top, Bottom, Left, Right
Add a timer to the program.

Double click the button, add this into the sub:
WebBrowser1.Navigate(ComboBox1.Text)

- start program. Insert a working web address like google.com, and press the button.
If you wanted to, you could have inserted the web address directly in the code, this is how: WebBrowser1.Navigate("www.google.com")

Go to the design page, click on the combobox, go to properties, click on events icon, double click on the KeyDown event. We want to be able to insert the web address into the combobox text and navigate to it by pressing the "enter" key. At this point, every time we press the "enter" key we hear a warning sound which is inconvenient.

Inside the combobox sub add:
If e.KeyCode = Keys.Enter And ComboBox1.Text.Length >= 0 Then
e.SuppressKeyPress = True
Button1_Click(Nothing, Nothing)
End If

- after the "enter" key is pressed, e.SuppressKeyPress will stop the notification sound that we don't want, also button1 will be called.

Now we will add the ability to double click the Navigate button and send the web address to our default windows web browser. Generally buttons can't use the double click event, so we will do this with a timer.

In the declaration area, outside button1 sub, insert this:
Dim t1 as Integer

Change the content of the button1 sub into this:
If Timer1.Enabled = False Then
Timer1.Start()
End If
t1 = t1 + 1

- the timer starts only if it's turned off. Every time you press the Navigate button, "t1" is raised by 1.

Go to the design page, double click the timer control, insert in the sub:
Timer1.Stop()
If t1 = 1 Then
WebBrowser1.Navigate(ComboBox1.Text)
ElseIf t1 > 1 Then
System.Diagnostics.Process.Start(ComboBox1.Text)
End If
t1 = 0
ComboBox1.Items.Add(ComboBox1.Text)

- the timer gets stopped directly. After the timer has been started (button1), the timer interval has to first end before the code from the timer sub is executed. During that interval a person should have enough time to decide if he wants to click on the button once or a couple of times.
If there is only one click, the visual basic webbrowser control will navigate to the web address.
System.Diagnostics.Process.Start(...) - if there are more clicks found, then the default OS web browser should visit the desired website.
ComboBox1.Items.Add(ComboBox1.Text) - addresses we have already navigated to will be added to the combobox. The problem with this is that if we navigate the same site twice, it will be added twice.

Code:

    Public Class Form1

    Dim t1 As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If Timer1.Enabled = False Then
    Timer1.Start()
    End If
    t1 = t1 + 1
    End Sub

    Private Sub ComboBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
    If e.KeyCode = Keys.Enter And ComboBox1.Text.Length >= 0 Then
    e.SuppressKeyPress = True
    Button1_Click(Nothing, Nothing)
    End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Timer1.Stop()
    If t1 = 1 Then
    WebBrowser1.Navigate(ComboBox1.Text)
    ElseIf t1 > 1 Then
    System.Diagnostics.Process.Start(ComboBox1.Text)
    End If
    t1 = 0
    ComboBox1.Items.Add(ComboBox1.Text)
    End Sub
    End Class


If you are sending an invalid address name to your OS browser, the program will most likely crash. This must be fixed.

Change this line of code in the timer sub:
System.Diagnostics.Process.Start(ComboBox1.Text)
into this:
Try
System.Diagnostics.Process.Start(ComboBox1.Text)
Catch
System.Diagnostics.Process.Start("http://www.google.com/search?q=" & ComboBox1.Text)
End Try

- now invalid web addresses will give you a google search instead of crashing.

Change this line:
ComboBox1.Items.Add(ComboBox1.Text)
into this:
For Each i In ComboBox1.Items
If i = ComboBox1.Text Then
Exit Sub
End If
Next
ComboBox1.Items.Add(ComboBox1.Text)

- if the same address was already used in the combobox, then we will exit the sub and avoid adding it again.

Final code:

    Public Class Form1

    Dim t1 As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If Timer1.Enabled = False Then
    Timer1.Start()
    End If
    t1 = t1 + 1
    End Sub

    Private Sub ComboBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
    If e.KeyCode = Keys.Enter And ComboBox1.Text.Length >= 0 Then
    e.SuppressKeyPress = True
    Button1_Click(Nothing, Nothing)
    End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Timer1.Stop()
    If t1 = 1 Then
    WebBrowser1.Navigate(ComboBox1.Text)
    ElseIf t1 > 1 Then
    Try
    System.Diagnostics.Process.Start(ComboBox1.Text)
    Catch
    System.Diagnostics.Process.Start("http://www.google.com/search?q=" & ComboBox1.Text)
    End Try
    End If
    t1 = 0
    For Each i In ComboBox1.Items
    If i = ComboBox1.Text Then
    Exit Sub
    End If
    Next
    ComboBox1.Items.Add(ComboBox1.Text)
    End Sub

    End Class


Start program.

You could also insert four more buttons to this program if you prefer. Code for the first one:
WebBrowser1.GoBack()
- revisit previously used web addresses

A button for moving forward if you ever navigated back:
WebBrowser1.GoForward()

A button for refreshing the current website:
WebBrowser1.Refresh()

A button that cancels the loading of a website:
WebBrowser1.Stop()

Visual Basic 06a - Event Handler Properties, KeyDown, KeyUp, KeyPress

Start new project.

Add a button to the form. Click on the button, go to the properties window, click on the events icon, find the keydown event and double click on it.

If you write inside the sub: e.  -> you will get a menu displaying all the possible properties for "e" under the "Common" tab.

Insert this inside the sub:
MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString)

- start the program, click on button1 if it's not highlighted then press a key on your keyboard.
"KeyValue" will give you the decimal value of the character according to the ASCII code. You can check the ASCII table here: Link.
Turning KeyValue to a string doesn't change anything, you always get the ASCII decimal value of a character.

The main event for this sub is KeyDown, so if you keep holding down a key on your keyboard, the sub will be constantly executed.

Let's change the previous line of code into this:
MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString & vbNewLine & vbNewLine &
"KeyCode: " & vbNewLine & e.KeyCode & vbNewLine & e.KeyCode.ToString)

- start program, press keys on the keyboard.
"KeyCode" will also represent the ASCII value of a character until it's turned into a string. The string value of "KeyCode" is the uppercase version of the character itself. You can also try pressing the modifier keys like control, alt and shift. Pressing "Alt" will give you "Menu".
If you hold down 2 or more keys at the same time, the "KeyCode" property will hold the value of the last one you have pressed.

Let's change again the 2 lines of code that we have inside the button1 sub:
MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString & vbNewLine & vbNewLine &
"KeyCode: " & vbNewLine & e.KeyCode & vbNewLine & e.KeyCode.ToString & vbNewLine & vbNewLine &
"KeyData: " & vbNewLine & e.KeyData & vbNewLine & e.KeyData.ToString)

- try the program out.
"KeyData" can add together the values of the three modifier keys (alt, control and shift) and another character from the keyboard when they are held down.
"Shift" value should be 65552, "control" should be 131089 and "alt" should be 262162.
Although it adds together more than one modifier, it doesn't add more than one character, which means that "KeyData" will always give you a unique integer value.
If "KeyData" is turned to a string, it will display you the names of all the modifiers that are pressed down at the same time plus the last key that was pressed.

Now change the event of button1 sub from keydown:
Handles Button1.KeyDown
to keyup:
Handles Button1.KeyUp

- now the sub will be run only when you release a pressed key on the keyboard. "KeyUp" should have the same properties for the "e" variable since the same event handler is declared ("KeyEventArgs").

Code:

    Public Class Form1

    Private Sub Button1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button1.KeyUp
    MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString & vbNewLine & vbNewLine &
    "KeyCode: " & vbNewLine & e.KeyCode & vbNewLine & e.KeyCode.ToString & vbNewLine & vbNewLine &
    "KeyData: " & vbNewLine & e.KeyData & vbNewLine & e.KeyData.ToString)
    End Sub

    End Class


Add another button to the form, go to properties, events icon, double click the keydown button again. Add this in the sub:
MsgBox(e.Shift & vbNewLine & e.Control & vbNewLine & e.Alt)

- click on the second button first if the first one is highlighted then press a key
Specific modifier properties will show either true or false when the specific key is pressed on the keyboard. Turning the values to string doesn't change anything.

Turn the previous code line into this:
MsgBox(e.Shift.ToString & vbNewLine & e.Control & vbNewLine & e.Alt & vbNewLine & vbNewLine &
"Modifier: " & vbNewLine & e.Modifiers & vbNewLine & e.Modifiers.ToString)

- the modifier property holds a value only for the modifier keys otherwise is zero (None). Just like "KeyData" it can list out more modifiers pressed together.

Change the event of button2 sub to keyup:
Handles Button2.KeyUp

- although a modifier key can start a sub with a KeyUp event, the event handler properties used inside this sub will not register that those modifiers were pressed. You should get "false" when displaying the values of the modifier properties.

Add a textbox to the form and give it a KeyDown event. Inside the sub add:
e.SuppressKeyPress = True

- "SuppresKeyPress" property will disallow any user input to be placed into the textbox. By default it's always set to false.

Change the previous code line to this:
If e.KeyValue = Keys.C Then
e.SuppressKeyPress = True
End If

- this will disallow the insertion of the "c" character.
When you write "Keys."  inside the sub, a menu will appear showing you all the possible keys that you could block this way.

This is how you could block all the numbers from being typed into the textbox:
If e.KeyValue >= Keys.D0 And e.KeyValue <= Keys.D9 Then
e.SuppressKeyPress = True
End If

Placing any operation like a messagebox or a dialog, which stop the sub execution for a moment, is going to conflict with the usage of the "SuppressKeyPress" property and therefore it will not do it's job.

Code:

    Public Class Form1

    Private Sub Button1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button1.KeyDown
    MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString & vbNewLine & vbNewLine &
    "KeyCode: " & vbNewLine & e.KeyCode & vbNewLine & e.KeyCode.ToString & vbNewLine & vbNewLine &
    "KeyData: " & vbNewLine & e.KeyData & vbNewLine & e.KeyData.ToString)
    End Sub

    Private Sub Button2_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button2.KeyUp
    MsgBox(e.Shift.ToString & vbNewLine & e.Control & vbNewLine & e.Alt & vbNewLine & vbNewLine &
    "Modifier: " & vbNewLine & e.Modifiers & vbNewLine & e.Modifiers.ToString)
    End Sub

    Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
    If e.KeyValue >= Keys.D0 And e.KeyValue <= Keys.D9 Then
    e.SuppressKeyPress = True
    End If
    End Sub

    End Class


Add another textbox to the form, go to properties, give it the KeyPress event. Insert into the sub:
MsgBox(e.KeyChar)

The event handler for KeyDown and KeyUp was KeyEventArgs, while the one for KeyPress is KeyPressEventArgs.

The "KeyPress" event will not start the sub by only pressing modifiers and keys from F1 to F12, it will start mainly by pressing printable ASCII characters and also keys like escape and return. However, the event handler does take into consideration if a modifier was held down before a triggering keyboard key was pressed.
"KeyChar" holds the symbolic value of the characters sent by the "KeyPress" event, not the numeric ASCII value.

Erase the previous code line (textbox2 sub), insert this:
If e.KeyChar = Keys.D.ToString.ToLower Then
MsgBox(e.KeyChar)
End If

- the message box will start when the pressed keyboard key is the character "d".
Keys.D.Tostring - gives us uppercase characters by default, so we have to add ToLower for lowercase.

Change the previous code with this one:
If e.KeyChar = Chr(100) Then
e.Handled = True
End If

Chr(100) - same as using: Keys.D.ToString.ToLower. The number inside the brackets is the decimal value of lowercase "d" character present in the ASCII table.
e.Handled = True - e.handled can be used just like e.SuppressKeyPress, it will remove the action that the keystroke is supposed to perform inside the control (for example, being printed inside the textbox).
You can even add a message box to this "if" statement, the code should still work.

The "Handled" property might not work well, on the other hand, when using the "KeyDown" event.

Final code:

    Public Class Form1

    Private Sub Button1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button1.KeyDown
    MsgBox("KeyValue: " & vbNewLine & e.KeyValue & vbNewLine & e.KeyValue.ToString & vbNewLine & vbNewLine &
    "KeyCode: " & vbNewLine & e.KeyCode & vbNewLine & e.KeyCode.ToString & vbNewLine & vbNewLine &
    "KeyData: " & vbNewLine & e.KeyData & vbNewLine & e.KeyData.ToString)
    End Sub

    Private Sub Button2_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button2.KeyUp
    MsgBox(e.Shift.ToString & vbNewLine & e.Control & vbNewLine & e.Alt & vbNewLine & vbNewLine &
    "Modifier: " & vbNewLine & e.Modifiers & vbNewLine & e.Modifiers.ToString)
    End Sub

    Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    If e.KeyValue >= Keys.D0 And e.KeyValue <= Keys.D9 Then
    e.SuppressKeyPress = True
    End If
    End Sub

    Private Sub TextBox2_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress
    If e.KeyChar = Chr(100) Then
    e.Handled = True
    End If
    End Sub

    End Class