# vb.net code transferred to a separate class..



## psyko12 (Aug 23, 2010)

```
Sub Go()
        Dim p As New Process
        p.StartInfo.FileName = "ping.exe"
        p.StartInfo.Arguments = "www.bbc.co.uk -t"
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardOutput = True
        p.StartInfo.CreateNoWindow = True
        AddHandler p.OutputDataReceived, AddressOf bleh
        p.Start()
        p.BeginOutputReadLine()
    End Sub

    Sub bleh(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        UpdateTextBox(e.Data)
    End Sub
    Private Delegate Sub UpdateTextBoxDelegate(ByVal Text As String)
    Private Sub UpdateTextBox(ByVal Tex As String)
        If Me.InvokeRequired Then
            Dim del As New UpdateTextBoxDelegate(AddressOf UpdateTextBox)
            Dim args As Object() = {Tex}
            Me.Invoke(del, args)
        Else
            Form1.tb.Text &= Tex & Environment.NewLine
        End If
    End Sub
```

This code works well when it's in the forms main code, but when I transfer it to a separate class file it doesn't work. Specifically this set of code The update/output.

```
Private Sub UpdateTextBox(ByVal Tex As String)
        If Me.InvokeRequired Then
            Dim del As New UpdateTextBoxDelegate(AddressOf UpdateTextBox)
            Dim args As Object() = {Tex}
            Me.Invoke(del, args)
        Else
            Form1.tb.Text &= Tex & Environment.NewLine
        End If
    End Sub
```

Now when I change it to Me into form1 it compiles ok but the displayed text from ping does not show. And if I used "Me" I get this errors:



> Error	1	'InvokeRequired' is not a member of 'txtbox_click_pinger.Class1'.
> Error	2	'Invoke' is not a member of 'txtbox_click_pinger.Class1'.


----------



## FordGT90Concept (Aug 23, 2010)

```
Public Delegate Sub UpdateTextBoxDelegate(ByVal Text As String)
Public Class Form1
    Private _Process As Process
    Public Sub New()
        InitializeComponent()

        _Process = New Process
        _Process.StartInfo.FileName = "ping.exe"
        _Process.StartInfo.Arguments = "www.bbc.co.uk -t"
        _Process.StartInfo.UseShellExecute = False
        _Process.StartInfo.RedirectStandardOutput = True
        _Process.StartInfo.CreateNoWindow = True
        AddHandler _Process.OutputDataReceived, AddressOf UpdateTextBox
        _Process.Start()
        _Process.BeginOutputReadLine()
    End Sub
    Private Sub UpdateTextBox(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Try
            If Me.InvokeRequired() Then
                ' Prevent cross-thread reference error.
                Me.Invoke(New DataReceivedEventHandler(AddressOf UpdateTextBox), New Object() {sender, e})
            Else
                tb.Text &= e.Data & Environment.NewLine
            End If
        Catch ex As Exception
            ' This will catch any errors generated during termination.
        End Try
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        ' Make sure to stop ping.exe or else it will run indefinitely.
        If (Not _Process Is Nothing) Then _Process.Kill()
    End Sub
End Class
```
You are basically overcomplicated things by making your own delegate instead of using the delegate that already exists for the event.


----------



## psyko12 (Aug 24, 2010)

That seems to have done the trick... I've made it as form2.. So form1 only acts as a multifunction launcher of sorts. Btw is it possible to make a protection code so that it would Only allow 1 instance of form2 running? 

Thanks man! You've really guided me alot in the process of vb learning.


----------



## FordGT90Concept (Aug 24, 2010)

If you had only one place holder for Form2 and always used that placeholder, only once instance of Form2 could exist.

Dim child As Form2

You could also just use .Show and .Hide on that form so you only create a new instance of it once.


----------



## psyko12 (Aug 24, 2010)

FordGT90Concept said:


> If you had only one place holder for Form2 and always used that placeholder, only once instance of Form2 could exist.
> 
> Dim child As Form2
> 
> You could also just use .Show and .Hide on that form so you only create a new instance of it once.



Ok here's what is happening now, just want to make sure I understand what you've said..

When I click ping button on form1... It shows form2 and initiates it. I've put a button on form2 with "Hide" (form2.hide). So it's still running in the background right? Now form1 has the "ping" and "show form2" buttons... 

"Show Form2" button is = form2.show()

uhm I've confused my self lol... That too is the command for "Ping" button.
Is there another way to code this so THE ping command wouldn't actually start off the bat when form2 is shown?

Sorry a bit confused.


----------



## FordGT90Concept (Aug 24, 2010)

Yes, the only way the Form gets killed for good is if you call .Close() or reallocate the memory (e.g. child = Nothing).

Just remember that if you are going to run an infinite loop on ping.exe you should start/stop ping.exe when the VisbleChanged event is raised.


----------



## psyko12 (Aug 24, 2010)

Have made it work to make use a single instance by doing this:

```
Public Sub New()
        [B][COLOR="Red"]MyBase.New()[/COLOR][/B]
        InitializeComponent()
        _p = New Process
        _p.StartInfo.FileName = "ping.exe"
        _p.StartInfo.Arguments = "www.bbc.co.uk -t"
        _p.StartInfo.UseShellExecute = False
        _p.StartInfo.RedirectStandardOutput = True
        _p.StartInfo.CreateNoWindow = True
        AddHandler _p.OutputDataReceived, AddressOf bleh
        _p.Start()
        _p.BeginOutputReadLine()
    End Sub
        InitializeComponent()
        _p = New Process
        _p.StartInfo.FileName = "ping.exe"
        _p.StartInfo.Arguments = "www.bbc.co.uk -t"
        _p.StartInfo.UseShellExecute = False
        _p.StartInfo.RedirectStandardOutput = True
        _p.StartInfo.CreateNoWindow = True
        AddHandler _p.OutputDataReceived, AddressOf bleh
        _p.Start()
        _p.BeginOutputReadLine()
    End Sub
```

And then added this to form 2 along with the code above:

```
Private Shared _Instance As Form2 = Nothing
    Public Shared Function Instance() As Form2
        If _Instance Is Nothing OrElse _Instance.IsDisposed = True Then
            _Instance = New Form2
        End If
        _Instance.BringToFront()
        Return _Instance
    End Function
```

Code for button initiate ping on form1 is:

```
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MyForm2 = Form2.Instance
        MyForm2.Show()
    End Sub
```
^still gonna edit this further to be a 1 click start/stop button with error catching (try/catch) 

Seems working perfectly now.. Also have made a show/hide check box with a try/catch combination so when there is no presence of the form2 it would not crash.. 

Thank you!


----------



## FordGT90Concept (Aug 24, 2010)

MyBase.New() is a repetition of Public Sub New().  You'd only have to use MyBase.New if you were using a constructor other than New().


MyBase.New(), in a Form, is the same as calling New Form().


----------



## psyko12 (Aug 24, 2010)

FordGT90Concept said:


> MyBase.New() is a repetition of Public Sub New().  You'd only have to use MyBase.New if you were using a constructor other than New().
> 
> 
> MyBase.New(), in a Form, is the same as calling New Form().



Corrected and noted, works whichever is used. Thanks!


----------



## FordGT90Concept (Aug 25, 2010)

Ehm, my point is it doesn't need it--it is implied.  It is only required if you are doing inheritance with a non-default base constructor.  For example, if you have two classes:


```
Public Class Vehicle
  Public Name As String

  Public Sub New()
  End Sub
  Public Sub New(ByVal vehiclename As String)
  End Sub
End Class

Public Class Car Extends Vehicle
  Public Sub New()
  End Sub
End Class
```
As is, New Car would use New Vehicle(); however, if we changed Car to...

```
Public Class Car Extends Vehicle
  Public Sub New()
    MyBase.New("Mustang")
  End Sub
End Class
```
It would call New Vehicle("Mustang").  That's not the best example but the point is that MyBase is really only useful if you are dealing with inheritance.


----------

