Author Archives: Paul

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!

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

Background Worker Illegal crossthread operation

A user of the MSDN forums asked the following question:(in this thread)

Hi, I want to thank everyone in advance for any help you can offer. I am an amateur programmer and I have been able to turn to this forum repeatedly for help with my problems — and this is deeply appreciated by me! Thank you!

I want to load a .csv file into a datagridview. The .csv file has 10 columns and at least 70,000 to 100,000 rows. When the program loads the file, the whole program freezes for several minutes. I eventually figured out that I could use a background worker to do things. However, when I tried to have the background worker add rows to the datagridview, I got an error message saying that it couldn’t because the datagridview was created on another thread than its own. …. I am wondering how I can solve this issue? Here is the program:

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub
    Private Sub bw() Handles BackgroundWorker1.DoWork
        get_main_catalog_of_items()
    End Sub
    Private Sub get_main_catalog_of_items()
        Datagridview1.Rows.Clear()
        Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("c:\catalogs\catalog_main.csv")
            MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
            MyReader.Delimiters = New String() {vbTab}
            Dim currentRow As Strng()
            While Not MyReader.EndOfData
                Try
                    currentRow = MyReader.ReadFields()
                    DataGridView1.Rows.Add(currentRow)
                Catch ex As Exception
                End Try
            End While
        End Using
    End Sub
End Class

Basically, what is happening is that when you access an object on one thread from another thread, this creates an unstable system environment. The way for getting around this is to check and see if an invoke is required for that object, and basically, if it is, you invoke a new delegate sub on the same thread of the datagridview, hence avoiding access across threads, because the delegate sub exists on the same thread as the datagridview. See example

Example

Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
    Dim bgw As New System.ComponentModel.BackgroundWorker
    Private Delegate Sub addDGVRow(dgv As DataGridView, row As DataGridViewRow)
    Sub doRowAdd(dgv As DataGridView, row As DataGridViewRow)
        If dgv.InvokeRequired Then
            dgv.Invoke(New addDGVRow(AddressOf doRowAdd), dgv, row)
        Else
            dgv.Rows.Add(row)
        End If
    End Sub
    Sub work(sender As Object, e As EventArgs)
        For i As Integer = 0 To 1000
            Dim row As New DataGridViewRow
            row.Cells.Add(New DataGridViewTextBoxCell With {.Value = i.ToString})
            row.Cells.Add(New DataGridViewTextBoxCell With {.Value = (i + 1).ToString})
            doRowAdd(DataGridView1, row)
        Next
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        DataGridView1.ColumnCount = 2
        AddHandler bgw.DoWork, AddressOf work
        bgw.RunWorkerAsync()
    End Sub
End Class

Here is the solution applied to your code:

Option Strict On
Option Explicit On
Option Infer Off
Imports System.ComponentModel
Public Class Form1
    Private Delegate Sub addDGVRow(dgv As DataGridView, row As String())
    Sub doRowAdd(dgv As DataGridView, row As String())
        If dgv.InvokeRequired Then
            dgv.Invoke(New addDGVRow(AddressOf doRowAdd), dgv, row)
        Else
            dgv.Rows.Add(row)
        End If
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub
    Private Sub bw() Handles BackgroundWorker1.DoWork
        get_main_catalog_of_items()
    End Sub
    Private Sub get_main_catalog_of_items()
        Datagridview1.Rows.Clear()
        Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("c:\catalogs\catalog_main.csv")
            MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
            MyReader.Delimiters = New String() {vbTab}
            Dim currentRow As String()
            While Not MyReader.EndOfData
                currentRow = MyReader.ReadFields()
                doRowAdd(DataGridView1, currentRow)
            End While
        End Using
    End Sub
End Class

Create function from Code

In the following StackOverFlow Question

I have been asked to edit this code…..

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If DateTime.Now.Hour >= 6 And DateTime.Now.Hour < 12 Then
        Message.Text = "Good Morning"
    End If

    If DateTime.Now.Hour >= 12 And DateTime.Now.Hour <= 17 Then
        Message.Text = "Good Afternoon"
    End If

    If DateTime.Now.Hour > 17 Or DateTime.Now.Hour < 6 Then
        Message.Text = "Good Evening"
    End If
End Sub

and change it into a function. the original code basically displays one of the messages on a webpage when opened depending what time of day it is. I was looking for some help on how or what i need to change to turn it into a function.

The code below i have edit but only slightly so anything that looks completely wrong will be because i have only edited a small part of it so the ByVal in the function i have to not tried to implement into the function as i am a bit stuck.

Private Function Greetings(goodMorning as string, goodAfternoon as String, goodEvening as String) as String

Dim outPut As String

If DateTime.Now.Hour >= 6 And DateTime.Now.Hour < 12 Then
            Message.Text = "Good Morning."
    ElseIf
        DateTime.Now.Hour >= 12 And DateTime.Now.Hour <= 17 Then
        Message.Text = "Good Afternoon."
    ElseIf 
        DateTime.Now.Hour >= 12 And DateTime.Now.Hour <= 17 Then
        Message.Text = "Good Afternoon."

    Return outPut
  End Function

When you write a Method, you need to take the following into consideration:

1.) Access Level
2.) Method Type(Function? or Sub?)
*A function will return a value, a sub will perform an operation without returning a value.

3.) Method Naming. Example, a function that returns someones age could be named “GetAge”
4.) Any parameters you may wish to pass.
5.) If you create a function, you need to declare the function “As” it’s expected return type
example:

A function that will return a string may be created like this:

Public Function GetString(param As String) As String
    Return "Hello" & param
End Function

The usage of that function may look like this:

Me.Text = GetString(" World!")

So inside your function that you are expected to create, instead of directly modifying an object’s text property, you will return the message using the “Return” keyword. When that function is used later, you will set the object’s text property with the direct output of your function.

You should create a function similar to this:

    Private Function GetGreeting() As String
        If DateTime.Now.Hour >= 6 And DateTime.Now.Hour < 12 Then
            Return "Good Morning"
        ElseIf DateTime.Now.Hour >= 12 And DateTime.Now.Hour <= 17 Then
            Return "Good Afternoon"
        Else
            Return "Good Evening"
        End If
    End Function

List Files in a folder

A user in the MSDN forums asked the following question in the following thread:

Hello, I am very new to programming and would like some help. I need a program that will search in a supplied folder and list all PDF type of file in a text box, and then have the operator select the file to open.

Can someone show me the code to do this?

Here is how I would.

    ''' <summary>
    ''' Returns the path to a pdf file that the user selected. Returns a blank if the user cancelled.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function OpenPDF() As String
        Dim OFD As New OpenFileDialog
        OFD.Filter = "Pdf Files|*.pdf"
        If OFD.ShowDialog = DialogResult.OK Then
            Return OFD.FileName
        End If
        Return ""
    End Function