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; }
0 comments