|
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
|
|
 |
|