The Application object represents the running application at a very high level. It provides properties and methods to starting an event loop to process Windows messages, possibly for a form. It also provides methods for controlling and stopping the event loop.
Don’t confuse the Application object with the My.Application namespace. The two have somewhat similar purposes but very different features.
The following sections describe the Application object’s most useful properties, methods, and events.
The following table describes the Application object’s most useful properties.
Property | Purpose |
---|---|
CommonAppDataPath | Returns the path where the program should store application data shared by all users. By default, this path has the form base_path\ company_name\product_name\product_version. The base_ path is typically C:\Documents and Settings\All Users\ Application Data. |
CommonAppDataRegistry | Returns the Registry key where the program should store application data shared by all users. By default, this path has the form HKEY_ LOCAL_MACHINE\Software\company_name\product_name\ product_version. |
CompanyName | Returns the application’s company name. |
CurrentCulture | Gets or sets the CultureInfo object for this thread. |
CurrentInputLanguage | Gets or sets the InputLanguage for this thread. |
ExecutablePath | Returns the fully qualified path to the file that started the execution, including the file name. |
LocalUserAppDataPath | Returns the path where the program should store data for this local, nonroaming user. By default, this path has the form base_path\ company_name\product_name\product_version. The base_path is typically C:\Documents and Settings\user_name\Local Settings\Application Data. |
MessageLoop | Returns True if the thread has a message loop. If the program begins with a startup form, this loop is created automatically. If it starts with a custom Sub Main, the loop doesn’t initially exist and the program must start it by calling Application.Run. |
OpenForms | Returns a collection holding references to all of the application’s open forms. |
ProductName | Returns the application’s product name. |
ProductVersion | Gets the product version associated with this application. |
StartupPath | Returns the fully qualified path to the directory where the program starts. |
UserAppDataPath | Returns the path where the program should store data for this user. By default, this path has the form base_path\company_name\ product_name\product_version. The base_path is typically C:\Documents and Settings\user_name\Application Data. |
UserAppDataRegistry | Returns the Registry key where the program should store application data for this user. By default, this path has the form HKEY_CURRENT_ USER\Software\company_name\product_name\product_ version. |
UseWaitCursor | Determines whether this thread’s forms display a wait cursor. Set this to True before performing a long operation, and set it to False when the operation is finished. |
To set the CompanyName, ProductName, and ProductVersion, open Solution Explorer, double-click the My Project entry, and select the Application tab. Then click the Assembly Information button and enter the values on the Assembly Information dialog box.
The following table describes the Application object’s most useful methods.
Method | Purpose |
---|---|
AddMessageFilter | Adds a message filter to monitor the event loop’s Windows messages. See the following text for an example. |
DoEvents | Processes Windows messages that are currently in the message queue. If the thread is performing a long calculation, it would normally prevent the rest of the thread from taking action such as processing these messages. Calling DoEvents lets the user interface catch up with the user’s actions. Note that you can often avoid the need for DoEvents if you perform the long task on a separate thread. |
Exit | Ends the whole application. This is a rather abrupt halt and any forms that are loaded do not execute their FormClosing or FormClosed event handlers, so be certain that the application has executed any necessary clean-up code before calling Application.Exit. |
ExitThread | Ends the current thread. This is a rather abrupt halt, and any forms running on the thread do not execute their FormClosing or FormClosed event handlers. |
OnThreadException | Raises the Application object’s ThreadException event, passing it an exception. If your application throws an uncaught exception in the IDE, the IDE halts. That makes it hard to test Application .ThreadException event handlers. You can call OnThreadException to invoke the event handler. |
RemoveMessageFilter | Removes a message filter. |
Run | Runs a message loop for the current thread. If you pass this method a form object, it displays the form and processes its messages until the form closes. |
SetSuspendState | Makes the system suspend operation or hibernate. When the system hibernates, it writes its memory contents to disk. When you restart the system, it resumes with its previous desktop and applications running. When the system suspends operation, it enters low-power mode. It can resume more quickly than a hibernated system, but memory contents are not saved, so they will be lost if the computer loses power. |
The following code gives a form a message filter that ignores left mouse button down messages. The NoLeftDownMessageFilter class provides the filter. It implements the IMessageFilter interface, which specifies the PreFilterMessage function.
PreFilterMessage examines a message and returns True if it wants to filter the message out of the form’s message queue. In this example, it returns True if the message is WM_LBUTTONDOWN, indicating that the left button has been pressed down.
The form’s Load event handler creates a new instance of the filter class and uses the Application object’s AddMessageFilter method to install the filter object.
The form’s Click event handler toggles the state of the Application object’s UseWaitCursor property. This displays or hides the wait cursor.
When you left-click on the form, the message filter intercepts the left button down message, so the Click event doesn’t occur. If you right-click on the form, the filter allows all messages through so the Click event occurs and the form displays or hides the wait cursor.
Public Class Form1 ' Filter out left mouse button down messages. Public Class NoLeftDownMessageFilter Implements IMessageFilter Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) _ As Boolean Implements IMessageFilter.PreFilterMessage ' If the message is left mouse down, return True ' to indicate that the message should be ignored. Const WM_LBUTTONDOWN As Long = &H201 Return (m.Msg = WM_LBUTTONDOWN) End Function End Class ' Install the message filter. Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim no_left_down_message_filter As New NoLeftDownMessageFilter Application.AddMessageFilter(no_left_down_message_filter) End Sub ' Toggle the wait cursor. Private Sub Form1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Click Application.UseWaitCursor = Not Application.UseWaitCursor End Sub End Class
The Application object provides a few events that give you information about the application’s state. The following table describes these events.
Event | Purpose |
---|---|
ApplicationExit | Occurs when the application is about to shut down. |
Idle | Occurs when the application finishes executing some code and is about to enter an idle state to wait for events. |
ThreadException | Occurs when the application throws an unhandled exception. See the following code for an example. |
ThreadExit | Occurs when a thread is about to exit. |
When you end an application by unloading its form, the program receives the events FormClosing, FormClosed, ThreadExit, and ApplicationExit, in that order.
If you end the application by calling the Application object’s Exit method, the program only receives the ThreadExit and ApplicationExit events. If more than one thread is running, they each receive ThreadExit events, and then they each receive ApplicationExit events.
The following code uses a ThreadException event handler to catch all exceptions thrown by the application. When it starts, the form’s Load event handler uses the Application object’s AddHandler method to add the app_ThreadException subroutine as a handler for the Application’s ThreadException event.
The app_ThreadException subroutine simply displays an error message so that you can tell that it executed. A real application would take different actions such as logging the error and a stack trace, restarting the application, and so forth.
When the user clicks the Throw button, the program throws an exception. If you are running the program in the development environment, Visual Studio halts at the Throw statement and tells you that it encountered an unhandled exception. If you run the compiled executable outside of the development environment, the application’s ThreadException event occurs. The app_ThreadException routine catches the event and displays its message.
When the user clicks the OnThreadException button, the program calls the Application object’s OnThreadException method, passing it an exception object. Whether you are running in the development environment or running the compiled executable, the application’s ThreadException event occurs and the app_ThreadException routine catches it.
Imports System.IO Public Class Form1 ' Install the ThreadException event handler. Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load AddHandler Application.ThreadException, AddressOf Me.app_ThreadException End Sub ' Catch a ThreadException event. Private Sub app_ThreadException(ByVal sender As Object, _ ByVal e As System.Threading.ThreadExceptionEventArgs) MessageBox.Show("Caught unhandled exception") End Sub ' Throw an InvalidDataException. Private Sub btnThrow_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnThrow.Click Throw New InvalidDataException("Bad data! Bad!") End Sub ' Call the OnThreadException method. Private Sub btnOnThreadException_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOnThreadException.Click Application.OnThreadException(New InvalidDataException("Bad data! Bad!")) End Sub End Class