Posts Tagged ‘.net

05
May
09

[VB.Net] FindWindowsIndexOf – .Netish Version

A more .net style function for getting a window using an indexOf:

    ''API Imports
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
    End Sub
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    ''FoundWindow stricture
    Public Structure FoundWindow
        Dim strWindowName As String
        Dim strClassName As String
        Dim hWnd As IntPtr
    End Structure

    ''' <summary>
    ''' This function is used to loop through all running processes, checking their main windows to see which ones contain a specific string
    ''' </summary>
    ''' <param name="strIndexOf">The string that you wish to check for in the window captions</param>
    ''' <param name="boolCase">Whether the function is should check for case</param>
    ''' <returns>A list of FoundWindow's containing the window name, class and handle</returns>
    ''' <remarks>As this function only loops through running processes main windows, it may miss some windows.</remarks>
    Public Function FindWindowsIndexOf(ByVal strIndexOf As String, ByVal boolCase As Boolean) As List(Of FoundWindow)
        Dim foundWindows As New List(Of FoundWindow)
        If boolCase = False Then
            strIndexOf = strIndexOf.ToLower
        End If
        For Each p As Process In Process.GetProcesses
            Dim windowCaption As String = p.MainWindowTitle
            If boolCase = False Then
                windowCaption = windowCaption.ToLower
            End If
            If windowCaption.IndexOf(strIndexOf) > -1 Then
                Dim foundWindow As New FoundWindow
                foundWindow.hWnd = FindWindow(vbNullString, p.MainWindowTitle)
                foundWindow.strWindowName = p.MainWindowTitle
                Dim sbClassName As New System.Text.StringBuilder("", 256)
                GetClassName(foundWindow.hWnd, sbClassName, 256)
                foundWindow.strClassName = sbClassName.ToString
                foundWindows.Add(foundWindow)
            End If
        Next
        Return foundWindows
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each fWnd As FoundWindow In FindWindowsIndexOf("TeST", False)
            Debug.WriteLine(fWnd.strWindowName & " : " & fWnd.hWnd.ToString)
        Next
    End Sub

Same as the last function, you can choose whether or not the function is case sensitive.

Advertisements
05
May
09

[VB.Net] FindWindowsIndexOf – API Version

Somebody on VBForums was asking how to do something similar to this, so after answering his question, I created this fairly useful function – for windows that names change each time you load them up or something…

    ''API Declarations
    Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowProc, ByVal lParam As IntPtr) As Integer
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Integer) As Integer
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
    End Sub

    ''EnumWindow Callback Delegate Function
    Private Delegate Function EnumWindowProc(ByVal hwnd As Integer, ByVal lParam As IntPtr) As Boolean

    ''Found Window Structures
    Public Structure FoundWindows
        Dim boolCase As Boolean
        Dim strFindWindow As String
        Dim lstFoundWindows As List(Of FoundWindow)
    End Structure
    Public Structure FoundWindow
        Dim strWindowName As String
        Dim strClassName As String
        Dim hWnd As IntPtr
    End Structure

    ''' <summary>
    ''' ''EnumWindow Callback Function
    ''' </summary>
    ''' <param name="hwnd">Current windows handle</param>
    ''' <param name="lParam">Contains the FoundWindows structure</param>
    ''' <returns>The function passes the currently found windows in the lParam using a GCHandle to reform the data</returns>
    ''' <remarks>This function is called for each of the windows found, and is where the indexOf is called</remarks>
    Public Function EnumWindowsProc(ByVal hwnd As Integer, ByVal lParam As IntPtr) As Boolean
        Dim foundWindows As FoundWindows = CType(System.Runtime.InteropServices.GCHandle.FromIntPtr(lParam).Target, FoundWindows)
        Dim windowTitle As String = foundWindows.strFindWindow
        Dim wndTxtLen As Integer = GetWindowTextLength(hwnd)
        If Not wndTxtLen = 0 Then
            Dim sb As New System.Text.StringBuilder("", wndTxtLen + 1)
            GetWindowText(hwnd, sb, sb.Capacity)
            Dim windowCaption As String = sb.ToString
            If foundWindows.boolCase = False Then
                windowCaption = windowCaption.ToLower
                windowTitle = windowTitle.ToLower
            End If
            If windowCaption.IndexOf(windowTitle) > -1 Then
                Dim foundWindow As New FoundWindow
                foundWindow.hWnd = CType(hwnd, IntPtr)
                Dim sbClassName As New System.Text.StringBuilder("", 256)
                GetClassName(foundWindow.hWnd, sbClassName, 256)
                foundWindow.strClassName = sbClassName.ToString
                foundWindow.strWindowName = sb.ToString
                foundWindows.lstFoundWindows.Add(foundWindow)
            End If
        End If
        Return True
    End Function

    ''' <summary>
    ''' This function is used to loop through all open windows and check which ones contain a specific string
    ''' </summary>
    ''' <param name="strIndexOf">The string that you wish to check for in the window captions</param>
    ''' <param name="boolCase">Whether the function is should check for case</param>
    ''' <returns>A FoundWindows structure containing a list of FoundWindow</returns>
    ''' <remarks>The FoundWindows structure also contains the strIndexOf that was used to search the windows caption</remarks>
    Public Function FindWindowsIndexOf(ByVal strIndexOf As String, ByVal boolCase As Boolean) As FoundWindows
        Dim foundWindows As New FoundWindows
        foundWindows.boolCase = boolCase
        foundWindows.strFindWindow = strIndexOf
        foundWindows.lstFoundWindows = New List(Of FoundWindow)
        Dim ListHandle As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(foundWindows)
        Try
            EnumWindows(AddressOf EnumWindowsProc, System.Runtime.InteropServices.GCHandle.ToIntPtr(ListHandle))
        Finally
            If ListHandle.IsAllocated Then ListHandle.Free()
        End Try
        Return foundWindows
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each fWnd As FoundWindow In FindWindowsIndexOf("Test", True).lstFoundWindows
            Debug.WriteLine(fWnd.strWindowName & " : " & fWnd.hWnd.ToString)
        Next
    End Sub

The function can check for casing as well. For example if you are running two windows one named “test” and another named “Test” if you use the function like this:

FindWindowsIndexOf("Test", True)

It will only return one window, however if you set the boolCase to false:

FindWindowsIndexOf("Test", False)

It will return both windows

28
Apr
09

[Vb.Net] HTML Syntax Highlighter

Based very loosely on the original version I wrote in VBA for use in word.
Instead of looping through “words” this goes through each character and compares it with the colour of the last. Although this method may be slightly slower than splitting the string via spaces, the results are better as strings like Simon(“hithere”) would be incorrectly coloured.

    Private Sub SyntaxBtn_Press(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SyntaxBtn.Click
        CodeBox.SelectionStart = 0
        CodeBox.SelectionLength = 1
        Dim CurColour = CodeBox.SelectionColor
        Dim Output As String = "<div style='border: #660000 5px solid;color:#000000;'><pre style='background-color:#ffffff;padding:3px;line-height:15px;color:#000000;font-family: Courier New !important; font-size: 11px !important'>" & vbNewLine
        Output &= "<span style=""color:rgb(" & CurColour.R & ", " & CurColour.G & ", " & CurColour.B & ");"">"
        Output &= CodeBox.SelectedText
        Dim matches As System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(CodeBox.Text, "<")
        Progress.Maximum = CodeBox.TextLength + (matches.Count * 4)
        Progress.Value = 0
        For i As Integer = 1 To (CodeBox.TextLength + (matches.Count * 4))
            Progress.Value += 1
            CodeBox.SelectionStart = i
            CodeBox.SelectionLength = 1
            If CodeBox.SelectedText = "<" Then CodeBox.SelectedText = "\<"
            If CodeBox.SelectionColor <> CurColour Then CurColour = CodeBox.SelectionColor : Output &= "</span><span style=""color:rgb(" & CurColour.R & ", " & CurColour.G & ", " & CurColour.B & ");"">"
            Output &= CodeBox.SelectedText
        Next
        Output &= "</span> " & "</pre></div>"
        My.Computer.Clipboard.SetText(Output)
    End Sub

The example output for this is something like this:


Output &= \</span>\<span style="color:rgb(163, 21, 21);">"<span style=""color:rgb("\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.R & \</span>\<span style="color:rgb(163, 21, 21);">", "\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.G & \</span>\<span style="color:rgb(163, 21, 21);">", "\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.B & \</span>\<span style="color:rgb(163, 21, 21);">");"">"

\</span>\<span style="color:rgb(0, 0, 0);">        Output &= CodeBox.SelectedText

\</span>\<span style="color:rgb(0, 0, 255);">Dim\</span>\<span style="color:rgb(0, 0, 0);"> matches \</span>\<span style="color:rgb(0, 0, 255);">As\</span>\<span style="color:rgb(0, 0, 0);"> System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(CodeBox.Text, \</span>\<span style="color:rgb(163, 21, 21);">"<"\</span>\<span style="color:rgb(0, 0, 0);">)

Progress.Maximum = CodeBox.TextLength + (matches.Count * 4)

Progress.Value = 0

\</span>\<span style="color:rgb(0, 0, 255);">For\</span>\<span style="color:rgb(0, 0, 0);"> i \</span>\<span style="color:rgb(0, 0, 255);">As\</span>\<span style="color:rgb(0, 0, 0);"> \</span>\<span style="color:rgb(0, 0, 255);">Integer\</span>\<span style="color:rgb(0, 0, 0);"> = 1 \</span>\<span style="color:rgb(0, 0, 255);">To\</span>\<span style="color:rgb(0, 0, 0);"> (CodeBox.TextLength + (matches.Count * 4))

Progress.Value += 1

CodeBox.SelectionStart = i

CodeBox.SelectionLength = 1

\</span>\<span style="color:rgb(0, 0, 255);">If\</span>\<span style="color:rgb(0, 0, 0);"> CodeBox.SelectedText = \</span>\<span style="color:rgb(163, 21, 21);">"<"\</span>\<span style="color:rgb(0, 0, 0);"> \</span>\<span style="color:rgb(0, 0, 255);">Then\</span>\<span style="color:rgb(0, 0, 0);"> CodeBox.SelectedText = \</span>\<span style="color:rgb(163, 21, 21);">"\<"

\</span>\<span style="color:rgb(0, 0, 0);">            \</span>\<span style="color:rgb(0, 0, 255);">If\</span>\<span style="color:rgb(0, 0, 0);"> CodeBox.SelectionColor <> CurColour \</span>\<span style="color:rgb(0, 0, 255);">Then\</span>\<span style="color:rgb(0, 0, 0);"> CurColour = CodeBox.SelectionColor : Output &= \</span>\<span style="color:rgb(163, 21, 21);">"</span><span style=""color:rgb("\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.R & \</span>\<span style="color:rgb(163, 21, 21);">", "\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.G & \</span>\<span style="color:rgb(163, 21, 21);">", "\</span>\<span style="color:rgb(0, 0, 0);"> & CurColour.B & \</span>\<span style="color:rgb(163, 21, 21);">");"">"

\</span>\<span style="color:rgb(0, 0, 0);">            Output &= CodeBox.SelectedText

\</span>\<span style="color:rgb(0, 0, 255);">Next

\</span>\<span style="color:rgb(0, 0, 0);">        Output &= \</span>\<span style="color:rgb(163, 21, 21);">"</span> "\</span>\<span style="color:rgb(0, 0, 0);"> & \</span>\<span style="color:rgb(163, 21, 21);">"</pre></div>"

\</span>\<span style="color:rgb(0, 0, 0);">        \</span>\<span style="color:rgb(0, 0, 255);">My\</span>\<span style="color:rgb(0, 0, 0);">.Computer.Clipboard.SetText(Output)

\</span>\<span style="color:rgb(0, 0, 255);">End\</span>\<span style="color:rgb(0, 0, 0);"> \</span>\<span style="color:rgb(0, 0, 255);">Sub\</span> \</pre>\</div>
17
Apr
09

[VB.Net] Bin Packing

An algorithm for packing a bin with a set of items
Allows for packing in descending order, which in most cases are more efficient

    Public Class Packing_Bin
        Public Number As Integer
        Public Size As Integer
        Public BinSpace As Integer
        Public Items As List(Of Integer)
    End Class

    Private Sub BinPack(ByVal Items As List(Of Integer), ByVal BinSize As Integer, Optional ByVal DecendingBinPack As Boolean = True)
        'Items:
        ''List of items to pack into the bins
        'BinSize:
        ''Declare the maximum size of the bins
        ''This is not necessary, you can just state the BinSize when you create a new bin
        'DecendingBinPack:
        ''Sorts the items into decending size order 

        If DecendingBinPack = True Then
            Items.Sort()
            Items.Reverse()
        End If

        ''Determine minimum number of bins required
        ''Again, not necessary, just used to check efficency of algorithm
        Dim MinimumBins As Integer
        For Each item As Integer In Items
            MinimumBins += item
        Next
        MinimumBins = Math.Ceiling(MinimumBins / BinSize)

        ''Create initial bin to be packed
        Dim Bins As New List(Of Packing_Bin)
        Dim InitialBin As New Packing_Bin
        With InitialBin
            .Number = 1
            .Size = BinSize
            .BinSpace = BinSize
            .Items = New List(Of Integer)
        End With
        Bins.Add(InitialBin)

        ''#Note - If you want to start with x bins with different properties, then create them here too
        ''Just declare a new Packing_Bin and set the properties

        ''Loop through out list of items
        For Each item As Integer In Items
            Dim Allocated As Boolean = False
            ''Loop through current bins
            For i As Integer = 0 To Bins.Count - 1
                ''If there is space in the bin, add it
                If Bins(i).BinSpace >= item Then
                    Bins(i).Items.Add(item)
                    Bins(i).BinSpace -= item
                    Allocated = True
                    Exit For
                End If
            Next
            ''If the item was not added to a bin, create a new bin an add it
            If Allocated = False Then
                Dim NewBin As New Packing_Bin
                With NewBin
                    .Number = Bins.Count + 1
                    .Size = BinSize
                    .BinSpace = BinSize - item
                    .Items = New List(Of Integer)
                    .Items.Add(item)
                End With
                ''Add the bin to our bin collection
                Bins.Add(NewBin)
            End If
        Next

        Debug.WriteLine("Minimum Number of Bins Required: " & MinimumBins)
        For Each bin As Packing_Bin In Bins
            Debug.Write("Bin #" & bin.Number & ": ")
            For i As Integer = 0 To bin.Items.Count - 2
                Debug.Write(bin.Items(i) & ", ")
            Next
            Debug.Write(bin.Items(bin.Items.Count - 1) & " - Space Remaining: " & bin.BinSpace & " of " & bin.Size & vbNewLine)
        Next
    End Sub

Usage:

        Dim BinSize As Integer = 15
        Dim Items As New List(Of Integer)
        Items.AddRange(New Integer() {12, 14, 15, 9, 8, 14, 9, 5, 9, 1, 5, 2, 6, 4, 14, 15, 1, 2, 12, 9})
        BinPack(Items, 15, True)

Would Output:
Minimum Number of Bins Required: 12
Bin #1: 15 – Space Remaining: 0 of 15
Bin #2: 15 – Space Remaining: 0 of 15
Bin #3: 14, 1 – Space Remaining: 0 of 15
Bin #4: 14, 1 – Space Remaining: 0 of 15
Bin #5: 14 – Space Remaining: 1 of 15
Bin #6: 12, 2 – Space Remaining: 1 of 15
Bin #7: 12, 2 – Space Remaining: 1 of 15
Bin #8: 9, 6 – Space Remaining: 0 of 15
Bin #9: 9, 5 – Space Remaining: 1 of 15
Bin #10: 9, 5 – Space Remaining: 1 of 15
Bin #11: 9, 4 – Space Remaining: 2 of 15
Bin #12: 8 – Space Remaining: 7 of 15

10
Apr
09

[Vb.Net] QuickSort

This uses the QuickSort algorithm to order a list of numbers:

  Private Function QuickSort(ByVal ListOfNumbers As List(Of Integer)) As List(Of Integer)
        ''If the list is 1 or 0 then it is sorted
        If ListOfNumbers.Count < 1 Then Return ListOfNumbers
        ''List of numbers smaller than the pivot, and larger than it
        Dim SmallList, LargeList As New List(Of Integer)
        ''Pivot = n/2 rounded down
        Dim Pivot As Integer = ListOfNumbers(Math.Floor((ListOfNumbers.Count) / 2))
        Dim PivotCount As Integer = 0
        QuickSort = New List(Of Integer)
        ''Add to appropriate list
        For i As Integer = 0 To ListOfNumbers.Count - 1
            If ListOfNumbers(i) < Pivot Then
                SmallList.Add(ListOfNumbers(i))
            ElseIf ListOfNumbers(i) > Pivot Then
                LargeList.Add(ListOfNumbers(i))
            Else
                PivotCount = PivotCount + 1
            End If
        Next
        ''Quicksort smaller list
        QuickSort.AddRange(QuickSort(SmallList))
        ''Add pivot
        While PivotCount > 0
            QuickSort.Add(Pivot)
            PivotCount -= 1
        End While
        ''Sort large list 
        QuickSort.AddRange(QuickSort(LargeList))
    End Function

Usage:

        Dim ArrayOfNumbers As Integer() = {21, 18, 16, 20, 11, 17, 15, 7, 3, 18, 19, 14, 11, 28, 12, 15, 7, 30, 27}
        Dim ListOfNumbers As New List(Of Integer)
        ListOfNumbers.AddRange(ArrayOfNumbers)
        For Each Number As Integer In QuickSort(ListOfNumbers)
            Debug.Write(Number & " ")
        Next
        Debug.Write(vbNewLine)

Would Output:
3 7 7 11 11 12 14 15 15 16 17 18 18 19 20 21 27 28 30

10
Apr
09

[VB.Net] Bubble Sort 2

This function displays the steps that are actually used in the algorithm, displaying each iteration and the state of the list at the end of each. This only works with numbers, however could easily be used to sort strings (just cast it to string instead of integer)

    Public Sub BubbleSortOutput(ByVal Delimiter As Char, ByVal NewDelimiter As Char, ByRef inText As String, ByRef outTextBox As TextBox)
        ''Create initial list of numbers from inText
        Dim Numbers As New List(Of Integer)
        ''Format number delimiter number delimiter number etc
        ''E.g. 1,2,3,4,5 or 1.2.3.4.5 or 1-2-3-4-5-6 etc
        ''Split the string and output to text box
        For Each str As String In inText.Split(Delimiter)
            Numbers.Add(CInt(str))
            outTextBox.Text += str & NewDelimiter
        Next
        outTextBox.Text += vbNewLine & "".PadRight(120, "-") & vbNewLine

        ''Starting the iterations
        Dim swaps As Boolean = True
        While swaps = True
            swaps = False
            Dim CurrentPass As List(Of Integer) = Numbers
            For i As Integer = 0 To Numbers.Count - 2
                ''Formatting tabs
                Dim delim As String = "".PadLeft(i, NewDelimiter)
                ''Display numbers that are being compared
                outTextBox.Text += delim & "[" & CurrentPass(i) & NewDelimiter & CurrentPass(i + 1) & "]" & vbNewLine
                ''If left is bigger than right, swap
                If CurrentPass(i) > CurrentPass(i + 1) Then
                    Dim temp As Integer = CurrentPass(i + 1)
                    CurrentPass(i + 1) = CurrentPass(i)
                    CurrentPass(i) = temp
                    swaps = True
                End If
            Next
            'Display output for pass
            outTextBox.Text += "".PadRight(120, "-") & vbNewLine
            For j As Integer = 0 To CurrentPass.Count - 2
                outTextBox.Text += CurrentPass(j) & NewDelimiter
            Next
            outTextBox.Text += CurrentPass(CurrentPass.Count - 1) & vbNewLine
            outTextBox.Text += "".PadRight(120, "-") & vbNewLine
        End While
    End Sub

Usage:

   BubbleSortOutput(","c, vbTab, TextBox1.Text, TextBox2)

Where TextBox1.Text contains: 92,28,48,37,77,34,94,46
and TextBox2 is a blank textbox.

Would output:

92	28	48	37	77	34	94	46
-----------------------------------------------------------
[92	28]
	[92	48]
		[92	37]
			[92	77]
				[92	34]
					[92	94]
						[94	46]
-----------------------------------------------------------
28	48	37	77	34	92	46	94
-----------------------------------------------------------
[28	48]
	[48	37]
		[48	77]
			[77	34]
				[77	92]
					[92	46]
						[92	94]
-----------------------------------------------------------
28	37	48	34	77	46	92	94
-----------------------------------------------------------
[28	37]
	[37	48]
		[48	34]
			[48	77]
				[77	46]
					[77	92]
						[92	94]
-----------------------------------------------------------
28	37	34	48	46	77	92	94
-----------------------------------------------------------
[28	37]
	[37	34]
		[37	48]
			[48	46]
				[48	77]
					[77	92]
						[92	94]
-----------------------------------------------------------
28	34	37	46	48	77	92	94
-----------------------------------------------------------
[28	34]
	[34	37]
		[37	46]
			[46	48]
				[48	77]
					[77	92]
						[92	94]
-----------------------------------------------------------
28	34	37	46	48	77	92	94
-----------------------------------------------------------
10
Apr
09

[VB.Net] Bubble Sort Algorithm

Two functions below, for using the Bubble sort algorithm on either Strings or Integers.
The two functions are fundamentally the same, just with different casting – and so could be combined into one function.

    Public Function BubbleSortNumber(ByVal ListofNumber As List(Of Integer)) As List(Of Integer)
        Dim swaps As Boolean = True
        While swaps = True
            swaps = False
            For i As Integer = 0 To ListofNumber.Count - 2
                If ListofNumber(i) > ListofNumber(i + 1) Then
                    Dim temp As Integer = ListofNumber(i + 1)
                    ListofNumber(i + 1) = ListofNumber(i)
                    ListofNumber(i) = temp
                    swaps = True
                End If
            Next
        End While
        Return ListofNumber
    End Function

Usage:

        ''Create List of Random Integers
        Dim randomG As New Random
        Dim ListOfInteger As New List(Of Integer)
        For i As Integer = 0 To 26
            ListOfInteger.Add(randomG.Next(0, 10))
        Next
        ''Sort and format
        Dim outpt2 As String = ""
        For Each bub As String In BubbleSortNumber(ListOfInteger)
            outpt2 += bub & " "
        Next
        Debug.WriteLine(outpt2)

Would output:
0 0 0 0 1 2 3 3 3 3 3 4 5 5 5 6 6 6 6 7 7 8 8 8 8 8 9

And for Strings

    Public Function BubbleSortString(ByVal ListofString As List(Of String)) As List(Of String)
        Dim swaps As Boolean = True
        While swaps = True
            swaps = False
            For i As Integer = 0 To ListofString.Count - 2
                If ListofString(i) > ListofString(i + 1) Then
                    Dim temp As String = ListofString(i + 1)
                    ListofString(i + 1) = ListofString(i)
                    ListofString(i) = temp
                    swaps = True
                End If
            Next
        End While
        Return ListofString
End Function

Usage:

        ''Create list of strings (in this case, characters)
        Dim ListOfString As New List(Of String)
        ListOfString.AddRange("q w e r t y u i o p a s d f g h j k l z x c v b n m".Split(" "))
        ''Sort and format
        Dim outpt1 As String = ""
        For Each bub As String In BubbleSortString(ListOfString)
            outpt1 += bub & " "
        Next
        Debug.WriteLine(outpt1)

Would output:
a b c d e f g h i j k l m n o p q r s t u v w x y z