{"id":28393,"date":"2007-01-16T10:00:04","date_gmt":"2007-01-16T10:00:04","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/01\/16\/enumchildwindows-already-enumerates-recursively\/"},"modified":"2007-01-16T10:00:04","modified_gmt":"2007-01-16T10:00:04","slug":"enumchildwindows-already-enumerates-recursively","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070116-04\/?p=28393","title":{"rendered":"EnumChildWindows already enumerates recursively"},"content":{"rendered":"<p>\nI often see people write code that goes something like this:\n<\/p>\n<pre>\n<i>\/\/ do not use - see discussion\nvoid DoSomethingToWindowTree(HWND hwndRoot)\n{\n \/\/ first do it to the window passed in\n DoSomething(hwndRoot);\n \/\/ now do it to all the children\n EnumChildWindows(hwndRoot, DoSomethingHelper, 0);\n}\nBOOL CALLBACK DoSomethingHelper(HWND hwnd, LPARAM lParam)\n{\n DoSomethingToWindowTree(hwnd);\n return TRUE;\n}\n<\/i><\/pre>\n<p>\nThe intent here was to perform the operation on all the windows\nin a window tree by operating on the root, then operating on\neach of the children.\nOperating on the children is in turn performed recursively,\nso that we eventually see every window in the tree.\n<\/p>\n<p>\nExcept that if you actually run this function on a vaguely\ninteresting window tree, you&#8217;ll find that items get counted\nmultiple times.\n<\/p>\n<p>\nThe reason is that the <code>EnumChildWindows<\/code> function\n<strong>already does the recursion<\/strong>:\n<\/p>\n<blockquote CLASS=\"q\"><p>\nIf a child window has created child windows of its own,\n<b>EnumChildWindows<\/b> enumerates those windows as well.\n<\/p><\/blockquote>\n<p>\nIf you add your own recursion, then you end up counting\ngrandchildren twice, great-grandchildren four times, and so on.\nThe recursion is already done by <code>EnumChildWindows<\/code>;\njust use it.\n<\/p>\n<pre>\nvoid DoSomethingToWindowTree(HWND hwndRoot)\n{\n \/\/ first do it to the window passed in\n DoSomething(hwndRoot);\n \/\/ now do it to all the descendants (children, grandchildren, etc.)\n EnumChildWindows(hwndRoot, DoSomethingHelper, 0);\n}\nBOOL CALLBACK DoSomethingHelper(HWND hwnd, LPARAM lParam)\n{\n DoSomething(hwnd);\n return TRUE;\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I often see people write code that goes something like this: \/\/ do not use &#8211; 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; } [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-28393","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>I often see people write code that goes something like this: \/\/ do not use &#8211; 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; } [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=28393"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28393\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=28393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=28393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=28393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}