Celoufran
Celoufran

Reputation: 93

vb.NET starting a form with a vb class instead of a form but the form closes as soon as it starts

I want to use an object to start my form in VB but when I use an object, the form open but then closes right after. I'm using a vb class as an object to start the application in my projects properties. The problem I encounter is that as soon as it shows the form, it all closes. Nothing stays open. How can I fix this? Here's my code for the object and the forms:

AppStarter.vb:

Public Class AppStarter
    Shared Sub Main()
        If System.IO.File.Exists("C:\Mingw\bin\g++.exe") Then
            Form1.Show()
        Else
            ErrorPage.Show()
            MsgBox("Test")
        End If
    End Sub
End Class

Form1:

Public Class Form1
    Dim fd As OpenFileDialog = New OpenFileDialog()
    Dim fld As FolderBrowserDialog = New FolderBrowserDialog()
    Dim strFileName As String
    Dim strCompiledFileName As String
    Dim strFileDestination As String
    Dim strFilePath As String
    Dim test As Boolean

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub cmdCompile_Click(sender As Object, e As EventArgs) Handles cmdCompile.Click
        If txtCompiledFileName.Text <> "" And strFilePath <> "" And strFileDestination <> "" Then
            strCompiledFileName = txtCompiledFileName.Text
            Try
                Process.Start("cmd", "/c cd " + strFileDestination + " & g++ " + strFilePath + " -o " + strCompiledFileName)
                MsgBox("Compiled Successfully!")
                ClearVar()
            Catch ex As Exception
                MsgBox(ex)
                ClearVar()
            End Try
        Else
            MsgBox("Missing compiled file name or file path.", MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub cmdChooseFile_Click(sender As Object, e As EventArgs) Handles cmdChooseFile.Click
        fd.Title = "Open File Dialog"
        fd.InitialDirectory = "C:\"
        fd.Filter = "C/C++ Files |*.c; *.cpp"
        fd.FilterIndex = 1
        fd.RestoreDirectory = True
        fd.DereferenceLinks = True

        If fd.ShowDialog() = DialogResult.OK Then
            strFileName = System.IO.Path.GetFileName(fd.FileName)
            strFilePath = fd.FileName
        End If

        lblChosenFile.Text = strFileName
    End Sub

    Private Sub cmdFileDestination_Click(sender As Object, e As EventArgs) Handles cmdFileDestination.Click
        fld.Description = "Select a folder to extract to:"
        fld.ShowNewFolderButton = True
        fld.SelectedPath = strFileDestination
        fld.RootFolder = System.Environment.SpecialFolder.MyComputer

        If fld.ShowDialog() = DialogResult.OK Then
            strFileDestination = fld.SelectedPath
            lblChosenFolder.Text = strFileDestination
        End If
    End Sub

    Public Sub ClearVar()
        txtCompiledFileName.Text = ""
        lblChosenFile.Text = "No chosen file"
        lblChosenFolder.Text = ""
    End Sub
End Class

ErrorPage:

Public Class ErrorPage
    Dim webAddress As String = "https://osdn.net/projects/mingw/releases/"

    Private Sub ErrorPage_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub cmdYes_Click(sender As Object, e As EventArgs) Handles cmdYes.Click
        Process.Start(webAddress)
    End Sub

    Private Sub cmdNo_Click(sender As Object, e As EventArgs) Handles cmdNo.Click
        Form1.Close()
        Close()
    End Sub


    Private Const CP_NOCLOSE_BUTTON As Integer = &H200
    Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim myCp As CreateParams = MyBase.CreateParams
            myCp.ClassStyle = myCp.ClassStyle Or CP_NOCLOSE_BUTTON
            Return myCp
        End Get
    End Property
End Class

Upvotes: 0

Views: 1935

Answers (1)

jmcilhinney
jmcilhinney

Reputation: 54417

If you want to write your own Main method and display your own startup form then you need to call Application.Run and pass the form as an argument. The Show method you're calling returns immediately and so your Main method completes and the application exits.

Here's how a C# WinForms apps starts:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

You should do basically the same thing:

Module Program

    <STAThread>
    Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(Form1)
    End Sub

End Module

If you need to put that Application.Run call inside an If block then so be it.

That said, there's probably no point doing that. The functionality you need is already built into the VB Application Framework. Just create a VB WinForms app project as normal and leave the startup form selected as normal. You can then open the application events code file from the project properties and handle the Startup event. In that event handler, if you set e.Cancel to True then the application will exit without ever creating a startup form. That means that you can do this:

Imports System.IO
Imports Microsoft.VisualBasic.ApplicationServices

Namespace My
    ' The following events are available for MyApplication:
    ' Startup: Raised when the application starts, before the startup form is created.
    ' Shutdown: Raised after all application forms are closed.  This event is not raised if the application terminates abnormally.
    ' UnhandledException: Raised if the application encounters an unhandled exception.
    ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
    ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
    Partial Friend Class MyApplication

        Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
            If Not File.Exists("C:\Mingw\bin\g++.exe") Then
                'Display error page and be sure to call ShowDialog rather than Show.

                'Exit without creating the startup form.
                e.Cancel = True
            End If
        End Sub

    End Class
End Namespace

If the file does exist then the application will start normally with your startup form displayed.

Upvotes: 1

Related Questions