Welcome Guest!
 VB.NET Helper
 Previous Message All Messages Next Message 
VB .NET Helper Newsletter  Rod Stephens
 Aug 19, 2009 10:15 PDT 

I've had two DevX articles posted recently.
----------
The second part of my DevX WPF 3-D article posted.

WPF Wonders: 3D Drawing with Textures, Transformations, and Realism
(Part 2)</A>
http://www.devx.com/dotnet/Article/42450

To build realism into 3D scenes, you need to draw with the appropriate
materials--and transformations help make the drawing process much
simpler.

This article explains how to use textures to make scenes more realistic.
Textures let you cover 3-D objects with bricks, wood grain, and so
forth.

The article also explains how to use transformations to make building
complex scenes easier.

The final example draws a wooden maze with a stone floor, containing a
spinning globe.
----------
And a new article on transformations posted. The examples show how to
build some pretty cool robots!

WPF Wonders: Transformations (and Robots!)
http://www.devx.com/dotnet/Article/42497

WPF's transformations make it easy to move, scale, or rotate objects,
and simplify building complex moveable 3D shapes.

This very cool article explains how to use transformations to make it
easeir to produce complex drawings. It explains basic transformations
that produce effects such as rotated, stretched, and skewed text.

I then explains how to use transformations can make building advanced
3-D scenes easier. It explains how to use transformations to model the
parts of a complicated models such as robots and provides two 3-D
examples that build a complex robot arm and a stick figure robot.
----------
On the HowTo front, I've posted VB 6 and VB .NET versions of a Web page
image scraper that pulls all of the images from a Web page. The two have
slightly different features because some things are easier to do than
others in the two languages. You may want to compare them to see what
you might like to take from one to the other. (For example, the VB 6
version doesn't provide image previews because it doesn't have an
easy-to-use FlowLayoutPanel.)
----------
Have a great week and thanks for subscribing!
----------
Rod
RodSte-@vb-helper.com

Books To Keep: http://www.BooksToKeep.com
----------
*** Now Available ***

Beginning Database Design Solutions
http://www.amazon.com/exec/obidos/ASIN/0470385499/vbhelper/

Visual Basic 2008 Programmer's Reference
http://www.amazon.com/exec/obidos/ASIN/0470182628/vbhelper/
==========

    VB.NET Contents:
1. New HowTo: Grab images from a Web page in Visual Basic .NET
2. New HowTo: Use the Convert class to convert values between decimal,
hexadecimal, octal, and binary in Visual Basic .NET

    Both Contents:
3. New Links
==========
++++++++++
<VB.NET>
++++++++++
==========
1. New HowTo: Grab images from a Web page in Visual Basic .NET
http://www.vb-helper.com/howto_net_grab_web_images.html
http://www.vb-helper.com/HowTo/howto_net_grab_web_images.zip

This description only touches on the most interesting parts of the
program. Download it to see the details.

You can click the links on the WebBrowser to navigate to a Web page, or
enter a URL and click the Go button to navigate there. The following
code shows how the program navigates.


' Navigate to the entered URL.
Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnGo.Click
    Try
        wbrWebSite.Navigate(txtUrl.Text)
    Catch ex As Exception
        MessageBox.Show("Error navigating to web site " & _
            txtUrl.Text & vbCrLf & ex.Message, _
            "Navigation Error", _
            MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
    End Try
End Sub

After you have navigated to the desired Web page, click the List Images
button to execute the following code. The program removes all controls
from the flpPictures FlowLayoutPanel control by setting their Parent
properties to Nothing. This removes all references to those controls so
they are destroyed when garbage collection runs.



Next the code gets the WebBrowser's Document property, which returns an
HtmlDocument object representing the Web page, and loops through the
HtmlDocument's Images collection. It gets the image object's src
property, which contains the image's URL.

The code makes a new PictureBox, calls subroutine GetPicture to download
the image into the PictureBox, and places the PictureBox in the
flpPictures FlowLayoutPanel. That control automatically arranges its
children in rows, wrapping when necessary, and displaying scroll bars if
the pictures don't all fit. Notice that the code saves the image's URL
in the PictureBox's Tag property.

Finally the code registers the pic_Click event handler to catch the
PictureBox's Click events.

This routine also contains code to let you see new PictureBoxes as they
are created and to stop the loop before it finishes. See the code for
details.

' Show the images from the URL.
Private m_Running As Boolean = False
Private Sub btnListImages_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnListImages.Click
    If btnListImages.Text = "List Images" Then
        Me.Cursor = Cursors.WaitCursor
        btnListImages.Text = "Stop"
        btnGo.Enabled = False
        btnSaveImages.Enabled = False
        Application.DoEvents()

        ' Remove old images.
        For i As Integer = flpPictures.Controls.Count - 1 To 0 Step -1
            flpPictures.Controls(i).Parent = Nothing
        Next i

        ' List the images on this page.
        Dim doc As System.Windows.Forms.HtmlDocument =
wbrWebSite.Document
        m_Running = True
        For Each element As HtmlElement In doc.Images
            Dim dom_element As mshtml.HTMLImg = element.DomElement
            Dim src As String = dom_element.src

            Dim pic As New PictureBox()
            pic.BorderStyle = BorderStyle.Fixed3D
            pic.SizeMode = PictureBoxSizeMode.AutoSize
            pic.Image = GetPicture(src)
            pic.Parent = flpPictures
            pic.Tag = src
            tipFileName.SetToolTip(pic, src)

            AddHandler pic.Click, AddressOf pic_Click

            Application.DoEvents()

            If Not m_Running Then Exit For
        Next element
        m_Running = False

        btnListImages.Text = "List Images"
        btnGo.Enabled = True
        btnSaveImages.Enabled = True
        Me.Cursor = Cursors.Default
    Else
        m_Running = False
    End If
End Sub

The GetPicture function uses a WebClient to download a picture. It calls
the WebClient's DownloadData method to pull the image down into a memory
stream. It then uses the Image class's FromStream method to convert the
stream into an image.

' Get the picture at a given URL.
Private Function GetPicture(ByVal url As String) As Image
    Try
        url = Trim(url)
        If Not url.ToLower().StartsWith("http://") Then url = "http://"
& url
        Dim web_client As New WebClient()
        Dim image_stream As New
MemoryStream(web_client.DownloadData(url))
        Return Image.FromStream(image_stream)
    Catch ex As Exception
        MessageBox.Show("Error downloading picture " & _
            url & vbCrLf & ex.Message, _
            "Download Error", _
            MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
    End Try
    Return Nothing
End Function

After you display the images, click on any that you don't want to
download. When you click on a PictureBox, the following code sets that
control's Parent property to Nothing. That removes it from the
FlowLayoutPanel, which automatically rearranges its remaining children.

' Remove the clicked PictureBox.
Private Sub pic_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
    Dim pic As PictureBox = DirectCast(sender, PictureBox)
    pic.Parent = Nothing
End Sub

When you click the Save Images button, the following code loops through
the PictureBoxes that remain in the FlowLayoutPanel. It gets each
image's file name from the PictureBox's Tag property and saves the
control's image in an appropriately named file.

' Save the images that have not been removed.
Private Sub btnSaveImages_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnSaveImages.Click
    Dim dir_name As String = txtDirectory.Text
    If Not dir_name.EndsWith("\") Then dir_name &= "\"

    For Each pic As PictureBox In flpPictures.Controls
        Dim bm As Bitmap = pic.Image
        Dim filename As String = pic.Tag
        filename = filename.Substring(filename.LastIndexOf("/") + 1)
        Dim ext As String =
filename.Substring(filename.LastIndexOf("."))
        Dim full_name As String = dir_name & filename

        Select Case ext
            Case ".bmp"
                bm.Save(full_name, Imaging.ImageFormat.Bmp)
            Case ".gif"
                bm.Save(full_name, Imaging.ImageFormat.Gif)
            Case ".jpg", "jpeg"
                bm.Save(full_name, Imaging.ImageFormat.Jpeg)
            Case ".png"
                bm.Save(full_name, Imaging.ImageFormat.Png)
            Case ".tiff"
                bm.Save(full_name, Imaging.ImageFormat.Tiff)
            Case Else
                MessageBox.Show( _
                    "Unknown file type " & ext & _
                    " in file " & filename, _
                    "Unknown File Type", _
                    MessageBoxButtons.OK, _
                    MessageBoxIcon.Error)
        End Select
    Next pic

    Beep()
End Sub

This program still has a few weak spots. The error handling isn't
perfect. For example, you can click the Save Images button even if you
haven't listed any images. The program simply saves zero files so it
doesn't hurt anything but it would make sense to disable that button
unless some images were displayed.

The program also downloads images when it needs them rather than pulling
them from cache so it isn't as fast as it might be. It also probably
cannot save images that are generated on the fly by the Web server.
==========
2. New HowTo: Use the Convert class to convert values between decimal,
hexadecimal, octal, and binary in Visual Basic .NET
http://www.vb-helper.com/howto_net_convertto_bases.html
http://www.vb-helper.com/HowTo/howto_net_convertto_bases.zip

When you change a text value in any of the text boxes, the
txt_TextChanged event handler takes action. That routine calls
subroutine DisplayValue, passing it the text box that was modified.

Subroutine DisplayValue checks the text box's name to see how it should
interpret the value. In any case, the code uses the Convert class's
ToInt64 method to convert the text into a 64-bit integer. (The class has
similar methods to convert to other data types, for example ToInt32.)

The optional second parameter to ToInt64 indicates the base from which
to convert. This can be 2, 8, 10 (the default), or 16.


Having converted the text value into a Long, the program displays it in
different bases. It uses ToString to display the decimal value, ToString
with the parameter X to display the hexadecimal value, the Oct$ function
to display the octal value (let me know if you know of a VB .NET method
for formatting as octal), and function LongToBinary to display the
binary.


Private Sub txt_TextChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles txtDecimal.TextChanged, txtBinary.TextChanged,
txtHexadecimal.TextChanged, txtOctal.TextChanged
    DisplayValue(sender)
End Sub

' Display the value in the indicated control in
' the other controls.
Private Sub DisplayValue(ByVal source As TextBox)
    ' Don't recurse.
    Static ignore_events As Boolean = False
    If ignore_events Then Exit Sub
    ignore_events = True

    ' Get the value.
    Dim value As Long
    Try
        Select Case source.Name
            Case "txtDecimal"
                value = Convert.ToInt64(source.Text)
            Case "txtHexadecimal"
                value = Convert.ToInt64(source.Text, 16)
            Case "txtOctal"
                value = Convert.ToInt64(source.Text, 8)
            Case "txtBinary"
                value = Convert.ToInt64(source.Text.Replace(" ", ""), 2)
        End Select
    Catch ex As Exception
        MessageBox.Show("Error parsing input" & vbCrLf & ex.Message, _
            "Input Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
    End Try

    ' Display the value in different formats.
    If source.Name <> "txtDecimal" Then
        txtDecimal.Text = value.ToString()
    End If
    If source.Name <> "txtHexadecimal" Then
        txtHexadecimal.Text = value.ToString("X")
    End If
    If source.Name <> "txtOctal" Then
        txtOctal.Text = Oct$(value)
    End If
    If source.Name <> "txtBinary" Then
        txtBinary.Text = LongToBinary(value)
    End If

    ignore_events = False
End Sub

Function LongToBinary returns a binary text representation of a value.
It also considers the value nibble-by-nibble. For each nibble, the code
compares the nibble's value to a power of 2 and outputs a 0 or 1
depending on whether the nibble has the same bit set as the power of
two.

' Convert this Long value into a binary string.
Private Function LongToBinary(ByVal long_value As Long, Optional ByVal
separate_bytes As Boolean = True) As String
    ' Convert into hex.
    Dim hex_string As String = long_value.ToString("X")

    ' Zero-pad to a full 16 characters.
    hex_string = New String("0", 16 - hex_string.Length) & hex_string

    ' Read the hexadecimal digits
    ' one at a time from right to left.
    Dim result_string As String = ""
    For digit_num As Integer = 0 To 15
        ' Convert this hexadecimal digit into a
        ' binary nibble.
        Dim digit_value As Integer =
Integer.Parse(hex_string.Substring(digit_num, 1),
Globalization.NumberStyles.HexNumber)

        ' Convert the value into bits.
        Dim factor As Integer = 8
        Dim nibble_string As String = ""
        For bit As Integer = 0 To 3
            If digit_value And factor Then
                nibble_string &= "1"
            Else
                nibble_string &= "0"
            End If
            factor \= 2
        Next bit

        ' Add the nibble's string to the left of the
        ' result string.
        result_string &= nibble_string
    Next digit_num

    ' Add spaces between bytes if desired.
    If separate_bytes Then
        Dim tmp As String = ""
        For i As Integer = 0 To result_string.Length - 8 Step 8
            tmp &= result_string.Substring(i, 8) & " "
        Next i
        result_string = tmp.Substring(0, tmp.Length - 1)
    End If

    ' Return the result.
    Return result_string
End Function
==========
++++++++++
<Both>
++++++++++
==========
3. New Links
http://www.vb-helper.com/links.html

Math Worksheets World
http://mathworksheetsworld.com/
1,200 printable K-12 math worksheets.

Online Binary-Decimal Converter
http://www.binaryconvert.com/
A quick online application that converts between decimal and binary.
==========
Archives:
    http://www.topica.com/lists/VBHelper
    http://www.topica.com/lists/VB6Helper
    http://www.topica.com/lists/VBNetHelper

Post questions at:
    http://www.topica.com/lists/VBHelperQA
	
 Previous Message All Messages Next Message 
  Check It Out!

  Topica Channels
 Best of Topica
 Art & Design
 Books, Movies & TV
 Developers
 Food & Drink
 Health & Fitness
 Internet
 Music
 News & Information
 Personal Finance
 Personal Technology
 Small Business
 Software
 Sports
 Travel & Leisure
 Women & Family

  Start Your Own List!
Email lists are great for debating issues or publishing your views.
Start a List Today!

© 2001 Topica Inc. TFMB
Concerned about privacy? Topica is TrustE certified.
See our Privacy Policy.