1

I have converted a VB6 program to VB.Net. The program runs and seems to operate about 80% ok. I am having difficulties understanding how some of the for references work.

In VB6 I have code like

 frmComms.MSComm1.PortOpen = True
' if port already used by other app then warn user and go back to initial screen
 If (Err.Number = PORT_ALREADY_USED) And (GlManualCom = MANUAL) Then
    frmDetection.Hide
    MsgBox rs.LoadResString(ErrMesxxx), vbCritical + vbOKOnly, rs.LoadResString(ErrMesxyz)
    Call frmSelection.RefreshSettings
    Unload Me
    frmSelection.Show
    Exit Sub
 ElseIf Err.Number = INVALID_PORT_NUMBER Then ' Invalid port number
    frmDetection.Hide
    MsgBox rs.LoadResString(ErrMes19Sub), vbExclamation + vbOKOnly, rs.LoadResString(ErrMes19Title)
    Call frmSelection.RefreshSettings
    Unload Me
    frmSelection.Show
    Exit Sub
  ElseIf Err.Number = DEVICE_NOT_OPEN Then ' This device is not open
    frmDetection.Hide
    MsgBox rs.LoadResString(ErrMeszzz) , vbCritical
    Call frmSelection.RefreshSettings
    Unload Me
    frmSelection.Show
    Exit Sub
 End If

These frmSelection references refer to the actual object in VB6, but in Vb.Net do they refer to the object or to some static reference. In other places in the code, it will set a public variable in the VB6 form as "frmSelection.CancelFlag = True", but trying to trace the code, I can not determine that this 'frmSelection.CancelFlag' is actually affecting my code. I get the feeling that I should be using an object reference to the 'frmSelection'. Like 'objSelection = new frmSelection', then I can set the variable using the object; objSelection.CancelFlag = True.

I used a program to convert the VB6 code to VB.Net, so maybe it is ok to refer to these items 'statically'. By 'static' I mean it in the C++ sense; that you can refer to variables of a class without ever creating the class.

In VB6, I was under the impression that the first reference to a form would create and load the form, maybe that was not true. But in VB.Net if I place a break point in the form Load event, it will not stop there even though there are many places in the code that are continuously using functions of the form.

I have tried to convert some of the frmXYZ references to objXYZ to see if that changes the outcome, but that did not appear to. I created a completely global variable instead of using the public variable in the form and that did work.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Ryan Buton
  • 341
  • 3
  • 11
  • I'm not sure exactly what you're asking. Yes, the best practice is to create an instance of the form (e.g., `Dim frm As New frmSelection`) and that's actually true for both VB6 and VB.NET. With that being said, using `frmSelection` directly would work fine because of backward compatibility **if you're only using one instance of the form**. See [this post](https://stackoverflow.com/q/4698538/8967612) for more about the VB's form default instance (read both answers there). – 41686d6564 stands w. Palestine Nov 16 '20 at 16:17
  • _"But in VB.Net if I place a break point in the form Load event, it will not stop there"_ That's probably because the form is only _loaded_ once (on the first call to `.Show()`). Using `.Hide()` does not "unload" the form and AFAIK, you can't use the `Load` and `Unload` keywords like in the VB6 code, so the only way to "unload" the form would be by manually closing it or by calling the `.Close()` method. If you do that, then the `Load` event will likely be triggered. Anyway, as I said above, creating instances is the best practice. Get used to this pattern and save yourself a lot of guessing. – 41686d6564 stands w. Palestine Nov 16 '20 at 16:30
  • Another possibility for why the breakpoint under `Load` is not hit might be that you copied the event handler and pasted it in the VB.NET code? Don't do that. Double click on the form and let it create the event handler for you and then start writing code inside it. The event handler signature in VB.NET must end with `Handles TheEvent` (unless created with the `AddHandler` statement but that's another story for another day). – 41686d6564 stands w. Palestine Nov 16 '20 at 16:34
  • 1
    When you use the Form name without "new", that is referred to as the `default instance` of the Form. Default instances work in both VB6 and VB.Net. If you're having problems where it "doesn't seem to work" then somewhere you have managed to create an instance of the Form with new and the Form you are seeing on the screen is not the same as the default instance. Either switch everything to use the default instance, or create one instance with the "new" keyword and make sure that Form reference is available everywhere you need to access it. – Idle_Mind Nov 16 '20 at 17:38
  • @41686d6564 - The form that did not hit the 'Load' is normally NOT 'Shown'. It has a MSCom (Serial) control that is used to by whole program. Only if the user wants to see some diagnostic info will it appear. At that time the 'Load' is called. I thought the Load would be call at the first time the form is referenced. Sorry that was unclear in the question. – Ryan Buton Nov 16 '20 at 18:58

2 Answers2

1

how the forms work in vb.net and VB6 are very similar. Often in .net, you will see code that creates a instance of the form, and then shows it. But, you can still use the VB6 type of approach, and use the "base" instance class.

So, you can go like this:

Form2.Show()

So, that will create a isntance of that form, and load it.

Now in any other code in any other form, you can go:

Form2.TextBox1.Text = "Hello"

So, in this regards, you are just fine.

Where your problem going to be is in regards to the MS-Comm object/control you using on that form for the serial communication parts.

Often (even in VB6), in code you could and would create a instance of that ms-comm object. But in a lot of cases, to save having to create that instance, then you dropped a ms-comm control on that form. That's where the heavy lifting and work needs to occur for your code.

So, from a general code approach point of view? You really don't' have to much if at all change your coding style and approach from what you were using in VB6.

Where the "big" change will occur is that you don't have a ActiveX ms-comm control, and thus that's where you need to address and change and work on, and give some care and love.

So, to show a form, you can create a instance, and display it. Or you can in fact just launch the form and a instance is created for you.

So, it really depends on how you open the form. I would not bother to change code, and just shows form.show() to launch forms.

You need to re-build and create code for the serial port communication. That's where your BIG change will occur. The ms-comm control in VB6 was (easy) since it could wire up code events on that form. That's where you big code change will occur. So for 99% of your general forms and code? You don't have to change much code. Where the challenge will occur is that you don't have a ActiveX serial com control. You need to re-build how that works since you don't have that ms-com ActiveX control on that form.

So, get up to speed with how to use serial communication in .net - without that simple ms-com control, then that code will need a re-write. Lots of articles can be found - say like this one:

https://www.xanthium.in/serial-port-programming-visual-basic-dotnet-for-embedded-developers

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • OK thanks, some how though, the VB6 MSCom Control came over fine and the program is talking serially like it used to. If you mean, I should not use the Control because it is ActiveX and not native .Net, I agree and have been thinking about doing that. – Ryan Buton Nov 16 '20 at 18:35
  • Well, if testing shows that ActiveX control working, then I guess you can stick with it. I did not think the ms-comm control would work. But if it does, then I would think you just have to re-create the event stubs attached to that control. If a double click in the property sheet (events) for that control wires up a vb.net event code stub, then you should be ok. The events for such a control will have to be wired up again - usually by double clicking on the event(s) in the property sheet. If that works (when you double click) in the property sheet, then you have solved 99% of your problems. – Albert D. Kallal Nov 16 '20 at 18:39
0

Part of the infrastructure that VB.Net sets up is the My.Forms object which is brought into scope so that it can be used directly, i.e. you refer to it via the syntax FrmName and not have to use the full name My.Forms.FrmName. Thus sometimes FrmName is the type, and sometimes it is the property My.Forms.FrmName, depending upon context.

I recommend that you use first replace the abbreviated reference with the full reference, with the intention of eventual not using object via My at all. As for the Load event, it is an event, and only gets called under specific circumstances. If you want to set a break point on something that is always called, set it in the constructor.

jmoreno
  • 12,752
  • 4
  • 60
  • 91
  • I started to try this, adding the My.Forms. ; but I get a warning "warning BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated." Is that expected? I had "My.Forms.frmComms.cancelLoop = true" without the My.Forms the code worked and no warnings were present. – Ryan Buton Dec 02 '20 at 14:52