Hi,
let's start from the beginning...:
Every process consist of at least one thread. Every thread
has a main procedure. If that main procedure ends, the thread dies.
ASA all thread died, the process quits.
A UI thread is a thread that creates windows (Forms/Controls).
As Windows is event based, you need a message loop to process the
windows messages and keep a UI thread alive.
(
http://msdn.microsoft.com/en-us/library/ms632590(VS.85).aspx)
The most flexible way to create a UI thread main procedure
is to write it on your own. The method containing the message loop
is called Application.Run(). So the minimum UI thread procedure is:
sub main
application.run()
end sub
However, this does not take you very far because there is no Form visible
yet. So, let's show a window:
sub main
dim f as form
f=new form
f.show
application.run()
end sub
Now it makes sense but application.run does not exist, yet. The message loop
would run forever. Therefore, there is an overloaded version of Run:
sub main
dim f as form
f=new form
f.show
application.run(f) 'passing a Form
end sub
This makes the message loop exit as soon as the passed Form has been closed.
In addition, we often want to use visual styles. This feature has to be enabled
before the first Form is created. Also, there's a feature called "compatible
text rendering" that is usually disabled. So, the full code is:
sub main
dim f as form
application.EnableVisualstyles
Application.SetCompatibleTextRenderingDefault(False)
f=new form
f.show
application.run(f) 'passing a Form
end sub
This kind of Sub Main has been considered as the most common Sub Main. Therefore,
(and for other purposes) the "Application Framework" has been introduced. It is
enabled by default in the project properties (on the "application" tab). If enabled,
you can specify a Form as the startup object. The compiler automatically compiles
a sub main that looks like the version above. This is to save work for the developer
for common startup scenarios. If the startup Form closes, the thread quits because
there's not code after application.run(f) anymore.
You can change the "shutdown mode" of the application on the same tab.
Either choose "When startup form closes" or "On last window close". As you write
"The startup form is Form1", it's probably the latter.
The other diaper for us hobby programmers - as MSFT considers VB developers - is the
"My" namespace. I don't elaborate on this because I completely decline it. You can make
your own decision:
http://msdn.microsoft.com/en-us/library/5btzf5yk(VS.90).aspx
I mention the My namesapce only because the Application Framework ist closely bound to it,
i.e. if you disable the My namespace, the Application Framework does not work anymore.
IMHO, My.* is like a intransparent blain inserted into your own project, and 90% of it
is dispensable. For example, there are many file IO classes/methods insinde the
System.IO namespace. The My namespace, introduced in VB 2005, duplicates most of what
already exists. It's just at detour. Instead of writing
Dim content = My.Computer.FileSystem.ReadAllBytes("blah")
you should better directly call
Dim content = IO.File.ReadAllBytes("blah")
Back to your problem: If you don't disable the My namespace like me, you can make
use of the OpenForms property:
My.Application.OpenForms
As the collection changes by closing the forms - which can be a problem when using
an enumerator - I'd put them into a list, first:
Dim forms As New List(Of Form)
For Each Form As Form In My.Application.OpenForms
If Not TypeOf Form Is Form2 Then 'exclude Form2
forms.Add(Form)
End If
Next
For Each Form In forms
Form.Close()
Next
Enough for now. ;-)