Enumerating open windows

Codeless

Regular
Joined
Jan 24, 2003
Messages
59
Location
Great NW
I have a program that, at times, has its window closed, but continues to run as a process in the background. I can use the Process class to find and kill the process, but what I'm looking for is a way to know for sure that the window is closed. How can I enumerate through all open forms to see if it exists. I have used the Windows API's in the past, but can it be done in .NET?
 
There's several ways you can do this. Here's one (not necessarily the best, but worth consideration):

Put the following code in a Module.
Code:
Module FormsCollection 
Public Forms As New FormsCollectionClass() 
End Module 

Class FormsCollectionClass : Implements IEnumerable 
Public AllForms As New Collection() 

Sub Add(ByVal f As Form) 
AllForms.Add(f) 
End Sub 

Sub Remove(ByVal f As Form) 
Dim itemCount As Integer 
For itemCount = 1 To AllForms.Count 
If f Is AllForms.Item(itemCount) Then 
AllForms.Remove(itemCount) 
Exit For 
End If 
Next 
End Sub 

ReadOnly Property Item(ByVal index) As Form 
Get 
Return AllForms.Item(index) 
End Get 
End Property 

Overridable Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator 
Return AllForms.GetEnumerator 
End Function 
End Class

In each Form in your project add:
Code:
Forms.Add(Me) 
 '  'After the : "Add any initialization after the InitializeComponent" line

And again in each form, add:
Code:
Forms.Remove(Me) 
  'as the first line in the "Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) " code block

You can now test for how many open forms you have at any time with:
Code:
Forms.AllForms.Count
'  eg
If (Forms.AllForms.Count = 0) Then 
:

You can also enumerate through the forms collection and test any form property, including the Name if you wanted to test for a particular form's existence:
Code:
Dim frm As Form 
Dim TempStr As String 
For Each frm In Forms 
TempStr &=  f.Name & VBCRLF
Next

As I say, not the slickest way, but it's OK.
 
i normally do it like this ...
Code:
    Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
    Private Const WM_CLOSE As Integer = &H10

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim typeForm As Type

        For Each typeForm In Reflection.Assembly.GetExecutingAssembly.GetTypes
            If typeForm.IsSubclassOf(GetType(Form)) Then
                Dim hWnd As Integer = FindWindow(Nothing, typeForm.Name)
                If Not hWnd = 0 AndAlso Not hWnd = MyBase.Handle.ToInt32 Then '/// make sure we dont close this form ( yet )
                    SendMessage(hWnd, WM_CLOSE, 0, 0)
                End If
            End If
        Next

        '/// if you want to also close this form , you can now add --- MyBase.Close()
    End Sub
 
Codeless said:
I have a program that, at times, has its window closed, but continues to run as a process in the background. I can use the Process class to find and kill the process, but what I'm looking for is a way to know for sure that the window is closed. How can I enumerate through all open forms to see if it exists. I have used the Windows API's in the past, but can it be done in .NET?

check out this library.

I believe there is a method, Win32Window.DesktopWindow.TopLevel, that may be what you need.
 
Hey dynamic_sysop,

Your code interested me, but I can't determine what (or if) this line is supposed to do anything...

Dim hWnd As Integer = FindWindow(Nothing, typeForm.Name)

... because it always returns 0, no matter which forms are open or closed as I run the program. So all this does is loop thru all the forms included within the project? Thanks for your help.
 
Back
Top