Enumerate Top Level Windows
This example illustrates how to list all of the top-level windows currently in
use and extract each window's handle, class name, title, and process and thread
IDs. It also demonstrates how to use callback
functions as well as Setting Tab Stops in a ListBox.
Although this program shows how to perform a number of useful tasks, by itself
it is not extremely useful. To see how to modify this code to
simulate the Window's Task List displayed when you hit the Alt-Tab keys, visit
my Task List example.
Download Source Code
The EnumWindows API function is used to enumerate
all of the existing windows. When you issue EnumWindows
you pass it the address of a public function defined in your code using the
AddressOf operator. The callback function,
which I named fEnumWindowsCallBack, must reside in a .bas module. The
operating system calls your function, fEnumWindowsCallBack in this case, for
each window and passes it the handle of the identified window.
EnumWindows continues until the last top-level window is enumerated
or the callback function returns False.
To build the window list, my fEnumWindowsCallBack function examines each window
it is passed and retrieves certain information about that window. For
starters, it call the GetClassName API to get the
name of the class the window belongs to. Next it calls
GetWindowText to get the window's caption. Finally, the
GetWindowThreadProcessId function is used to return the process ID
and thread ID the window is associated with.
|Setting Tab Stops in a Listbox
This information is displayed in a listbox for simplicity sake. Because
the data consists of rows and columns, a grid control comes to mind.
However, it is an easy matter to set Tab stops in a listbox to neatly
align the data into columns. To set the Tab stops I use a type safe
variation of the SendMessage function which I call
SendMessageArray. Sending the LB_SETTABSTOPS
message to the listbox with a wParam value of zero clears any existing
Tabs. To set the Tabs you need to store the Tab Stops in an array.
Then you resend the LB_SETTABSTOPS message.
This time wParam is set to the number of tab stops and the lParam value is set
to the first element of the tab stop array.
While there is a way to calculate the location of the tab stops, I find the
trial and error method to work best. The listbox program referenced above
talks about this in more detail.
Download this project and run it to view all top-level windows.