Previous | Index | Next 

[PRB] The VB.NET application hangs on the splash screen or terminates earlier than expected

Migrated VB.NET applications consider the first form being loaded as the application’s main form. Such a form is internally loaded by means of an Application.Run method, which returns when the form is closed. If the first loaded form is the splash screen, the application hangs on it because typically splash forms don’t have the “X” (close) button.

Another common issue you might face is with VB6 projects that use form chaining techniques, in which the code unloads a form and immediately loads another form, as in this code:

         Private Sub cmdClose_Click()
            ' close the current form and load another form
            Unload Me
            Form2.Show
        End Sub

(In a sense, splash screens are just a specific case of form chaining.) The problem with the above code is that, if the current form is the startup form, then the VB.NET application terminates when the form is closed and never has an opportunity to load another form.

VB Migration Partner offers three solutions to this problem. The first solution is “cleaner” and produces better VB.NET applications, but is limited to simple splash screen; the second solution is based on a hack, but is the only one that works in all circumstances. The third solution is the less robust of the group and might not work with complex forms.

The first solution is based on the EnableAppFramework pragma; as its name suggests, this pragma enables the VB.NET application framework feature, which you usually enable manually from the Application tab of the My Project designer in Visual Studio. The first two parameters of this pragma allows you to select the main form and the splash screen form, as in this example:

        '##  EnablesAppFramework frmMain, frmSplash

The third parameter can enable XP visual styles, whereas the fourth parameter should be 1 (one) if you want the application to exit only after all forms close (by default, the VB.NET application exits as soon as the main form closes):

        '## EnablesAppFramework frmMain, frmSplash,  True, 1

The second solution consists of using a hidden form as the startup form in the VB.NET application and showing all the other forms from inside its Activate event. VB Migration Partner implements this technique behind the scenes, but it requires that you manually insert a statement inside the Sub Main method, typically by means of an InsertStatement pragma:

         Sub Main()
            '## InsertStatement If InitializeFormChaining6() Then Exit Sub
            ' display the startup form
            Form1.Show
            ' …
        End Sub

Notice that it is essential that the application has a Sub Main method, therefore you need to change the VB6 project if its startup object is a form instead.

The previous VB6 code is migrated to VB.NET as follows:

         Sub Main()
            If InitializeFormChaining6() Then Exit Sub
            ' display the startup form
            Form1.Show
            ' …
        End Sub

The InitializeFormChaining6 method returns True the first time it is called, and False on all subsequent calls. This is what happens when the application runs:

  1. the call to InitializeFormChaining6 loads a hidden form.
  2. the code inside the hidden form’s Activate event handler invokes the Main method.
  3. when InitializeFormChaining6 is called a second time, it returns False; therefore execution continues and all subsequent statements in the method are executed regularly.
  4. when the nested call to Main ends, execution flow goes back to the Activate event handler; when the handler exit, execution goes back to the InitializeFormChaining6 method mentioned at step 1.
  5. the InitializeFormChaining6 method returns True to the Main method, which is immediately exited without executing any of the statements that follow (otherwise these statements would mistakenly executed twice).

Understanding this sequence is important, in case you want to set a breakpoint inside the Main method. To avoid confusion, you should avoid setting a breakpoint on the call to InitializeFormChaining6 method.

Even if VB Migration Partner is able to convert applications that use form chaining, we recommend that you revise the architecture of your project, so that there’s no need to resort to the InitializeFormChaining6 method.

Finally, the third solution relies on the new IsSplashScreen property that we added to VB6Form in version 1.32 of VB Migration Partner. If you set this property to True before showing the form, the library will make the form visible by means of a simple Show or ShowDialog, instead of the Application.Run method:

        Sub Main()
            Form1.IsSplashScreen = True
            Form1.Show
            ' …
        End Sub

Please notice that .NET coding guidelines strongly recommend that the first form in the application be displayed by means of the Application.Run. Forms that are made visible by means of the Show or ShowDialog methods might crash or make your application unstable. Therefore we recommend that you use this last technique only if any other approach fails and that you thoroughly test your application before releasing it.

 

Previous | Index | Next