Public Class Form1
Private Sub GenerateAndSearch(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerate.Click, btnSearch.Click
Static intDataArray(-1) As Integer
Dim btnButtonClicked As Button = sender
Select Case btnButtonClicked.Tag
Case "Generate Array"
Call GenerateSortedArray(intDataArray)
Me.lstListArrayElements.Items.Clear()
Call DisplayData(intDataArray, Me.lstListArrayElements, "Sorted array:")
Case "Search Array"
Dim intNumToFind As Integer = Val(Me.txtNumToFind.Text)
Dim intNumFoundIndex As Integer
intNumFoundIndex = BinarySearch(intDataArray, intNumToFind)
If intNumFoundIndex = -1 Then
Me.lblFoundMessage.Text = "Number not found."
Else
Me.lblFoundMessage.Text = "Number found at index" & intNumFoundIndex
End If
End Select
End Sub
Sub GenerateSortedArray(ByRef intArray() As Integer)
Const intNUMELEMENTS As Integer = 50
Const intMAXNUMBER As Integer = 100
ReDim intArray(intNumElements - 1)
Randomize()
Dim intIndex As Integer
For intIndex = 0 To intArray.Length - 1
intArray(intIndex) = Int(intMAXNUMBER * Rnd()) + 1
Next intIndex
Call InsertionSort(intArray)
End Sub
Sub InsertionSort(ByRef intArray() As Integer)
Dim intIndex, intPreviousIndex, intTempItem As Integer
For intIndex = 1 To intArray.Length - 1
intTempItem = intArray(intIndex)
intPreviousIndex = intIndex - 1
Do While intPreviousIndex > 0 And
intArray(intPreviousIndex) > intTempItem
intArray(intPreviousIndex + 1) = intArray(intPreviousIndex)
intPreviousIndex = intPreviousIndex - 1
Loop
If intArray(intPreviousIndex) > intTempItem Then
intArray(intPreviousIndex + 1) = intArray(intPreviousIndex)
intArray(intPreviousIndex) = intTempItem
Else
intArray(intPreviousIndex + 1) = intTempItem
End If
Next intIndex
End Sub
Sub DisplayData(ByRef intArray() As Integer, ByRef lstList As ListBox, ByVal strTitle As String)
lstList.Items.Add(strTitle)
Dim intIndex As Integer
For intIndex = 0 To intArray.Length - 1
lstList.Items.Add(intIndex & vbTab & intArray(intIndex))
Next intIndex
End Sub
Function BinarySearch(ByRef intArray() As Integer, ByVal intNumToFind As Integer) As Integer
Dim intHighIndex As Integer = intArray.Length - 1
Dim intMidIndex As Integer
Dim intLowIndex As Integer = 0
Dim blnFound As Boolean = False
Do While (Not blnFound) And (intLowIndex <= intHighIndex)
intMidIndex = (intMidIndex + intLowIndex) / 2
If intArray(intMidIndex) = intNumToFind Then
blnFound = True
ElseIf intArray(intMidIndex) > intNumToFind Then
intHighIndex = intMidIndex - 1
Else
intLowIndex = intMidIndex + 1
End If
Loop
If blnFound Then
Return intMidIndex
Else
Return -1
End If
End Function
Private Sub NewData_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtNumtoFind.TextChanged, btnGenerate.Click
Me.lblFoundMessage.text = Nothing
End Sub
End Class
My problem is I cannot get my code to display a list of arrays to find. I cant see where im going wrong any ideas? Also my sort button is not working but that may be due to the fact nothing shows up when i click button btnGenerate.
Your biggest problem appears to be in your BinarySearch function. The reason you weren't getting any display is the BinarySearch function had an infinite loop. Here's some corrected code with explanations and is tested and working:
Function BinarySearch(ByRef intArray() As Integer, ByVal intNumToFind As Integer) As Integer
Dim intHighIndex As Integer = intArray.Length - 1
Dim intMidIndex As Integer
Dim intLowIndex As Integer = 0
Dim blnFound As Boolean = False
Do While (Not blnFound) And (intLowIndex <= intHighIndex)
'This should add high and low then divide by 2 not mid and low
'Also you should use the integer division sign to return an integer result
intMidIndex = (intHighIndex + intLowIndex) \ 2
If intArray(intMidIndex) = intNumToFind Then
blnFound = True
'mid should become the new limit without any inc/decrement
ElseIf intArray(intMidIndex) > intNumToFind Then
intHighIndex = intMidIndex
Else
intLowIndex = intMidIndex
End If
Loop
If blnFound Then
Return intMidIndex
Else
Return -1
End If
End Function
A couple of other corrections that should be made:
Select Case btnButtonClicked.Tag should be Select Case btnButtonClicked.Tag.ToString()
intArray(intIndex) = Int(intMAXNUMBER * Rnd()) + 1 should be intArray(intIndex) = CInt(intMAXNUMBER * Rnd()) + 1
One other thought, you might want to put a check in the generate routine to only generate unique numbers. Binary search will only find one element but not any of the others if there are more.
The NewData_TextChanged method erases your search results:
Me.lblFoundMessage.text = Nothing
Remove that line of code and the results should be displayed.
Related
Today i continue my work, Building a menu with a vb.net console application. I found more samples to build with Windows forms. Still i try to get Basic Knowledge with the console surface.I was not able to put the following marquee text in a scroll menu, the second Code past the marquee text.
Module Module1
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub Main()
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
aTimer.Start()
Console.ReadKey()
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
Console.Clear()
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorLeft = 10 'no visible change
Console.CursorTop = 10 'visible change
Console.Write("{0}{1}", vbCr, sb.ToString)
End Sub
End Module
The marquee text Output from above is not easy to manage with the console.cursorleft command. I have no clue how to move it to the right or to put the marquee Output in the following Code, a scroll menu, on the third line.
Module Module1
Dim MenuList As New List(Of String)
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
End Module
The menu Frame for the above Code can be used with the up and down arrows on the Keyboard.
Maybe it is to much work but i have no clue how to continue.
The first Solution for the marquee Output is an easy change of the original code. The wrap, vbCr, was the main Problem to move the text output toward the right edge oft he screen. The following code can be used to change the cursorTop Positon and also the cursorLeft Position of the Text.
Console.CursorVisible = False
Console.CursorLeft = 30
Console.CursorTop = 10
Console.Write("{0}", sb.ToString)
The heavy part are the Menu code Lines. To answer my own question some additional help was necessary.
I posted my question on the MS developer Network written in german language. With the following link it can be viewed.
For the case the link should be broken or other cases i post the code on this site.
Module Module1
Dim MenuList As New List(Of String)
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
If CurrentItem = 2 Then ' Zero can be used to show the marquee output prompt
aTimer.Start() ' With a change to two or four the timer can be stoped:
'Else
'If aTimer.Enabled Then
' aTimer.Stop()
'End If
End If
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorVisible = False
Console.CursorLeft = 20
Console.CursorTop = 12 ' For the first Element CursorTop=10, fort he third 12
Console.Write("{0}", sb.ToString)
End Sub
End Module
To learn an other language like English i have to search a lot. Visual Basic Code is mostly written with English key words for the commands. I think it is easier to look up the maintainable changes for your self. To search is not every day funny.
I'm developing a program that asks the user to input 5 numbers. The lowest of the 5 numbers will be dropped, and then the other 4 numbers are to be averaged.
I'm quite new to VB, but I believe I'm currently on the right path here...
I've sorted the array to help identify the lowest number, but I do not know how to exclude the lowest number and to then average the other remaining 4.
Here is my code so far:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IntArr(4) As Integer
Dim i As Integer
For i = 1 To 5
IntArr(4) = InputBox("Enter Number" & i)
Next
Array.Sort(IntArr)
'textbox1.text = ???
End Sub
End Class
Can anyone please assist or at least point me in the right direction?
In keeping with the spirit of your code, something like the following would work.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IntArr(4) As Integer
Dim OutArr(3) As Integer
For i = 0 To 4
IntArr(i) = InputBox("Enter Number " & i)
Next
Array.Sort(IntArr)
Array.Copy(IntArr, 1, OutArr, 0, 4) 'exclude the lowest number
TextBox1.Text = OutArr.Average()
End Sub
End Class
Using built in LINQ functions
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfItems = 5
Dim numberOfItemsToRemove = 1
Dim inArray(numberOfItems - 1) As Integer
Dim outArray(numberOfItems - 1 - numberOfItemsToRemove) As Integer
Dim i As Integer
For i = 0 To numberOfItems - 1
While Not Integer.TryParse(InputBox("Enter Number " & i + 1), inArray(i))
MessageBox.Show("Invalid input!")
End While
Next
outArray = inArray.OrderBy(Function(j) j).Skip(numberOfItemsToRemove).ToArray()
MessageBox.Show(
String.Format(
"Input: [{0}], Output: [{1}], average: {2:0.0}",
String.Join(", ", inArray),
String.Join(", ", outArray),
outArray.Average))
End Sub
Your code as it is above will continue to simply change the value of index 4 with each box if I'm not mistaken. I would do something like this (I will use your variable names for your convenience).
Button1_Click(procedure junk that is auto-inserted)
Dim intArr(4) As Integer
Dim OutArr(3) As Integer
Dim intCounter, intAverage, intLowest, intLowIndex As Integer
'populate all indexes of intArr()
For intCounter = 0 to 4
intArr(intCounter) = InputBox("Please enter a number.")
Next intCounter
intCounter = 1 'reset counter for check
intLowest = intArr(intLowIndex) 'start with index 0
'find lowest number and its index
For intCounter = 1 to 4
If intLowest > intArr(intCounter) Then 'defaults to previous
intLowest = intArr(intCounter)
intLowIndex = intCounter
End If
Next intCounter
intCounter = 0 'reset counter again for possible For...Next loops
Select Case intLowIndex
Case = 0
For intCounter = 0 to 3
OutArr(intCounter) = intArr(intCounter + 1)
Next intCounter
Case = 1
OutArr(0) = intArr(0)
OutArr(1) = intArr(2)
OutArr(2) = intArr(3)
OutArr(3) = intArr(4)
Case = 2
OutArr(0) = intArr(0)
OutArr(1) = intArr(1)
OutArr(2) = intArr(3)
OutArr(3) = intArr(4)
Case = 3
OutArr(0) = intArr(0)
OutArr(1) = intArr(1)
OutArr(2) = intArr(2)
OutArr(3) = intArr(4)
Case = 4
For intCounter = 0 to 3
OutArr(intCounter) = intArr(intCounter)
Next intCounter
End Select
intAverage = (OutArr(0) + OutArr(1) + OutArr(2) + OutArr(3)) / 4
'insert your preferred method to display OutArr() and intAverage
using winforms / vb.net
I am trying to count how many characters exist in "textbox3" after a specific character "." in a textbox.
examples:
2adf = 0 (no "." exists)
2adf. = 0
2adf.2 = 1
2adf.2a = 2
2adf.2af = 3
2adf.2afe = 4
I already have a function to search if there is a "."
if (CountCharacter(TextBox3.Text, ".") = 1) then
'a "." exists so count number of characters after "."
end if
Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
Dim cnt As Integer = 0
For Each c As Char In value
If c = ch Then cnt += 1
Next
Return cnt
End Function
I am not sure how to check the count after the "." though
You could use the string.IndexOf method for this task
Sub Main
Dim test = "2adf.2afe"
Dim result = CountCharsAfter(test, "."c)
Console.WriteLine(result)
End Sub
Public Function CountCharsAfter(input as string, charToSearch as Char) as Integer
DIm pos = input.LastIndexOf(charToSearch)
if pos = -1 then
return 0
else
return input.Length - (pos + 1)
End if
End Function
Try this
Dim NoChar As Integer = CalculateChra("12adf.2afe", ".")
Private Function CalculateChra(ByVal V_String As String, ByVal LastChar As Char) As Integer
Dim Start As String = Split(V_String, LastChar)(0) & "."
Dim M As String = V_String.Substring(Start.Length)
Return M.Length
End Function
dim n,cnt as integer
n=0
cnt=0
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
If e.KeyChar = Chr(46) Then
n = Len(TextBox1.Text)
End If
If n <> 0 Then
cnt += 1
End If
MsgBox(" no.of charectors after '.' is/are : " & cnt - 1)
End Sub
I am computing the ROI with a moving rectangle and extracting the ROI to compute the standard deviation, mean, area and Pixel value coordinates X and Y in a seperate form2 by clicking the mouse. At this juncture I am trying to pass a function from the main Form that loads the Image and displays the rectangle to another Form that has the displayed properties of the mean and standard deviation etc. However, I'm receiving errors in runtime in the function that contains the standard deviation. The error displayed is
Index was outside the bounds of the array.
It is displayed at the end of this portion of the code in the function StD, i.e at the end of the mean part'
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
what is this actually saying and how can I fix this situation. Any tips and ideas, thanks.
My code is at the bottom
enterPublic Function StD(ByVal image As Bitmap, ByVal mean As Double, ByVal meancount As Integer) As Double
Dim SD(SquareHeight * SquareWidth) As Double
Dim count As Integer = 0
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Dim pixelcolor As Color = image.GetPixel(i, j)
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
count += 1
Next
Next
Dim SDsum As Double = 0
For i = 0 To count
SDsum = SDsum + SD(i)
Next
SDsum = SDsum / (SquareHeight * SquareWidth)
SDsum = ((SDsum) ^ (1 / 2))
Return SDsum
End Function code here
I would like to pass this using the code below
enterPrivate Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim mean As Double = 0
Dim meancount As Integer = 0
Dim bmap As New Bitmap(400, 400)
bmap = PictureBox1.Image
Dim colorpixel As Color = bmap.GetPixel(e.X, e.Y)
' Dim pixels As Double = colorpixel.R + colorpixel.G + colorpixel.B
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Rect.Contains(e.Location) Then
If (PictureBox1.Image Is Nothing) Or (PictureBox1.Height - (e.Y + SquareHeight) < 0) Or (PictureBox1.Width - (e.X + SquareWidth) < 0) Then
Else
Dim ROI As New Bitmap(400, 400)
Dim x As Integer = 0
Dim countx As Integer = 0
Dim county As Integer = 0
For i = e.X To (e.X + SquareWidth)
For j = (e.Y + x) To (e.Y + SquareHeight)
Dim pixelcolor As Color = bmap.GetPixel(i, j)
ROI.SetPixel(countx, county, pixelcolor)
mean = mean + pixelcolor.R + pixelcolor.G + pixelcolor.B
county += 1
meancount += 1
Next
county = 0
countx += 1
x = x + 1
Next
mean = mean / (meancount * 3)
Dim SD = mean - 75
Dim area As Integer = (SquareHeight * SquareWidth)
Dim anotherForm As Form2
anotherForm = New Form2(mean, StD(bmap, mean, meancount), area, 34)
anotherForm.Show()
End If
End If
' Catch ex As Exception
' MessageBox.Show(ex.Message())
' End Try
End Sub code here
To be displayed with this code
enter Public Sub New(ByVal mean As Double, ByVal StD As Double, ByVal Area As Integer, ByVal pixel As Double)
MyBase.New()
InitializeComponent()
TextBox1.Text = mean.ToString()
TextBox2.Text = StD.ToString()
TextBox3.Text = Area.ToString()
TextBox4.Text = pixel.ToString()
End Sub code here
The problem probably is because of these lines:
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Try using this instead:
For i = 0 To SquareWidth - 1
For j = 0 To SquareHeight - 1
Thanks for reading - I am using the class below to calculate the CRC32 checksum of a specified file.
My question is how would I go about reporting the progress of file completion (in %) to a progressbar on a different form. I have tried (i / count) * 100 under the New() sub but I am not having any luck, or setting the progress bar with it for that matter. Can anyone help?
Thanks in advance
Steve
Public Class CRC32
Private crc32Table() As Integer
Private Const BUFFER_SIZE As Integer = 1024
Public Function GetCrc32(ByRef stream As System.IO.Stream) As Integer
Dim crc32Result As Integer
crc32Result = &HFFFFFFFF
Dim buffer(BUFFER_SIZE) As Byte
Dim readSize As Integer = BUFFER_SIZE
Dim count As Integer = stream.Read(buffer, 0, readSize)
Dim i As Integer
Dim iLookup As Integer
Do While (count > 0)
For i = 0 To count - 1
iLookup = (crc32Result And &HFF) Xor buffer(i)
crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
crc32Result = crc32Result Xor crc32Table(iLookup)
Next i
count = stream.Read(buffer, 0, readSize)
Loop
GetCrc32 = Not (crc32Result)
End Function
Public Sub New()
Dim dwPolynomial As Integer = &HEDB88320
Dim i As Integer, j As Integer
ReDim crc32Table(256)
Dim dwCrc As Integer
For i = 0 To 255
Form1.CRCWorker.ReportProgress((i / 255) * 100) 'Report Progress
dwCrc = i
For j = 8 To 1 Step -1
If (dwCrc And 1) Then
dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
dwCrc = dwCrc Xor dwPolynomial
Else
dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
End If
Next j
crc32Table(i) = dwCrc
Next i
'file complete
End Sub
End Class
'------------- END CRC32 CLASS--------------
'-------------- START FORM1 --------------------------
Private Sub CRCWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles CRCWorker.DoWork
For i = CurrentInt To dgv.Rows.Count - 1
CRCWorker.ReportProgress(0, i & "/" & Total_Files)
Current_File_Num = (i + 1)
SetControlText(lblCurrentFile, Str(Current_File_Num) & "/" & Total_Files)
result = CheckFile(SFV_Parent_Directory & "\" & dgv.Rows(i).Cells(0).Value, dgv.Rows(i).Cells(1).Value)
Select Case result
Case 0 ' missing file
UpdateRow(i, 2, "MISSING")
'dgv.Rows(i).Cells(2).Value = "MISSING"
Missing_Files = Missing_Files + 1
SetControlText(lblMissingFiles, Str(Missing_Files))
Case 1 ' crc match
UpdateRow(i, 2, "OK")
' dgv.Rows(i).Cells(2).Value = "OK"
Good_Files = Good_Files + 1
SetControlText(lblGoodFiles, Str(Good_Files))
Case 2 'crc bad
UpdateRow(i, 2, "BAD")
' dgv.Rows(i).Cells(2).Value = "BAD"
Bad_Files = Bad_Files + 1
SetControlText(lblBadFiles, Str(Bad_Files))
End Select
If CRCWorker.CancellationPending = True Then
e.Cancel = True
Exit Sub
End If
Next
End Sub
Private Sub CRCWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles CRCWorker.ProgressChanged
Dim val As Integer = e.ProgressPercentage
ProgressBar2.Maximum = 100
ProgressBar2.Value = e.ProgressPercentage
Debug.Print(val)
End Sub
Function CheckFile(ByVal tocheck_filepath As String, ByVal expected_crc As String) As Integer 'returns result of a file check 0 = missing 1 = good 2 = bad
If File.Exists(tocheck_filepath) = False Then
Return 0 'return file missing
End If
Dim f As FileStream = New FileStream(tocheck_filepath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
Dim c As New CRC32()
crc = c.GetCrc32(f)
Dim crcResult As String = "00000000"
crcResult = String.Format("{0:X8}", crc)
f.Close()
End Function
It appears your .ReportProgress() call is in the New() subroutine, which is the part that makes the lookup table for the CRC calculation. The New() subroutine is called once, before the main CRC routine. The main CRC routine is the one that takes up all the time and needs the progress bar.
Shouldn't the progress bar updating be in the GetCrc32() function? Something like this:
Public Function GetCrc32(ByRef stream As System.IO.Stream, _
Optional prbr As ProgressBar = Nothing) As UInteger
Dim crc As UInteger = Not CUInt(0)
Dim buffer(BUFFER_SIZE) As Byte
Dim readSize As Integer = BUFFER_SIZE
Dim left As Long = stream.Length
If Not (prbr Is Nothing) Then ' ProgressBar setup for counting down amount left.
prbr.Maximum = 100
prbr.Minimum = 0
prbr.Value = 100
End If
Dim count As Integer : Do
count = stream.Read(buffer, 0, readSize)
For i As Integer = 0 To count - 1
crc = (crc >> 8) Xor tbl((crc And 255) Xor buffer(i))
Next
If Not (prbr Is Nothing) Then ' ProgressBar updated here
left -= count
prbr.Value = CInt(left * 100 \ stream.Length)
prbr.Refresh()
End If
Loop While count > 0
Return Not crc
End Function
In Windows Forms BackgroundWorker Class is often used to run intensive tasks in another thread and update progress bar without blocking the interface.
Example of using BackgroundWorker in VB.Net
The problem is when you use use the form in your code without instantiating it Form1.CRCWorker.ReportProgress((i / 255) * 100) there is a kind of hidden "auto-instantiation" happening and new instance of Form1 is created each time.