Obtaining A List All Window Handles
Obtaining A List All Window Handles
Obtaining A List All Window Handles
Introduction
The most important feature when first looking into programming with the Win32 API is to being able to find the handles and class
names of the windows. Many API functions require the window handle before anything can be acheived. The code in this article
will enable you to obtain a list of all the window handles, class names and titles currently running in Excel. In effect it is doing
API Declarations
There are 3 API functions used in this code:
Buffers
The latter 2 API functions require the use of buffers. It is very common for API functions to use buffers. In Visual Basic and VBA
we are used to calling functions and using their return value. In API programming you often pass a variable to the function that is
written to by the function. In the case of strings this means passing a buffer. You can create a buffer in several ways but the way
I tend to use is to use the 'String$()' function to create a string of null characters as follows:
strText now contains a string of 100 null characters. We pass this string and its length that we know to be 100 to the functions.
The function then returns the length of the string it has written to the buffer so we can determine the string which to output
using the 'Left$()' function passing it our buffer and the API function's return value. Putting this together we have:
Recursion
The code we are creating in this article uses a technique called recursion. A ecursive procedure is a proedure that calls itself. At
first this may seem like a never ending loop is created and it is possible if you are not careful to create one! The key to it is to
create a condition in the function that when satisfied no further calls are made. In the case of the code on this page the condition
in a 'while loop'. The routine loops through calling itself until no further windows are found. ecursion is an area that can be quite
difficult to get your head round but when you do you will find it a very useful technique
parent window we want to search, the child window we want to search next in the z-order from and then the class name and
window title of the window we want to find. In this case we want to find all windows so we use 'vbNullString' in place of the last
2 arguments. It is important that we use vbNullString and not "" as vbNullString is a special value. Alternatively we could declare
the function:
The parent argument we will make flexible and pass this as an agument to the Sub. The child argument should first be 0& but for
each subsequent call should be the previous handle we found so that we loop through all the windows.
names for now. The output of the sub will be produced on an excel sheet and will start in cell A1. We will then offset by 1 column
as we enter a new level of child windows and 1 row for each window found. As the column offset is dependent on the level in the
heirachy we are looking at we shall pass this as another argument to the sub. The row however needs to be incremented for
every window found so we will declare that at module level. We also need to declare a variable in the sub to hold the class name
and window handle of each window and also one to be the return value of our API call. We therefore have the following:
Dim x As Integer
The next step is to find the first child of the hParent window. We can easily do this using:
We want to loop through every child window we find i.e. while we find a window handle so we can set up a loop:
For each of these windows though we wnat to find the class name of the window and output it. We therefore need to use the
GetClassName function to retrieve the class of the window and output it to the excel sheet as follows:
Finally we want to increment the row by 1 and also check for children of the window we have found. These child windows need
to output with an offset of 1 more than the parent. We can therefore add the following:
Dim x As Integer
This sub can be started from any window and will display all children of that window when passed the relevent window handle.
Alternatively you can pass it 0& as the hParent argument and it will find all top level windows and all their children.
Summary
Hopefully the above text will adi your understanding of using API functions as well as showing a few useful techniques. As always
if you have any commenst, suggestions or spot any errors please email [email protected]. I have added to the
code above to provide the added functionality of displaying any or all of the window handles, class names and window text and
the full code follows below. All you need to do is call the GetWindows sub. To change the output change the third argument
passed to GetWinInfo to be one of those given in the enumeration. Feel free to use and modify the code but I would appreciate it
Option Explicit
Private x As Integer
End Sub