Category Archives: Visual Basic

Moved WordPress over to Syntaxbytes.com

Hello, I will no longer be using paulishak.wordpress.com as my blog.
This site will remain up, but I will post new blog entries at the following site:

syntaxbytes.com

syntaxbytes.com looks exactly like this site, with additional features such as rss feeds for my MSDN forum activity.

Thanks!

Advertisements

Creating a skinnable application

I posted this to the forum for someone asking questions who was acting very arrogant, so I decided to delete my posts from that thread’ I felt like this code still offers someone else the opportunity to learn, so I moved to this blog.

Here is an example of making a custom program skinnable, but be informed that every little detail needs to be addressed. If you need to make for the skin writer(end user) to be able to specify drag areas of the form, then you need to create that logic. Every single little detail that you wish to be customized, needs to be added to the library, and also the logic to: Serialize, deserialize, validate, and apply it.

This is an extreme amount of work to allow for skinnable applications, so I hope your application is worth skinning.

Example Configuration File(Created with the SimpleSkin.ToXMLFile method)
*Note if you would like to add more fields, you need to modify the library(listed further down)

<?xml version="1.0" encoding="utf-16"?>
<SimpleSkin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FormSkinPath>C:\Users\et3ishak\Desktop\myFormSkin.png</FormSkinPath>
  <Button1SkinPath>C:\Users\et3ishak\Desktop\skinnedButton.png</Button1SkinPath>
  <Button1MouseDownSkinPath>C:\Users\et3ishak\Desktop\skinnedButtonMouseDown.png</Button1MouseDownSkinPath>
  <Button1Location>
    <X>100</X>
    <Y>100</Y>
  </Button1Location>
</SimpleSkin>

Example Usage:

Option Strict On
Option Explicit On
Option Infer Off
Imports System.IO
Public Class Form1
    Private FormSkinPath As String = Nothing 'My.Computer.FileSystem.SpecialDirectories.Desktop & "\myFormSkin.png"
    Private Button1SkinPath As String = Nothing 'My.Computer.FileSystem.SpecialDirectories.Desktop & "\skinnedButton.png"
    Private Button1MouseDownSkinPath As String = Nothing 'My.Computer.FileSystem.SpecialDirectories.Desktop & "\skinnedButtonMouseDown.png"
    Private Button1Location As Point = New Point(100, 100)
    Private SimpleSkin1 As New CustomSkinningLibrary.SimpleSkin
    WithEvents skinnedForm As CustomSkinningLibrary.SkinnableForm
    Private Sub btnShowSkinnedForm_Click(sender As Object, e As EventArgs) Handles btnShowSkinnedForm.Click
        With SimpleSkin1
            .FormSkinPath = Me.FormSkinPath
            .Button1SkinPath = Me.Button1SkinPath
            .Button1MouseDownSkinPath = Me.Button1MouseDownSkinPath
            .Button1Location = Me.Button1Location
        End With
        Try
            skinnedForm = CustomSkinningLibrary.SkinnableForm.Create(SimpleSkin1)
            skinnedForm.Show()
        Catch ex As CustomSkinningLibrary.SkinIncompleteException
            For Each s As String In ex.Errors
                MsgBox(s)
            Next
        End Try
    End Sub
    Private Sub btnSetFormSkinPath_Click(sender As Object, e As EventArgs) Handles btnSetFormSkinPath.Click
        Dim ofd As New OpenFileDialog With {.Title = "Select Form Skin Image"}
        ofd.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|All files (*.*)|*.*"
        ofd.Multiselect = False
        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.FormSkinPath = ofd.FileName
        End If
    End Sub
    Private Sub btnSetButton1SkinPath_Click(sender As Object, e As EventArgs) Handles btnSetButton1SkinPath.Click
        Dim ofd As New OpenFileDialog With {.Title = "Select Button Skin Image"}
        ofd.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|All files (*.*)|*.*"
        ofd.Multiselect = False
        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.Button1SkinPath = ofd.FileName
        End If
    End Sub
    Private Sub btnSetButton1MouseDownSkinPath_Click(sender As Object, e As EventArgs) Handles btnSetButton1MouseDownSkinPath.Click
        Dim ofd As New OpenFileDialog With {.Title = "Select Button MouseDown Skin Image"}
        ofd.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|All files (*.*)|*.*"
        ofd.Multiselect = False
        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.Button1MouseDownSkinPath = ofd.FileName
        End If
    End Sub
    Private Sub btnSaveSkinDataToXml_Click(sender As Object, e As EventArgs) Handles btnSaveSkinDataToXml.Click
        MsgBox("Make sure you set all your properties!")
        Dim sfd As New SaveFileDialog With {.Title = "Export Skin To XML"}
        sfd.Filter = "Xml files (*.xml|*.xml"
        If sfd.ShowDialog = Windows.Forms.DialogResult.OK Then
            With SimpleSkin1
                .FormSkinPath = Me.FormSkinPath
                .Button1SkinPath = Me.Button1SkinPath
                .Button1MouseDownSkinPath = Me.Button1MouseDownSkinPath
                .Button1Location = Me.Button1Location
            End With
            SimpleSkin1.ToXMLFile(sfd.FileName)
        End If
    End Sub
    Private Sub btnLoadSkinFromXml_Click(sender As Object, e As EventArgs) Handles btnLoadSkinFromXml.Click
        Dim skin As CustomSkinningLibrary.SimpleSkin = Nothing
        Dim ofd As New OpenFileDialog With {.Title = "Import Skin From XML"}
        ofd.Filter = "Xml files (*.xml|*.xml"
        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
            skin = SimpleSkin1.FromXMLFile(ofd.FileName)
        Else
            Exit Sub
        End If
        Dim form As CustomSkinningLibrary.SkinnableForm = CustomSkinningLibrary.SkinnableForm.Create(skin)
        form.Show()
    End Sub
End Class

Example Skin Library:

Namespace CustomSkinningLibrary
    <Serializable>
    Public Class SimpleSkin
        Public Property FormSkinPath As String = Nothing
        Public Property Button1SkinPath As String = Nothing
        Public Property Button1MouseDownSkinPath As String = Nothing
        Public Property Button1Location As Point = Nothing
        Public ReadOnly Property Complete As Boolean
            Get
                If FormSkinPath Is Nothing Then Return False
                If Button1SkinPath Is Nothing Then Return False
                If Button1MouseDownSkinPath Is Nothing Then Return False
                If Button1Location = Nothing Then Return False
                If Not System.IO.File.Exists(Me.FormSkinPath) Then Return False
                If Not System.IO.File.Exists(Me.Button1SkinPath) Then Return False
                If Not System.IO.File.Exists(Me.Button1MouseDownSkinPath) Then Return False
                Return True
            End Get
        End Property
        Public Sub ToXMLFile(Path As String)
            Dim serializer As New Xml.Serialization.XmlSerializer(GetType(SimpleSkin))
            Dim sb As New System.Text.StringBuilder
            Using s As New StringWriter(sb)
                serializer.Serialize(s, Me)
            End Using
            My.Computer.FileSystem.WriteAllText(Path, sb.ToString, False)
        End Sub
        Public Function FromXMLFile(Path As String) As SimpleSkin
            Dim serializer As New Xml.Serialization.XmlSerializer(GetType(SimpleSkin))
            Dim a As New StreamReader(Path)
            Dim obj As Object
            obj = serializer.Deserialize(a)
            Return DirectCast(obj, SimpleSkin)
        End Function
    End Class
    Public Class SkinnableForm
        Inherits Form
        Public WithEvents Button1 As SkinnableButton
        Private MySkin As Bitmap
        Protected Sub New()
        End Sub
        Protected Sub SetSkin(bmp As Bitmap)
            Dim g As Graphics = Me.CreateGraphics
            g.DrawImage(bmp, Me.ClientRectangle)
        End Sub
        Protected Overrides Sub OnPaint(pevent As PaintEventArgs)
            SetSkin(MySkin)
            Exit Sub
        End Sub
        Private Sub button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            MsgBox("hello world!")
        End Sub
        Public Shared Function Create(skin As SimpleSkin) As SkinnableForm
            If skin.Complete Then
                Dim createdForm As New SkinnableForm
                Dim formImage As Image = Image.FromFile(skin.FormSkinPath)
                createdForm.Button1 = SkinnableButton.Create(skin)
                createdForm.Button1.Parent = createdForm
                createdForm.MySkin = CType(formImage, Bitmap)
                createdForm.Size = formImage.Size
                createdForm.SetSkin(createdForm.MySkin)
                createdForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
                Return createdForm
            Else
                Dim errors As New List(Of String)
                If skin.FormSkinPath Is Nothing Then errors.Add("Property 'SimpleSkin.FormBitmapPath' Is Nothing")
                If skin.Button1SkinPath Is Nothing Then errors.Add("Property 'SimpleSkin.Button1BitmapPath' Is Nothing")
                If skin.Button1MouseDownSkinPath Is Nothing Then errors.Add("Property 'SimpleSkin.Button1MouseDownBitmapPath' Is Nothing")
                If skin.Button1Location = Nothing Then errors.Add("Property 'SimpleSkin.Button1Location' Is Nothing")
                If Not System.IO.File.Exists(skin.FormSkinPath) Then errors.Add("Property 'SimpleSkin.Button1Location' Specified File Does Not Exist")
                If Not System.IO.File.Exists(skin.Button1SkinPath) Then errors.Add("Property 'SimpleSkin.Button1Location' Specified File Does Not Exist")
                If Not System.IO.File.Exists(skin.Button1MouseDownSkinPath) Then errors.Add("Property 'SimpleSkin.Button1Location' Specified File Does Not Exist")
                Throw New SkinIncompleteException(errors)
            End If
        End Function
    End Class
    Public Class SkinIncompleteException
        Inherits Exception
        Public Property Errors As List(Of String)
        Sub New(errors As List(Of String))
            Me.Errors = errors
        End Sub
    End Class
    Public Class SkinnableButton
        Inherits Button
        Private MySkin As Bitmap
        Private MouseDownSkin As Bitmap
        Private MouseIsDown As Boolean = False
        Protected Sub New()
            Me.SetStyle(ControlStyles.UserPaint, True)
        End Sub
        Protected Overrides Sub OnPaintBackground(pevent As PaintEventArgs)
            MyBase.OnPaintBackground(pevent)
        End Sub
        Protected Sub SetSkin(bmp As Bitmap, g As Graphics)
            Dim r As New Rectangle(New Point(0, 0), New Size(Me.Width, Me.Height))
            g.DrawImage(bmp, r)
        End Sub
        Protected Overrides Sub OnPaint(pevent As PaintEventArgs)
            Dim mouserect As New Rectangle(Me.PointToClient(MousePosition), New Size(1, 1))
            If MouseIsDown Then
                SetSkin(MouseDownSkin, pevent.Graphics)
            Else
                SetSkin(MySkin, pevent.Graphics)
            End If
            Exit Sub
        End Sub
        Protected Overrides Sub OnMouseDown(mevent As MouseEventArgs)
            Me.MouseIsDown = True
            MyBase.OnMouseDown(mevent)
        End Sub
        Protected Overrides Sub OnMouseUp(mevent As MouseEventArgs)
            Me.MouseIsDown = False
            MyBase.OnMouseUp(mevent)
        End Sub
        Public Shared Function Create(skin As SimpleSkin) As SkinnableButton
            Dim skBtn As New SkinnableButton()
            skBtn.Location = skin.Button1Location
            skBtn.MySkin = CType(Image.FromFile(skin.Button1SkinPath), Bitmap)
            skBtn.Size = skBtn.MySkin.Size
            skBtn.MouseDownSkin = CType(Image.FromFile(skin.Button1MouseDownSkinPath), Bitmap)
            Return skBtn
        End Function
    End Class
End Namespace

Classic Directsound example….

Hello the site that this was hosted on went down, so I figured now was a good time to bring it over to my blog. Later I will fix any “option strict off” errors, and review it against my current understanding of things.

Option Strict Off
Imports Microsoft.DirectX.DirectSound
Imports System.IO
Imports System.Text
Public Class Form1
    WithEvents SecondaryBuffer As SecondaryBuffer
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        '1. The latest DirectX SDK must be installed!
        '2. Add a Reference to C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\Microsoft.DirectX.DirectSound.dll
        '3. Imports Microsoft.DirectX.DirectSound
        '4. This uses .Net Framwork 2.0
        '5. go to Debug/Exceptions. OPen up the Managed Debugging Assistants node on the tree and scroll down till you find LoaderLock and uncheck it. 
        Dim WaveFileOptions As New Wave.WaveFileOptions
        Dim WaveFile As New Wave(WaveFileOptions)
        Dim ResourceBytes(My.Resources.NewWav.Length - 1) As Byte
        Dim Stream0 As UnmanagedMemoryStream = My.Resources.NewWav
        Dim Buffer(Stream0.Length - 1) As Byte
        Stream0.Read(Buffer, 0, Stream0.Length)
        Stream0.Dispose()
        WaveFile.SetDirectBytes(Buffer)
        Dim DXFormat As New Microsoft.DirectX.DirectSound.WaveFormat
        DXFormat.AverageBytesPerSecond = WaveFile.FileFormatSubChunk.ByteRate
        DXFormat.BitsPerSample = WaveFile.FileFormatSubChunk.BitsPerSample
        DXFormat.BlockAlign = WaveFile.FileFormatSubChunk.BlockAlign
        DXFormat.Channels = WaveFile.FileFormatSubChunk.NumChannels
        DXFormat.FormatTag = WaveFormatTag.Pcm
        DXFormat.SamplesPerSecond = WaveFile.FileFormatSubChunk.SampleRate
        Dim Desc As New BufferDescription(DXFormat)
        Dim BufferDescription As New Microsoft.DirectX.DirectSound.BufferDescription(DXFormat)
        BufferDescription.BufferBytes = WaveFileOptions.BitsPerSample
        BufferDescription.ControlFrequency = True
        BufferDescription.ControlPan = True
        BufferDescription.ControlVolume = True
        BufferDescription.GlobalFocus = True
        BufferDescription.StaticBuffer = True
        Dim Stream As New System.IO.MemoryStream(WaveFile.GetBytes)
        Dim SoundDevice As New Device
        SoundDevice.SetCooperativeLevel(Me.Handle, CooperativeLevel.Priority)
        SecondaryBuffer = New Microsoft.DirectX.DirectSound.SecondaryBuffer(Stream, BufferDescription, SoundDevice)
        SecondaryBuffer.Volume = -1
        SecondaryBuffer.Pan = 0
        SecondaryBuffer.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Looping)
    End Sub
End Class
Public Class Wave
    'By Paul Ishak
    'WAVE PCM soundfile format 
    'The Canonical WAVE file format
    'As Described Here: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
    Public FileHeader As Header
    Public FileFormatSubChunk As FormatSubChunk
    Public FileDataSubChunk As DataSubChunk
    Const _Byte As Integer = 1
    Const _word As Integer = 2
    Const _dword As Integer = 4
    Const _qword As Integer = 8
    Public Structure WaveFileOptions
        Public SampleRate As WavSampleRate
        Public AudioFormat As Format
        Public BitsPerSample As BitsPerSample
        Public NumberOfChannels As NumberOfChannels
        Public FormatSize As FormatSize
        Public NumberOfSamples As UInt32
        Public Data As Byte()
    End Structure
    '                                               DATATYPE          OFFSET        Endian           Description
    Structure Header
        Public Property ChunkID As Byte() '          Dword              0             Big            Contains the letters "RIFF" in ASCII form(0x52494646 big-endian form).
        Public Property ChunkSize As UInt32 '        Dword              4             Little         36 + SubChunk2Size, or more precisely: 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
        Public Property Format As Byte() '           Dword              8             Big            Contains the letters "WAVE" in ASCII form (0x57415645 big-endian form).
    End Structure
    Structure FormatSubChunk
        Public Property Subchunk1ID As Byte() '      Dword              12            Big            Contains the letters "fmt "(0x666d7420 big-endian form).
        Public Property Subchunk1Size As UInt32 '    Dword              16            little         16 for PCM.  This is the size of the rest of the Subchunk which follows this number.
        Public Property AudioFormat As UInt16  '     Word               20            little         PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression.
        Public Property NumChannels As UInt16 '      Word               22            little         Mono = 1, Stereo = 2, etc.
        Public Property SampleRate As UInt32 '       Dword              24            little         8000, 44100, etc.
        Public Property ByteRate As UInt32 '         Dword              28            little         == SampleRate * NumChannels * BitsPerSample/8
        Public Property BlockAlign As UInt16 '       Word               32            little         == NumChannels * BitsPerSample/8
        Public Property BitsPerSample As UInt16 '    Word               34            little         8 bits = 8, 16 bits = 16, etc.
    End Structure
    Structure DataSubChunk
        Public Property Subchunk2ID As Byte() '      Dword              36            Big            Contains the letters "data"(0x64617461 big-endian form).
        Public Property Subchunk2Size As UInt32 '    Dword              40            little         == NumSamples * NumChannels * BitsPerSample/8     This is the number of bytes in the data.
        Public Property Data As Byte() '             VariableLength     44            little         The actual sound data.
    End Structure
    Public Sub OpenFile(FileName As String)
        Try
            If Not InStr(LCase(FileName), ".wav") Then Throw New Exception("Invalid File Extension Specified!")
            If Not My.Computer.FileSystem.FileExists(FileName) Then Throw New Exception("File Does Not Exist!")
            Dim FileBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(FileName)
            'Get Header
            Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword)
            Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0)
            Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword)
            'Get FormatSubChunk
            Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword)
            Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0)
            Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0)
            Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0)
            Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0)
            Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0)
            Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0)
            Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0)
            'Get DataSubChunck
            Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword)
            Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0)
            Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size)
        Catch
            Throw New Exception("File Is Invalid or corrupt!")
        End Try
    End Sub
    Public Sub SetDirectBytes(FileBytes() As Byte)
        Try
            'Get Header
            Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword)
            Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0)
            Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword)
            'Get FormatSubChunk
            Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword)
            Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0)
            Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0)
            Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0)
            Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0)
            Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0)
            Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0)
            Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0)
            'Get DataSubChunck
            Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword)
            Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0)
            Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size)
        Catch ex As Exception
            ' Throw New Exception("File Is Invalid or corrupt!")
            MsgBox(ex.StackTrace)
        End Try
    End Sub
 
    Public Function GetBytes() As Byte()
        Dim Results As Byte() = Nothing
        Results = CombineArrays(FileHeader.ChunkID, BitConverter.GetBytes(FileHeader.ChunkSize))
        Results = CombineArrays(Results, FileHeader.Format)
        Results = CombineArrays(Results, FileFormatSubChunk.Subchunk1ID)
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.Subchunk1Size))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.AudioFormat))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.NumChannels))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.SampleRate))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.ByteRate))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BlockAlign))
        Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BitsPerSample))
        Results = CombineArrays(Results, FileDataSubChunk.Subchunk2ID)
        Results = CombineArrays(Results, BitConverter.GetBytes(FileDataSubChunk.Subchunk2Size))
        Results = CombineArrays(Results, FileDataSubChunk.Data)
        Return Results
    End Function
    Function CombineArrays(Array1() As Byte, Array2() As Byte) As Byte()
        Dim AllResults(Array1.Length + Array2.Length - 1) As Byte
        Array1.CopyTo(AllResults, 0)
        Array2.CopyTo(AllResults, Array1.Length)
        Return AllResults
    End Function
    Private Function GetDataFromByteArray(ByVal ByteArray As Byte(), ByVal BlockOffset As Long, ByVal RangeStartOffset As Long, ByVal DataLength As Long) As Byte()
        On Error Resume Next
        Dim AnswerL As New List(Of Byte)
        Dim Answer(0 To CInt((DataLength - 1))) As Byte
        Dim CurrentOffset As Long
        For I = 0 To UBound(ByteArray)
            CurrentOffset = BlockOffset + I
            If CurrentOffset >= RangeStartOffset Then
                If CurrentOffset <= RangeStartOffset + DataLength Then
                    AnswerL.Add(ByteArray(I))
                End If
            End If
        Next
        Dim count As Integer = -1
        For Each bt As Byte In AnswerL
            count = count + 1
            Answer(count) = bt
        Next
        Return Answer
    End Function
    Public Function ViewBinary(Optional HexOffsets As Boolean = True) As String
        Dim asc As New StringBuilder
        Dim Hex As New StringBuilder
        Dim result As New StringBuilder
        Dim MB As Byte() = Me.GetBytes
        Select Case HexOffsets
            Case True
                result.Append(" OFFSET " & "    " & "00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F  " & "    " & "0123456789ABCDEF" & vbCrLf & vbCrLf)
            Case False
                result.Append(" OFFSET " & "    " & "00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  " & "    " & "0123456789012345" & vbCrLf & vbCrLf)
        End Select
        Dim Count As Integer = -16
        For Each B As Byte In MB
            Count = Count + 1
            Hex.Append(B.ToString("X2") & "  ")
            If B > 32 And B < 128 Then
                asc.Append(Chr(B))
            Else
                asc.Append(".")
            End If
            If Count Mod 16 = 0 Then
                Select Case HexOffsets
                    Case True
                        result.Append(Count.ToString("X").PadLeft(8, "0") & "    " & Hex.ToString & "    " & asc.ToString & vbCrLf)
                    Case False
                        result.Append(Count.ToString.PadLeft(8, "0") & "    " & Hex.ToString & "    " & asc.ToString & vbCrLf)
                End Select
                Hex.Remove(0, Hex.ToString.Length)
                asc.Remove(0, asc.ToString.Length)
            End If
        Next
        Dim Counts As String = String.Empty
        Select Case HexOffsets
            Case True
                Counts = (Count + (16 - (Count Mod 16))).ToString("X").PadLeft(8, "0").ToString
            Case False
                Counts = (Count + (16 - (Count Mod 16))).ToString.PadLeft(8, "0").ToString
        End Select
        Dim H As Integer = 64 - Hex.ToString.Length
        Dim FinalHex As String = Hex.ToString & Space(H)
        result.Append(Counts & "    " & FinalHex & "    " & asc.ToString & vbCrLf)
        Return result.ToString
    End Function
    Public Shared Function SelectWavData(PictureBox As PictureBox, SelectionColor As Color, Origin As Integer, TextColor As Color, Optional SetLocal As Integer = -1) As SelectedData
        Dim LocalMousePosition As Point = PictureBox.PointToClient(Cursor.Position)
        Dim BM As New Bitmap(PictureBox.Size.Width, PictureBox.Size.Height)
        Dim gr As Graphics = Graphics.FromImage(BM)
        Dim Pen As New Pen(Brushes.Green, 1)
        If SetLocal > -1 Then
            LocalMousePosition.X = SetLocal
        End If
        If LocalMousePosition.X > PictureBox.ClientRectangle.Width Then
            LocalMousePosition.X = PictureBox.ClientRectangle.Width
        End If
        If LocalMousePosition.X < 0 Then
            LocalMousePosition.X = 0
        End If
        Dim Line1point1 As New Point(LocalMousePosition.X, 0)
        Dim Line1point2 As New Point(LocalMousePosition.X, PictureBox.ClientRectangle.Height)
        Dim Line2point1 As New Point(Origin, 0)
        Dim Line2point2 As New Point(Origin, PictureBox.ClientRectangle.Height)
        Dim Poly(3) As Point
        Poly(0) = Line1point1
        Poly(1) = Line2point1
        Poly(2) = Line2point2
        Poly(3) = Line1point2
        If Origin = LocalMousePosition.X = False Then
            gr.FillPolygon(New SolidBrush(SelectionColor), Poly)
            '  gr.DrawPolygon(New Pen(Brushes.Yellow, 2), Poly)
        End If
        PictureBox.Image = BM
        Select Case LocalMousePosition.X > Origin
            Case True
                gr.DrawString("Selected Range(" & Origin & "-" & LocalMousePosition.X & ")", New Font("Consolas", 8), New SolidBrush(TextColor), 1, 1)
                Return New SelectedData(Origin, LocalMousePosition.X)
            Case Else
                gr.DrawString("Selected Range(" & LocalMousePosition.X & "-" & Origin & ")", New Font("Consolas", 8), New SolidBrush(TextColor), 1, 1)
                Return New SelectedData(LocalMousePosition.X, Origin)
        End Select
    End Function
    Public Shared Sub DrawWave(PictureBox As PictureBox, GridSize As Integer, CurrentWaveFile As Wave, GridColor As Color, SineColor As Color)
        Dim Bytes As Byte() = CurrentWaveFile.FileDataSubChunk.Data
        Dim Data(0 To UBound(Bytes)) As UInt16
        Dim Count As Integer = -1
        For Each b As Byte In Bytes
            Count = Count + 1
            Data(Count) = CType(b, UInt16)
        Next
 
        Dim InvertedData(0 To UBound(Bytes)) As UInt32
        For I = 0 To UBound(Data)
            InvertedData(I) = ((255 - Data(I)) \ 2) + ((PictureBox.Height - (255 \ 2)) \ 2)
        Next
        Dim Points As New List(Of Point)
        For I = 0 To UBound(InvertedData)
            Dim Point As New Point(InvertedData(I), I + 1)
            Points.Add(Point)
        Next
        Dim PointsArr() As Point = Points.ToArray
        Dim BM As New Bitmap(PictureBox.Height, PictureBox.Width)
        Dim gr As Graphics = Graphics.FromImage(BM)
        Dim Pen As New Pen(SineColor, 1)
        Dim pen2 As New Pen(Brushes.Red, 3)
        Dim pen3 As New Pen(GridColor, 1)
        For I = 1 To PictureBox.Width Step GridSize
            gr.DrawLine(pen3, New Point(0, I), New Point(PictureBox.Height, I))
            gr.DrawLine(pen3, New Point(I, 0), New Point(I, PictureBox.Width))
        Next
        gr.DrawLines(Pen, PointsArr)
        gr.DrawLine(pen2, New Point(0, PictureBox.ClientRectangle.Width / 2), New Point(PictureBox.Height, PictureBox.ClientRectangle.Width / 2))
        gr.DrawLine(pen3, New Point(0, PictureBox.ClientRectangle.Width / 2), New Point(PictureBox.Height, PictureBox.ClientRectangle.Width / 2))
        BM.RotateFlip(RotateFlipType.Rotate270FlipNone)
        PictureBox.BackgroundImage = BM
    End Sub
    Public Structure SelectedData
        Public SelectionStart As Integer
        Public SelectionEnd As Integer
        Sub New(SelectionStart As Integer, SelectionEnd As Integer)
            Me.SelectionStart = SelectionStart
            Me.SelectionEnd = SelectionEnd
        End Sub
    End Structure
    Sub New(Options As WaveFileOptions)
        FileHeader.ChunkID = Encoding.ASCII.GetBytes("RIFF")
        FileFormatSubChunk.Subchunk1Size = Options.FormatSize
        FileFormatSubChunk.NumChannels = Options.NumberOfChannels
        FileFormatSubChunk.BitsPerSample = Options.BitsPerSample
        FileDataSubChunk.Subchunk2Size = Options.NumberOfSamples * Options.NumberOfChannels * Options.BitsPerSample / 8
        FileHeader.ChunkSize = 4 + (8 + FileFormatSubChunk.Subchunk1Size) + (8 + FileDataSubChunk.Subchunk2Size)
        FileHeader.Format = Encoding.ASCII.GetBytes("WAVE")
        FileFormatSubChunk.Subchunk1ID = Encoding.ASCII.GetBytes("fmt ")
        FileFormatSubChunk.AudioFormat = Options.AudioFormat
        FileFormatSubChunk.SampleRate = Options.SampleRate
        FileFormatSubChunk.ByteRate = Options.SampleRate * Options.NumberOfChannels * Options.BitsPerSample / 8
        FileFormatSubChunk.BlockAlign = Options.NumberOfChannels * Options.BitsPerSample / 8
        FileDataSubChunk.Subchunk2ID = Encoding.ASCII.GetBytes("data")
        FileDataSubChunk.Data = Options.Data
    End Sub
    Public Enum WavSampleRate As UInt32
        hz8000 = 8000
        hz11025 = 11025
        hz16000 = 16000
        hz22050 = 22050
        hz32000 = 32000
        hz44100 = 44100
        hz48000 = 48000
        hz96000 = 96000
        hz192000 = 192000
    End Enum
    Public Enum Format As UInt16
        Standard = 1
    End Enum
    Public Enum BitsPerSample As UInt16
        bps_8 = 8
        bps_16 = 16
        bps_32 = 32
        bps_64 = 64
        bps_128 = 128
        bps_256 = 256
    End Enum
    Public Enum NumberOfChannels As UInt16
        Mono = 1
        Stereo = 2
    End Enum
    Public Enum FormatSize As UInt32
        PCM = 16
    End Enum
End Class

GraphicsFrameClass

Recently I realized that more and more I am wanting to create buffered graphics when I draw with gdi, vs. the traditional direct use of a graphics object.

I have recently come up with this class that makes things easier. I wanted to share it with the community, so please enjoy.

Example of the GraphicsFrame Class’s Usage:

Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim Frame As New GraphicsFrame(Me.Handle, Me.ClientRectangle.Size)
        With Frame.Graphics
            .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            .Clear(Me.BackColor)
            .FillEllipse(Brushes.Red, New Rectangle(10, 10, 100, 100))
            .DrawEllipse(Pens.Green, New Rectangle(10, 10, 100, 100))
            .DrawString("Hello world!", New Font("Consolas", 12), Brushes.Black, New Point(10, 10))
        End With
        Frame.Render()
    End Sub
End Class

The GraphicsFrame Class:

''' <summary>
''' The graphics frame is designed to allow for a quick implementation of buffered graphics.
''' </summary>
''' <remarks></remarks>
Public Class GraphicsFrame
    Private context As System.Drawing.BufferedGraphicsContext
    Private backBuffer As System.Drawing.BufferedGraphics
    Private Property _canvasGraphics As System.Drawing.Graphics
    Private Property _maximumBuffer As System.Drawing.Size
    Public ReadOnly Property Graphics() As System.Drawing.Graphics
        Get
            Return backBuffer.Graphics
        End Get
    End Property
    Public Sub New(ByRef canvas As System.Windows.Forms.Control)
        Me._canvasGraphics = canvas.CreateGraphics
        Me._maximumBuffer = canvas.ClientRectangle.Size
        context = BufferedGraphicsManager.Current
        context.MaximumBuffer = New Size(_maximumBuffer.Width + 1, _maximumBuffer.Height + 1)
        backBuffer = context.Allocate(_canvasGraphics, New Rectangle(0, 0, _maximumBuffer.Width, _maximumBuffer.Height))
    End Sub
    Public Sub New(ByRef canvasGraphics As Graphics, maximumBuffer As Size)
        Me._canvasGraphics = canvasGraphics
        Me._maximumBuffer = maximumBuffer
        context = BufferedGraphicsManager.Current
        context.MaximumBuffer = New Size(_maximumBuffer.Width + 1, _maximumBuffer.Height + 1)
        backBuffer = context.Allocate(_canvasGraphics, New Rectangle(0, 0, _maximumBuffer.Width, _maximumBuffer.Height))
    End Sub
    Public Sub New(ByVal handle As IntPtr, maximumBuffer As Size)
        Me._canvasGraphics = Graphics.FromHwnd(handle)
        Me._maximumBuffer = maximumBuffer
        context = BufferedGraphicsManager.Current
        context.MaximumBuffer = New Size(_maximumBuffer.Width + 1, _maximumBuffer.Height + 1)
        backBuffer = context.Allocate(_canvasGraphics, New Rectangle(0, 0, _maximumBuffer.Width, _maximumBuffer.Height))
    End Sub
    Public Sub New(ByRef canvas As Image)
        Me._canvasGraphics = Graphics.FromImage(canvas)
        Me._maximumBuffer = canvas.Size
        context = BufferedGraphicsManager.Current
        context.MaximumBuffer = New Size(_maximumBuffer.Width + 1, _maximumBuffer.Height + 1)
        backBuffer = context.Allocate(_canvasGraphics, New Rectangle(0, 0, _maximumBuffer.Width, _maximumBuffer.Height))
    End Sub
    Public Sub New(ByRef canvas As Bitmap)
        Me._canvasGraphics = Graphics.FromImage(canvas)
        Me._maximumBuffer = canvas.Size
        context = BufferedGraphicsManager.Current
        context.MaximumBuffer = New Size(_maximumBuffer.Width + 1, _maximumBuffer.Height + 1)
        backBuffer = context.Allocate(_canvasGraphics, New Rectangle(0, 0, _maximumBuffer.Width, _maximumBuffer.Height))
    End Sub
    Public Sub Render()
        If Not backBuffer Is Nothing Then backBuffer.Render()
    End Sub
End Class

Links to previously published Technet Wiki articles

I have decided that I will be using wordpress as a primary location to publish content to the internet. That being said, I am also including links to past community contributions on my wordpress site. Thank you.

 

Pull Out Panel – Borderless Form – Visual Basic.Net
Visual Basic – Accessing a method Via its declared name string.
Visual Basic – Changing the speed of a wavefile
LoOps! With Visual Basic.Net
Conditional Branches With Visual Basic.Net
Dos Scripts From Visual Basic.Net
Visual Basic.Net Common Errors – Index was out of range.
Pattern Matching Words With Visual Basic
How To Convert a 32 Bit integer into a color
Virtual Memory In Visual Basic.Net
Bitmap.Lockbits De-Mystified .Net
Visual Basic – Knife Thrower!
Visual Basic – Drive Searcher
Workaround – Visual Basic/C# WebBrowser DBLClick Word
Convert System.Decimal to and from Byte Arrays (VB & C#)
Become More Productive by Making Custom Code Generation Tools(VB & C#)
Declaring Numeric Data Types
Braille Code in .Net
Evaluating Expressions – Visual Basic

 

Guild wars 2 API Wrapper

So…. Been working on this wrapper for gw2 client. I really want to explore the whole api and see what I can make……
If you know how to use this, then you are welcome to use it for whatever you want.

Option Strict On
Option Explicit On
Option Infer Off
Imports System.Net
Imports Newtonsoft.Json
Imports System.Xml
Imports System.IO
Namespace GW2API
    Public Class Client
        Public Shared Function ItemJSON(itemID As String) As String
            Dim gw2API As String = "https://api.guildwars2.com/v1/item_details.json?item_id=" & itemID
            Dim json As String = String.Empty
            Using w As New WebClient
                Try
                    json = w.DownloadString(gw2API)
                Catch
                    json = ""
                End Try
            End Using
            Return json
        End Function
        Public Shared Function ItemXMLFromID(itemID As String) As String
            Return ItemXMLFromJSON(ItemJSON(itemID))
        End Function
        Public Shared Function ItemXMLFromJSON(json As String) As String
            Return GetXMLString(ItemJSONToXML(json))
        End Function
        Public Shared Function ItemJSONToXML(json As String) As XmlDocument
            Try
                Return DirectCast(JsonConvert.DeserializeXmlNode("{GuildWars2Item:" & json & "}"), XmlDocument)
            Catch ex As Exception
                Return New XmlDocument
            End Try
        End Function
        Private Shared Function GetXMLString(xmlDoc As XmlDocument) As String
            If xmlDoc Is Nothing Then Return ""
            Dim result As String = String.Empty
            Using sw As New StringWriter
                Using xw As New XmlTextWriter(sw)
                    xw.Formatting = System.Xml.Formatting.Indented
                    xmlDoc.WriteTo(xw)
                End Using
                result = sw.ToString()
            End Using
            Return result
        End Function
    End Class
End Namespace
Option Strict On
Option Explicit On
Option Infer Off
Imports System.Xml
Imports System.IO
Imports System.Text
Imports System.Net
Namespace GW2API
    Public Class Item
#Region "Guild Wars 2 Item Properties"
        Public Property item_id As String
        Public Property name As String
        Public Property description As String
        Public Property type As String
        Public Property level As String
        Public Property rarity As String
        Public Property vendor_value As String
        Public Property icon_file_id As String
        Public Property icon_file_signature As String
        Public Property game_types As New List(Of String)
        Public Property default_skin As String
        Public Property flags As New List(Of String)
        Public Property weapon As String
        Public Property damage_type As String
        Public Property min_power As String
        Public Property max_power As String
        Public Property defense As String
        Public Property suffix_item_id As String
        Public Property secondary_suffix_item_id As String
        Public Property infix_upgrade As String
        Public Property attributes As String
        Public Property attribute As String
        Public Property modifier As String
        Public Property armor As String
        Public Property weight_class As String
        Public Property consumable As String
        Public Property unlock_type As String
        Public Property recipe_id As String
        Public Property container As String
        Public Property bag As String
        Public Property no_sell_or_sort As String
        Public Property size As String
        Public Property infusion_slots As String
        Public Property color_id As String
        Public Property trinket As String
        Public Property gizmo As String
        Public Property back As String
        Public Property upgrade_component As String
        Public Property bonuses As String
        Public Property suffix As String
        Public Property buff As String
        Public Property skill_id As String
        Public Property duration_ms As String
        Public Property restrictions As New List(Of String)
        Public Property infusion_upgrade_flags As String
        Public Property gathering As String
        Public Property tool As String
        Public Property charges As String
#End Region
#Region "Object Properties"
        ''' <summary>
        ''' This image may be assigned if you wish to return a custom 'image not available' image, 
        ''' otherwise the default embedded 'image not available' image will be returned from the image property.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property OverrideErrorImage As Image = Nothing
        ''' <summary>
        ''' A list of guild wars item properties in this object, that have values assigned to them.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property UsedProperties As New List(Of String)
        ''' <summary>
        ''' A list of unknown properties and their values, which did not exist at the time of the development of this wrapper.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property UnknownProperties As New List(Of UnknownProperty)
#Region "Embedded File"
        Public Shared Property defaultImageBytes As Byte() = {137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 64, 0, 0, 0, 64, 8,
                                   2, 0, 0, 0, 37, 11, 230, 137, 0, 0, 0, 1, 115, 82, 71, 66, 0, 174, 206, 28, 233, 0, 0, 0, 4,
                                   103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 14, 195, 0,
                                   0, 14, 195, 1, 199, 111, 168, 100, 0, 0, 3, 63, 73, 68, 65, 84, 104, 67, 221, 152, 189, 149, 219, 48, 16,
                                   132, 21, 41, 185, 72, 129, 130, 11, 156, 95, 1, 87, 132, 138, 80, 172, 62, 212, 135, 66, 181, 224, 18, 212, 138,
                                   235, 240, 14, 23, 252, 128, 165, 8, 30, 101, 75, 207, 183, 158, 55, 15, 15, 67, 226, 103, 6, 132, 5, 248, 54,
                                   255, 3, 126, 254, 250, 145, 148, 53, 64, 169, 165, 194, 52, 128, 103, 202, 66, 108, 11, 232, 68, 196, 182, 128, 78,
                                   68, 108, 11, 232, 68, 196, 182, 128, 78, 68, 108, 11, 232, 68, 196, 182, 128, 78, 68, 108, 11, 232, 68, 196, 182,
                                   128, 78, 68, 108, 11, 232, 68, 196, 182, 128, 78, 68, 108, 11, 232, 68, 196, 182, 128, 78, 68, 108, 11, 232, 192,
                                   235, 155, 191, 53, 28, 174, 227, 195, 219, 238, 112, 126, 175, 109, 214, 147, 209, 62, 119, 151, 248, 234, 114, 222, 250,
                                   155, 143, 71, 70, 182, 246, 94, 10, 232, 192, 78, 128, 19, 245, 135, 200, 104, 199, 253, 228, 213, 191, 8, 208, 184,
                                   97, 122, 150, 182, 62, 113, 184, 227, 166, 203, 249, 232, 181, 237, 233, 22, 218, 151, 0, 183, 221, 135, 235, 177, 193,
                                   44, 237, 181, 151, 2, 58, 176, 14, 212, 15, 48, 204, 138, 3, 111, 118, 185, 149, 133, 12, 206, 226, 114, 180, 25,
                                   66, 179, 50, 169, 61, 127, 63, 125, 122, 101, 156, 58, 210, 222, 121, 41, 160, 3, 215, 4, 24, 86, 55, 6, 240,
                                   137, 3, 26, 103, 165, 203, 24, 32, 228, 111, 235, 64, 125, 177, 212, 208, 94, 121, 41, 160, 3, 103, 3, 92, 119,
                                   90, 146, 126, 128, 217, 250, 227, 1, 150, 54, 143, 211, 26, 121, 41, 160, 35, 247, 7, 127, 93, 3, 216, 147, 183,
                                   179, 85, 86, 5, 168, 159, 66, 1, 98, 151, 21, 91, 72, 51, 90, 179, 186, 118, 145, 214, 200, 75, 1, 61, 101,
                                   243, 17, 6, 140, 11, 211, 9, 32, 7, 117, 11, 109, 15, 199, 242, 92, 205, 232, 82, 81, 70, 139, 221, 59, 95,
                                   254, 142, 246, 214, 75, 1, 157, 136, 216, 22, 208, 137, 136, 109, 1, 157, 136, 216, 22, 208, 137, 136, 109, 1, 157,
                                   136, 216, 22, 208, 137, 136, 109, 1, 221, 146, 67, 32, 226, 171, 35, 166, 249, 185, 92, 248, 17, 124, 136, 156, 122,
                                   237, 128, 38, 189, 20, 208, 119, 108, 238, 5, 119, 215, 224, 121, 126, 179, 0, 181, 115, 8, 80, 207, 154, 187, 15,
                                   178, 16, 96, 174, 23, 167, 88, 193, 112, 50, 134, 198, 159, 187, 211, 147, 3, 48, 180, 38, 179, 79, 20, 51, 244,
                                   2, 116, 122, 205, 95, 93, 219, 198, 53, 246, 147, 2, 212, 53, 43, 171, 181, 63, 249, 21, 192, 217, 9, 208, 233,
                                   213, 108, 209, 17, 22, 96, 210, 248, 201, 91, 232, 137, 1, 120, 104, 45, 169, 191, 60, 64, 220, 12, 54, 241, 91,
                                   216, 66, 157, 47, 62, 219, 171, 9, 80, 63, 197, 115, 183, 80, 231, 87, 168, 25, 180, 92, 33, 231, 94, 53, 24,
                                   46, 225, 51, 189, 24, 63, 94, 93, 219, 198, 127, 249, 143, 248, 219, 18, 219, 2, 58, 17, 177, 45, 160, 19, 17,
                                   219, 2, 58, 17, 177, 45, 160, 19, 17, 219, 2, 58, 17, 177, 45, 160, 3, 95, 112, 45, 123, 34, 205, 149, 151,
                                   2, 58, 240, 197, 1, 46, 231, 157, 14, 135, 63, 165, 185, 242, 82, 64, 7, 78, 142, 64, 242, 216, 65, 67, 125,
                                   56, 221, 234, 201, 239, 7, 86, 120, 50, 192, 207, 166, 248, 188, 158, 128, 117, 162, 175, 254, 179, 209, 208, 90, 123,
                                   41, 160, 3, 123, 1, 12, 109, 134, 120, 123, 113, 91, 139, 127, 30, 181, 144, 229, 79, 102, 26, 182, 204, 98, 214,
                                   253, 84, 94, 155, 193, 154, 122, 41, 160, 3, 39, 1, 144, 190, 156, 237, 7, 153, 24, 237, 220, 49, 103, 3, 76,
                                   191, 213, 184, 4, 95, 210, 90, 122, 41, 160, 3, 215, 5, 40, 75, 222, 4, 160, 222, 250, 243, 102, 245, 106, 56,
                                   237, 248, 192, 230, 113, 90, 31, 47, 5, 116, 96, 179, 73, 20, 32, 46, 249, 186, 0, 241, 142, 217, 12, 40, 248,
                                   237, 176, 110, 33, 77, 106, 9, 53, 23, 30, 250, 180, 62, 94, 10, 232, 192, 197, 0, 184, 92, 220, 66, 241, 142,
                                   217, 124, 82, 225, 254, 126, 238, 19, 97, 96, 145, 214, 216, 75, 1, 157, 136, 216, 22, 208, 137, 136, 109, 1, 157,
                                   136, 216, 22, 208, 137, 136, 109, 1, 157, 136, 216, 22, 208, 137, 136, 109, 1, 157, 136, 216, 22, 208, 137, 136, 109,
                                   1, 157, 136, 216, 22, 106, 45, 21, 66, 128, 164, 44, 1, 18, 99, 179, 249, 13, 103, 64, 168, 59, 156, 67, 74,
                                   244, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}
#End Region

        ''' <summary>
        ''' This property attempts to download the icon image for this guild wars object. If downloading fails, the specified or default 
        ''' 'image not available' image will be returned.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Image(Optional size As Size = Nothing) As Image
            Get
                If size = Nothing Then size = New Size(64, 64)
                Try
                    'https://render.guildwars2.com/file/{signature}/{file_id}.{format}
                    Dim api As String = String.Format("https://render.guildwars2.com/file/{0}/{1}.{2}", Me.icon_file_signature, Me.icon_file_id, "png")
                    Dim buffer As Byte()
                    Dim bm As Image
                    Using w As New WebClient
                        buffer = w.DownloadData(api)
                    End Using
                    Using s As New MemoryStream(buffer)
                        bm = Image.FromStream(s)
                    End Using
                    Dim resizedImage As New Bitmap(size.Width, size.Height)
                    Dim g As Graphics = Graphics.FromImage(resizedImage)
                    g.DrawImage(bm, 0, 0, resizedImage.Width + 1, resizedImage.Height + 1)
                    Return resizedImage
                Catch
                    Dim img As Image
                    Dim resizedImage As New Bitmap(size.Width, size.Height)
                    Dim g As Graphics = Graphics.FromImage(resizedImage)
                    Using ss As New MemoryStream(Item.defaultImageBytes)
                        If Me.OverrideErrorImage Is Nothing Then
                            img = Bitmap.FromStream(ss)
                        Else
                            img = Me.OverrideErrorImage
                        End If
                    End Using
                    g.DrawImage(img, 0, 0, resizedImage.Width + 1, resizedImage.Height + 1)
                    Return resizedImage
                End Try
            End Get
        End Property
#End Region
        ''' <summary>
        ''' Returns a string representation of this object. Unused properties are not included in this string representation.
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shadows Function ToString() As String
            Dim sb As New StringBuilder
            For Each s As String In UsedProperties
                Dim value As Object = GetPropValue(Me, s)
                Select Case value.GetType
                    Case GetType(String)
                        sb.Append(s & ": " & value.ToString & vbCrLf)
                    Case GetType(List(Of String))
                        Dim str As List(Of String) = DirectCast(value, List(Of String))
                        Dim arr As String = String.Empty
                        For Each ss As String In str
                            arr = arr & ss & ", "
                        Next
                        arr = arr.Substring(0, arr.Length - 2)
                        sb.Append(s & ": " & arr & vbCrLf)
                    Case Else

                End Select

            Next
            Return sb.ToString
        End Function
        ''' <summary>
        ''' Returns a listviewitem with values in the order specified by the order of the property names supplied in the propertyOrder string.
        ''' </summary>
        ''' <param name="propertyOrder">Provide a list of property names, from the "GW2API.Item" object, to return the 
        ''' values of those properties, in the order provided.</param>
        ''' <returns>Returns a ListViewItem containing the values of the specified properties, from this object, in the order provided.</returns>
        ''' <remarks></remarks>
        Public Function ToListViewItem(propertyOrder As List(Of String)) As ListViewItem
            Dim item As New ListViewItem("error")
            Dim values As List(Of Object) = Me.GetOrderedPropertyValues(propertyOrder)
            Dim currentPropName As String = String.Empty
            Dim index As Integer = -1
            Try
                For i As Integer = 0 To values.Count - 1
                    Dim s As Object = values(i)
                    index += 1
                    currentPropName = propertyOrder(index)
                    If s Is Nothing Then Continue For
                    Select Case s.GetType
                        Case GetType(String)
                            Dim str As String = DirectCast(s, String)
                            If index = 0 Then
                                item.Text = str
                                Continue For
                            End If
                            item.SubItems.Add(str)
                        Case GetType(List(Of String))
                            Dim str As List(Of String) = DirectCast(s, List(Of String))
                            Dim arr As String = String.Empty
                            For Each ss As String In str
                                arr = arr & ss & ", "
                            Next
                            arr = arr.Substring(0, arr.Length - 2)
                            If index = 0 Then
                                item.Text = arr
                                Continue For
                            End If
                            item.SubItems.Add(arr)
                        Case Else
                            item.SubItems.Add(s.ToString)
                    End Select
                Next
            Catch
            End Try
            Return item
        End Function
        Public Function GetOrderedPropertyValues(properties As List(Of String)) As List(Of Object)
            Dim result As New List(Of Object)
            For Each p As String In properties
                result.Add(GW2API.Item.GetPropValue(Me, p))
            Next
            Return result
        End Function
        Public Shared Function GetPropValue(src As Object, propName As String) As Object
            Try
                Return src.GetType.GetProperty(propName).GetValue(src, Nothing)
            Catch
                Return Nothing
            End Try
        End Function
        Public Class UnknownProperty
            Public PropertyName As String
            Public PropertyValues As New List(Of String)
            Public Property PropertyObject As Object
            Sub New(PropertyName As String, PropertyValues As Object)
                Me.PropertyName = PropertyName
                Select Case True
                    Case PropertyValues.GetType = GetType(List(Of String))
                        Me.PropertyValues = DirectCast(PropertyValues, List(Of String))
                    Case PropertyValues.GetType = GetType(String)
                        Me.PropertyValues.Add(DirectCast(PropertyValues, String))
                End Select
                Me.PropertyObject = PropertyValues
            End Sub
        End Class
        Private Shared Function GetAllJsonItems(filePath As String, delimiter As Char()) As List(Of String)
            Dim db As String = My.Computer.FileSystem.ReadAllText(filePath)
            Dim items As String() = db.Split(delimiter, StringSplitOptions.RemoveEmptyEntries)
            Return items.ToList
        End Function
        Public Shared Function FromID(ID As String) As Item
            Dim json As String = Client.ItemJSON(ID)
            Return Item.FromJson(json)
        End Function
        Public Shared Function FromJson(json As String) As Item
            Dim result As New Item
            Dim xml As String = Client.ItemXMLFromJSON(json)
            If xml = "" Then Return result
            Dim xmlReader As XmlReader = New XmlTextReader(New StringReader(xml))
            Dim doc As XmlDocument = Client.ItemJSONToXML(json)

            While xmlReader.Read
                Dim value As String = xmlReader.Value

                If xmlReader.NodeType = XmlNodeType.Element Then
                    Dim eleName As String = xmlReader.Name
                    If eleName = "GuildWars2Item" Then Continue While
                    If result.UsedProperties.IndexOf(eleName) > -1 Then Continue While
                    result.UsedProperties.Add(eleName)
                    Dim valueList As XmlNodeList = doc.GetElementsByTagName(xmlReader.Name)
                    Select Case eleName
                        Case "item_id" : result.item_id = valueList(0).InnerXml
                        Case "name" : result.name = valueList(0).InnerXml
                        Case "description" : result.description = valueList(0).InnerXml
                        Case "type" : result.type = valueList(0).InnerXml
                        Case "level" : result.level = valueList(0).InnerXml
                        Case "rarity" : result.rarity = valueList(0).InnerXml
                        Case "vendor_value" : result.vendor_value = valueList(0).InnerXml
                        Case "icon_file_id" : result.icon_file_id = valueList(0).InnerXml
                        Case "icon_file_signature" : result.icon_file_signature = valueList(0).InnerXml
                        Case "game_types"
                            For Each s As XmlNode In valueList
                                If result.game_types.IndexOf(s.InnerXml) > -1 Then Continue For
                                result.game_types.Add(s.InnerXml)
                            Next
                        Case "default_skin" : result.default_skin = valueList(0).InnerXml
                        Case "flags"
                            For Each s As XmlNode In valueList
                                If result.flags.IndexOf(s.InnerXml) > -1 Then Continue For
                                result.flags.Add(s.InnerXml)
                            Next
                        Case "weapon" : result.weapon = valueList(0).InnerXml
                        Case "damage_type" : result.damage_type = valueList(0).InnerXml
                        Case "min_power" : result.min_power = valueList(0).InnerXml
                        Case "max_power" : result.max_power = valueList(0).InnerXml
                        Case "defense" : result.defense = valueList(0).InnerXml
                        Case "suffix_item_id" : result.suffix_item_id = valueList(0).InnerXml
                        Case "secondary_suffix_item_id" : result.secondary_suffix_item_id = valueList(0).InnerXml
                        Case "infix_upgrade" : result.infix_upgrade = valueList(0).InnerXml
                        Case "attributes" : result.attributes = valueList(0).InnerXml
                        Case "attribute" : result.attribute = valueList(0).InnerXml
                        Case "modifier" : result.modifier = valueList(0).InnerXml
                        Case "armor" : result.armor = valueList(0).InnerXml
                        Case "weight_class" : result.weight_class = valueList(0).InnerXml
                        Case "consumable" : result.consumable = valueList(0).InnerXml
                        Case "unlock_type" : result.unlock_type = valueList(0).InnerXml
                        Case "recipe_id" : result.recipe_id = valueList(0).InnerXml
                        Case "container" : result.container = valueList(0).InnerXml
                        Case "bag" : result.bag = valueList(0).InnerXml
                        Case "no_sell_or_sort" : result.no_sell_or_sort = valueList(0).InnerXml
                        Case "size" : result.size = valueList(0).InnerXml
                        Case "infusion_slots" : result.infusion_slots = valueList(0).InnerXml
                        Case "color_id" : result.color_id = valueList(0).InnerXml
                        Case "trinket" : result.trinket = valueList(0).InnerXml
                        Case "gizmo" : result.gizmo = valueList(0).InnerXml
                        Case "back" : result.back = valueList(0).InnerXml
                        Case "upgrade_component" : result.upgrade_component = valueList(0).InnerXml
                        Case "bonuses" : result.bonuses = valueList(0).InnerXml
                        Case "suffix" : result.suffix = valueList(0).InnerXml
                        Case "buff" : result.buff = valueList(0).InnerXml
                        Case "skill_id" : result.skill_id = valueList(0).InnerXml
                        Case "duration_ms" : result.duration_ms = valueList(0).InnerXml
                        Case "restrictions"
                            For Each s As XmlNode In valueList
                                If result.restrictions.IndexOf(s.InnerXml) > -1 Then Continue For
                                result.restrictions.Add(s.InnerXml)
                            Next
                        Case "infusion_upgrade_flags" : result.infusion_upgrade_flags = valueList(0).InnerXml
                        Case "gathering" : result.gathering = valueList(0).InnerXml
                        Case "tool" : result.tool = valueList(0).InnerXml
                        Case "charges" : result.charges = valueList(0).InnerXml
                        Case Else
                            Dim unknowns As New List(Of String)
                            For Each s As XmlNode In valueList
                                If unknowns.IndexOf(s.InnerXml) > -1 Then Continue For
                                unknowns.Add(s.InnerXml)
                            Next
                            result.UnknownProperties.Add(New UnknownProperty(eleName, unknowns))
                    End Select
                End If
            End While
            Return result
        End Function
    End Class
End Namespace

Stuff for beginners


In Visual Basic, when you create a new Windows Forms Application an editor will open up with a blank form that you can add controls to. This area where you drag controls from the toolbox to your new form is known as ‘The Designer’. Below is a picture of the designer.


So with Windows Forms, you can drag and drop(from the toolbox), and re-size and arrange the layout of various controls, and design your program’s UI(User Interface). You will see in the image below that there are many pre-packaged controls that come with visual studio that you can drag from the toolbox onto your program’s Form(User Interface/window)

In order for a control to be useful, the control has to have a purpose. For instance, a button has the purpose of being clicked. But how would you know that button has been clicked, or that what was clicked was the button or not something else?

The answer is simple, controls in Visual Basic will raise an event when the user interacts with it.  Events are also triggered by various other means. In the case of a button being clicked, the Button.Click event would be raised. With that being said, some would say that writing a Visual Basic application with Visual Studio consists of two different parts.

1.) Drawing out your user interface.

2.) Writing code for events triggered by your application.

This description would saffice for the beginner, but as you progress in your learning, you will find that even the ‘Visual’ part of writing software with Visual Basic is code, and eventually you may find that it is more practical to do almost your entire application via code verses using the design interface. Lets say for instance that we have dragged from the toolbox, a button control, and placed it on a Form as shown in the image below.

And now, lets say we have gone through the process of designing our application’s interface by dragging and arranging controls on the form, like in the image below

We have drawn an interface that allows for the saving and opening of a text file. But alone this interface is useless. Just because we have said “Open File” on a button, does not mean that the button is now able to open a file. There is more work to be done. We have only drawn the interface and not created code for performing file operations, but the design of the interface suggests that we will be editing the content of the larger control on the form(RichTextBox).

So now we have to make those controls do something. If you double click on any of the buttons, Visual Basic will generate a sub routine(code block) for you(that handles the most common user-raised event for that control).

Inside this sub routine is where you will write the instructions of what you want the program to do when the user interacts with that control. Below is an example image of what will be generated when you double click the ‘Open File’ button (in design mode).

Access Modifiers are what determines the level of visibulity for that particular method(this applies to objects as well).

Access Modifiers Definitions

Public – Unrestricted: Any code that can see a public element can access it

Protected – Derivational: Code in the class that declares a protected element, or a class derived from it, can access the element

Friend – Assembly: Code in the assembly that declares a friend element can access it

Protected Friend – Union of Protected and Friend: Code in the same class or the same assembly as a protected

friend element, or within any class derived from the element’s class, can access it

Private – Declaration context: Code in the type that declares a private element, including code within contained types, can access the element

Type Of Method

There are two basic types of methods. Methods that return a value, and methods that do not return a value.

A method that returns a value is called a Function. A Method that does not return a value is called a Subroutine or Sub.

Accessability/Method Name

The method name is how the method will be referred to when you desire to execute it.

there are only a few basic rules when it comes to naming a method:

1.)Method must start with a letter or an underscore. 2.) Method May only contain letters, numbers, or an underscore

There are standards and practices for naming in Visual Basic, to learn more about this, visit this link:

Full Naming Conventions

Signature/Arguments

These are values that the method requires in order to do its work. You cannot add a handles clause for an event to a method if they do not have matching signatures, invalid data will be passed to the method causing errors.

Handles Clause

This can only be used if a control has been declared ‘WithEvents’. Example:

Friend WithEvents Button1 As New System.Windows.Forms.Button

The above example can utilize the Handles Clause feature for assigning an Event handler

Public Button1 As New System.Windows.Forms.Button

The above example cannot utilize the Handles Clause feature for assigning an Event handler, AddHandler must be used.

Handled Event

In Visual Basic you can refer to an event by typing the name of an object and after that when you press the decimal sign at the end of the name of the object, available properties, methods, and events will be listed in a listbox.
The events are the ones with the lightening bolts next to them.

Method Ending Statement

This is pretty cut and dry, if your method is a function then your method ending statement will be End Function. If your method is a sub-routine, then your method ending statement will be End Sub

This was a brief covering from drawing an interface up to the point where you double click the controls in design mode to start coding.