January 16th, 2007

EnumChildWindows already enumerates recursively

I often see people write code that goes something like this:

// do not use - see discussion
void DoSomethingToWindowTree(HWND hwndRoot)
{
 // first do it to the window passed in
 DoSomething(hwndRoot);
 // now do it to all the children
 EnumChildWindows(hwndRoot, DoSomethingHelper, 0);
}
BOOL CALLBACK DoSomethingHelper(HWND hwnd, LPARAM lParam)
{
 DoSomethingToWindowTree(hwnd);
 return TRUE;
}

The intent here was to perform the operation on all the windows in a window tree by operating on the root, then operating on each of the children. Operating on the children is in turn performed recursively, so that we eventually see every window in the tree.

Except that if you actually run this function on a vaguely interesting window tree, you’ll find that items get counted multiple times.

The reason is that the EnumChildWindows function already does the recursion:

If a child window has created child windows of its own, EnumChildWindows enumerates those windows as well.

If you add your own recursion, then you end up counting grandchildren twice, great-grandchildren four times, and so on. The recursion is already done by EnumChildWindows; just use it.

void DoSomethingToWindowTree(HWND hwndRoot)
{
 // first do it to the window passed in
 DoSomething(hwndRoot);
 // now do it to all the descendants (children, grandchildren, etc.)
 EnumChildWindows(hwndRoot, DoSomethingHelper, 0);
}
BOOL CALLBACK DoSomethingHelper(HWND hwnd, LPARAM lParam)
{
 DoSomething(hwnd);
 return TRUE;
}
Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.