none
arrray problem in vb2015 RRS feed

  • Question

  • Hello !

    I am very beginner, and need some help.

    I "translate" one VB6 program to VB.NET ,and somewhere i have one fail.

    Theerror message :" the value cannot be null".

    Please who can help me, save me.

    Sorry for my bad English, i write from Europe.

    Option Explicit On
    Public Class Form1
        Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
        Structure t3Dcoord
            Dim X As Double
            Dim Y As Double
            Dim Z As Double
        End Structure

        Dim fps As Integer
        Dim fpsValue As Integer
        Dim M() As t3Dcoord 'our main array.  We'll adjust the size later
        Dim Temp() As t3Dcoord 'a temporary array we use when drawing
        Dim Cam As t3Dcoord 'our camera
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

            If e.KeyCode = Keys.Escape Then ' Case vbKeyEsc
                End
            End If
            If e.KeyCode = Keys.Up Then 'Case vbKeyUp
                Cam.Y = Cam.Y - 10 'move up
            End If
            If e.KeyCode = Keys.Down Then 'Case vbKeyDown
                Cam.Y = Cam.Y + 10 'move down
            End If
            If e.KeyCode = Keys.Left Then  'Case vbKeyLeft
                Cam.X = Cam.X - 10 'move left
            End If
            If e.KeyCode = Keys.Right Then  'Case vbKeyRight
                Cam.X = Cam.X + 10 'move right
            End If
            If e.KeyCode = Keys.PageUp Then  'Case vbKeyPageUp
                Cam.Z = Cam.Z + 10 'move in
            End If
            If e.KeyCode = Keys.PageDown Then  'Case vbKeyPageDown
                Cam.Z = Cam.Z - 10 'move out
            End If
            ' End Select
        End Sub

        Private Sub Form_Load()
            Randomize()

            Me.Top = 40
            Me.Left = 40
            BackColor = Color.White

            Cam.X = 0
            Cam.Y = 0
            Cam.Z = 0

            Call Createdots()
        End Sub

        Private Sub Createdots()
            Dim i As Integer
            For i = 0 To 5000
                ReDim Preserve M(i)
                M(i).X = (Rnd() * 1000) - 500
                M(i).Z = (Rnd() * 1000) - 500
            Next
            ReDim Temp(UBound(M))
        End Sub

        Private Sub Mainloop()

            Dim img As Image = PictureBox1.BackgroundImage
            Dim bmp As Bitmap = CType(img, Bitmap)
            Dim x As Integer
            Dim y As Integer
            Dim i As Integer
            Do
                For i = 0 To UBound(M)          ' <---  i have the fail here (M)? value always 0

                    Temp(i).X = M(i).X - Cam.X
                    Temp(i).Y = M(i).Y - Cam.Y
                    Temp(i).Z = M(i).Z - Cam.Z

                    On Error Resume Next 'cuts out overflow errors

                    If Temp(i).Z > 0 Then
                        'This is the code that prepares the dots for putting on the screen
                        'All you do is divide the x by z and the y by z
                        'See no complex maths involved at all
                        Temp(i).X = Temp(i).X / Temp(i).Z
                        Temp(i).Y = Temp(i).Y / Temp(i).Z
                        bmp.SetPixel(Temp(i).X, Temp(i).Y, Color.Red)
                        PictureBox1.Invalidate()
                    End If

                Next
            Loop
        End Sub
        'all this does is start the main loop once the program has loaded
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            fpsValue = fps 'put the number of frames from this second into a safe place
            fps = 0 'reset the fps
        End Sub
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            Call Mainloop() 'cal the main loop
            Me.Enabled = False 'stop the timer now thats its done its job
        End Sub
    End Class

    Friday, April 5, 2019 11:25 PM

Answers

  •   One thing I see is that your Form_Load sub has not been converted properly for VB.Net.  It should look like this.

        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Randomize()
    
            Me.Top = 40
            Me.Left = 40
            BackColor = Color.White
    
            Cam.X = 0
            Cam.Y = 0
            Cam.Z = 0
    
            Createdots()
        End Sub
     

     I also noticed that in the Timer2 Tick event sub,  you have a comment that says that the one line stops the timer now that it has done its job.  However,  you are disabling the Form instead of stoping Timer2.  Correction is shown here...

        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            Mainloop() 'cal the main loop
            'Me.Enabled = False 'This will disable the Form
            Timer2.Enabled = False 'This will disable Timer2
        End Sub
     

     You may also want to use Option Strict also.  It will point out that you are trying to use the Double type values in the BitMap.SetPixel method which requires you to pass Integer type values to it.  That can be corrected using the CInt() function to convert the Doubles to Integers like shown here in the line I am referring to.

    bmp.SetPixel(CInt(Temp(i).X), CInt(Temp(i).Y), Color.Red)
     

     However,  I also see that you are creating an infinite Do loop in the Mainloop sub which will basically lock up the thread that your Form uses so that it will not have any time to process any other window messages,  like key presses and Painting messages.  So,  I'm not sure how well the code will work for you in the end.

     You may be further ahead finding a VB.Net example to do whatever this code is suppose to do,  or carefully explain to us what it is you want to do.  Someone might post an example for you that would work better.

     I am getting out of here for the night but,  will try to check in tomorrow and see how you made out.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Saturday, April 6, 2019 12:17 AM
    • Marked as answer by Identity80 Sunday, April 7, 2019 1:12 PM
    Saturday, April 6, 2019 12:16 AM
  • I got it to draw the first frame but there are still big problems. There seems to be no scale to the drawing so it does not draw on the bmp properly. See where I used abs and * 100 for x and y ?

    The code is basically converted just not working logic. The timers don't make sense. We don't know what the settings are for the controls etc.

    The errors the others pointed out are mostly corrected.

    If you tell us what it is supposed to do maybe we can help more. Just rotate the random points? Do you understand the math ie can you draw this by hand? If so show us what the math is that the code is supposed to be doing.

    Edit v2:

    '3d version 2
    Public Class Form6
        Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
        Structure t3Dcoord
            Dim X As Double
            Dim Y As Double
            Dim Z As Double
        End Structure
    
        Dim fps As Integer
        Dim fpsValue As Integer
        Dim M() As t3Dcoord 'our main array.  We'll adjust the size later
        Dim Temp() As t3Dcoord 'a temporary array we use when drawing
        Dim Cam As t3Dcoord 'our camera
    
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            Dim dr As Integer = 100
    
            If e.KeyCode = Keys.Escape Then ' Case vbKeyEsc
                End
            End If
            If e.KeyCode = Keys.Up Then 'Case vbKeyUp
                Cam.Y = Cam.Y - dr 'move up
            End If
            If e.KeyCode = Keys.Down Then 'Case vbKeyDown
                Cam.Y = Cam.Y + dr 'move down
            End If
            If e.KeyCode = Keys.Left Then  'Case vbKeyLeft
                Cam.X = Cam.X - dr 'move left
            End If
            If e.KeyCode = Keys.Right Then  'Case vbKeyRight
                Cam.X = Cam.X + dr 'move right
            End If
            If e.KeyCode = Keys.PageUp Then  'Case vbKeyPageUp
                Cam.Z = Cam.Z + dr 'move in
            End If
            If e.KeyCode = Keys.PageDown Then  'Case vbKeyPageDown
                Cam.Z = Cam.Z - dr 'move out
            End If
    
            Mainloop()
        End Sub
    
        Private Sub Form_Load() Handles MyBase.Load
            Randomize()
    
            Dim i As Integer
            For i = 0 To 5000
                ReDim Preserve M(i)
                M(i).X = (Rnd() * 1000) - 500
                M(i).Y = (Rnd() * 1000) - 500
                M(i).Z = (Rnd() * 1000) - 500
    
            Next
            ReDim Temp(UBound(M))
    
            Mainloop()
        End Sub
    
        Private Sub Mainloop()
            Dim bmp As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
            Dim x As Integer
            Dim y As Integer
            Dim i As Integer
    
            ''Do
            For i = 0 To UBound(M)          ' <---  i have the fail here (M)? value always 0
    
                Temp(i).X = M(i).X - Cam.X
                Temp(i).Y = M(i).Y - Cam.Y
                Temp(i).Z = M(i).Z - Cam.Z
    
                If Temp(i).Z > 0 Then
                    x = CInt(100 * Temp(i).X / Temp(i).Z)
                    y = CInt(100 * Temp(i).Y / Temp(i).Z)
                    If x >= 0 AndAlso x < bmp.Width - 1 AndAlso y >= 0 AndAlso y < bmp.Height - 1 Then
                        bmp.SetPixel(x, y, Color.Red)
                        bmp.SetPixel(x + 1, y, Color.Red)
                        bmp.SetPixel(x + 1, y + 1, Color.Red)
                    End If
                End If
            Next
    
            PictureBox1.BackgroundImage = CType(bmp, Image)
    
            'Loop
        End Sub
        'all this does is start the main loop once the program has loaded
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            fpsValue = fps 'put the number of frames from this second into a safe place
            fps = 0 'reset the fps
        End Sub
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            Call Mainloop() 'cal the main loop
            Me.Enabled = False 'stop the timer now thats its done its job
        End Sub
    
    End Class


    Hi Razerz!




    • Marked as answer by Identity80 Sunday, April 7, 2019 1:12 PM
    • Edited by tommytwotrain Sunday, April 7, 2019 1:15 PM
    Saturday, April 6, 2019 3:41 PM

All replies

  •   One thing I see is that your Form_Load sub has not been converted properly for VB.Net.  It should look like this.

        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Randomize()
    
            Me.Top = 40
            Me.Left = 40
            BackColor = Color.White
    
            Cam.X = 0
            Cam.Y = 0
            Cam.Z = 0
    
            Createdots()
        End Sub
     

     I also noticed that in the Timer2 Tick event sub,  you have a comment that says that the one line stops the timer now that it has done its job.  However,  you are disabling the Form instead of stoping Timer2.  Correction is shown here...

        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            Mainloop() 'cal the main loop
            'Me.Enabled = False 'This will disable the Form
            Timer2.Enabled = False 'This will disable Timer2
        End Sub
     

     You may also want to use Option Strict also.  It will point out that you are trying to use the Double type values in the BitMap.SetPixel method which requires you to pass Integer type values to it.  That can be corrected using the CInt() function to convert the Doubles to Integers like shown here in the line I am referring to.

    bmp.SetPixel(CInt(Temp(i).X), CInt(Temp(i).Y), Color.Red)
     

     However,  I also see that you are creating an infinite Do loop in the Mainloop sub which will basically lock up the thread that your Form uses so that it will not have any time to process any other window messages,  like key presses and Painting messages.  So,  I'm not sure how well the code will work for you in the end.

     You may be further ahead finding a VB.Net example to do whatever this code is suppose to do,  or carefully explain to us what it is you want to do.  Someone might post an example for you that would work better.

     I am getting out of here for the night but,  will try to check in tomorrow and see how you made out.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Saturday, April 6, 2019 12:17 AM
    • Marked as answer by Identity80 Sunday, April 7, 2019 1:12 PM
    Saturday, April 6, 2019 12:16 AM
  • Hi

    Your Sub Form.Load is never being called and so, your Call Createdots() is never called, so, your array M() is never being filled, and so, when the line For i = 0 To UBound(M) is called, the M() is Nothing and so, the Exception.

    You really do need to learn how to use the main debug tools such as BreakPoints, hover over variables to inspect value during tun time - and a few others too.

    Is this code something you found on the internet and just copied//pasted?


    Regards Les, Livingston, Scotland




    • Edited by leshay Saturday, April 6, 2019 12:28 AM
    Saturday, April 6, 2019 12:25 AM
  • Hello !

    I try every thing , what you write for me .

    Now (M) has value, but I can't see the points, and the form does not respond .

    This code is one 3d draw tutorial.

    l try to translate to vb.net from vb6, later  i need to change .

    ( call the points from txt file, and not randomize them. This part is ready)

    Thank you for your help.I wait for your answer, maybe you find something more.

    Regards Zoli


    • Edited by Identity80 Saturday, April 6, 2019 12:02 PM
    Saturday, April 6, 2019 11:35 AM
  • Hi !

    This code is one 3d draw tutorial.

    l try to translate to vb.net from vb6, not only copy-paste  ,later  i need to change .

    ( call the points from txt file, and not randomize them. This part is ready)

    All what i know (learn ), i learned it from books, not in the school .

    ( I can use the breakpoint , but the arrays is always problem )

    Thank you for your help.

    Regards Zoli

    Saturday, April 6, 2019 11:52 AM
  • Hi

    I would suggest that you do not try to convert code from VB6. VB.NET has many many differences and improvement from VB6, and would enable you to create your project in a more manageable way. With attempting to convert from VB6, not only do you need to learn VB.NET as you go along, but you are faced with the difficulties in the conversion itself - so a double load on your brain :)

    If you are trying to learn coding in VB.NET from a book which uses VB6, then you are bound to meet many many problems, and I would suggest a more recent VB.NET book to be much more useful for you. Or, if you are serious, you can learn everything from this Forum just by asking questions as you learn.


    Regards Les, Livingston, Scotland

    Saturday, April 6, 2019 1:50 PM
  • I got it to draw the first frame but there are still big problems. There seems to be no scale to the drawing so it does not draw on the bmp properly. See where I used abs and * 100 for x and y ?

    The code is basically converted just not working logic. The timers don't make sense. We don't know what the settings are for the controls etc.

    The errors the others pointed out are mostly corrected.

    If you tell us what it is supposed to do maybe we can help more. Just rotate the random points? Do you understand the math ie can you draw this by hand? If so show us what the math is that the code is supposed to be doing.

    Edit v2:

    '3d version 2
    Public Class Form6
        Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
        Structure t3Dcoord
            Dim X As Double
            Dim Y As Double
            Dim Z As Double
        End Structure
    
        Dim fps As Integer
        Dim fpsValue As Integer
        Dim M() As t3Dcoord 'our main array.  We'll adjust the size later
        Dim Temp() As t3Dcoord 'a temporary array we use when drawing
        Dim Cam As t3Dcoord 'our camera
    
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            Dim dr As Integer = 100
    
            If e.KeyCode = Keys.Escape Then ' Case vbKeyEsc
                End
            End If
            If e.KeyCode = Keys.Up Then 'Case vbKeyUp
                Cam.Y = Cam.Y - dr 'move up
            End If
            If e.KeyCode = Keys.Down Then 'Case vbKeyDown
                Cam.Y = Cam.Y + dr 'move down
            End If
            If e.KeyCode = Keys.Left Then  'Case vbKeyLeft
                Cam.X = Cam.X - dr 'move left
            End If
            If e.KeyCode = Keys.Right Then  'Case vbKeyRight
                Cam.X = Cam.X + dr 'move right
            End If
            If e.KeyCode = Keys.PageUp Then  'Case vbKeyPageUp
                Cam.Z = Cam.Z + dr 'move in
            End If
            If e.KeyCode = Keys.PageDown Then  'Case vbKeyPageDown
                Cam.Z = Cam.Z - dr 'move out
            End If
    
            Mainloop()
        End Sub
    
        Private Sub Form_Load() Handles MyBase.Load
            Randomize()
    
            Dim i As Integer
            For i = 0 To 5000
                ReDim Preserve M(i)
                M(i).X = (Rnd() * 1000) - 500
                M(i).Y = (Rnd() * 1000) - 500
                M(i).Z = (Rnd() * 1000) - 500
    
            Next
            ReDim Temp(UBound(M))
    
            Mainloop()
        End Sub
    
        Private Sub Mainloop()
            Dim bmp As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
            Dim x As Integer
            Dim y As Integer
            Dim i As Integer
    
            ''Do
            For i = 0 To UBound(M)          ' <---  i have the fail here (M)? value always 0
    
                Temp(i).X = M(i).X - Cam.X
                Temp(i).Y = M(i).Y - Cam.Y
                Temp(i).Z = M(i).Z - Cam.Z
    
                If Temp(i).Z > 0 Then
                    x = CInt(100 * Temp(i).X / Temp(i).Z)
                    y = CInt(100 * Temp(i).Y / Temp(i).Z)
                    If x >= 0 AndAlso x < bmp.Width - 1 AndAlso y >= 0 AndAlso y < bmp.Height - 1 Then
                        bmp.SetPixel(x, y, Color.Red)
                        bmp.SetPixel(x + 1, y, Color.Red)
                        bmp.SetPixel(x + 1, y + 1, Color.Red)
                    End If
                End If
            Next
    
            PictureBox1.BackgroundImage = CType(bmp, Image)
    
            'Loop
        End Sub
        'all this does is start the main loop once the program has loaded
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            fpsValue = fps 'put the number of frames from this second into a safe place
            fps = 0 'reset the fps
        End Sub
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            Call Mainloop() 'cal the main loop
            Me.Enabled = False 'stop the timer now thats its done its job
        End Sub
    
    End Class


    Hi Razerz!




    • Marked as answer by Identity80 Sunday, April 7, 2019 1:12 PM
    • Edited by tommytwotrain Sunday, April 7, 2019 1:15 PM
    Saturday, April 6, 2019 3:41 PM
  • Hello,

    To add to the current replies, best to rewrite in VB.NET, toss all the VB6 code, set Option Strict On and Option Infer Off.

    Tips

    1. Use assertion e.g. test for empty or null array. If empty or null then go to tip 2.

    Dim someArray As t3Dcoord() = {}
    If someArray Is Nothing OrElse someArray.Length = 0 Then
        MessageBox.Show("Nothing")
    Else
        MessageBox.Show("Has values")
    End If
    2. Learn how to use the Visual Studio debugger (the common response is "I don't know how" but that can be overcome from taking time to learn and forget trying to fix the issue as setting breakpoints can solve many issues).


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Saturday, April 6, 2019 4:10 PM
    Moderator
  • Hello !

    I try every thing , what you write for me .

    Now (M) has value, but I can't see the points, and the form does not respond .

     That would be because of the infinite Do loop I talked about in my last post.  It is locking up the Form's thread making the Form not able to process any windows messages.  That includes key press messages,  mouse click messages,  and the paint messages which it needs to process in order for you to see what has been drawn.

     Notice how TommyTwoTrains put the Exit Do in the loop in his code.  That makes it exit the loop and allow the Form to receive a Paint message.  Seems like the original code should have had some exit point from the loop,  or the loop was suppose to be run in a separate thread would be my best guess.  8)

     

     OT -  Hi Tom.  8)


    If you say it can`t be done then i`ll try it

    Saturday, April 6, 2019 7:00 PM
  • Hello, 

    I hope the others excuse me that I interrupt. 

    But just a simple addition. Because of the endless discussion the then MVP (not me) had with Microsoft decided was that at initialisation an array would not be its length, but its length +1. 

    Therefore the old code like Mid would go, and the new code like IndexOf would go. 

    The result was in my opinion only that there became lots of misunderstandings for the newer users which did not know all that vintage stuff. 

    An array instanced as Dim X(10) as string contains 11 items. 


    Success
    Cor

    Saturday, April 6, 2019 7:28 PM
  • Hi tommytwotrain

    "If you tell us what it is supposed to do maybe we can help more. Just rotate the random points? Do you understand the math ie can you draw this by hand? If so show us what the math is that the code is supposed to be doing."

    First goal,just rotate the random points .

    This code is one 3d draw tutorial. l try to translate to vb.net from vb6 (because i not find better ).

    Later i need to change .( call the points from txt file, and not randomize them.

    This part is ready /i can call the points coordinates from txt file, and put it to textbox/ )

    Thank you for your help.

    Regards Zoli


    • Edited by Identity80 Sunday, April 7, 2019 6:35 AM
    Sunday, April 7, 2019 6:33 AM
  • Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

            If e.KeyCode = Keys.Escape Then ' Case vbKeyEsc
                End
            End If
            If e.KeyCode = Keys.Up Then 'Case vbKeyUp
                Cam.Y = Cam.Y - 10 'move up
            End If
            If e.KeyCode = Keys.Down Then 'Case vbKeyDown
                Cam.Y = Cam.Y + 10 'move down
            End If
            If e.KeyCode = Keys.Left Then  'Case vbKeyLeft
                Cam.X = Cam.X - 10 'move left
            End If
            If e.KeyCode = Keys.Right Then  'Case vbKeyRight
                Cam.X = Cam.X + 10 'move right
            End If
            If e.KeyCode = Keys.PageUp Then  'Case vbKeyPageUp
                Cam.Z = Cam.Z + 10 'move in
            End If
            If e.KeyCode = Keys.PageDown Then  'Case vbKeyPageDown
                Cam.Z = Cam.Z - 10 'move out
            End If

            Mainloop() <-------

    End Sub

      <---- if put this  Mainloop() here,all points move,but all "old point" still in the picturebox, and

    the picturebox  it will be completely red :( .

    I think this is another story......and who helped the most....


      


    • Edited by Identity80 Sunday, April 7, 2019 1:11 PM
    Sunday, April 7, 2019 1:09 PM
  • Id,

    We need to make a new bmp each time to clear it. There are better ways to draw things see below.

    I made the keypress events work and have updated my last post example v2 above. There is still more clean up to do and the timers are not implemented but you just put the mainloop call in the timer event just like the keypress.

    If you want to continue with this you should show your original vb code and an image if you want to duplicate it exactly.

    However there are probably better examples to use now. Here are a couple new ways from this forum:

    The first one is similar to what you have here.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/ef572fc3-d6bd-4cf0-baae-b968a14236ea/display-amp-rotate-a-3d-cube-using-visual-basic?forum=vbgeneral


    This one uses DirectX version 9c in vb.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/6597efc7-2406-406a-ae69-0f0097e6af5d/how-to-add-directx-9-9c-3d-drawing-to-visual-studio-2010-windows-7-and-above?forum=vbgeneral

    PS you should also add disposing the bitmaps that are created if you continue that method.

    Sunday, April 7, 2019 1:20 PM
  • Thank you all Tommy ,you are great man !

    Regards Zoli

    Monday, April 8, 2019 12:53 PM