{"id":11873,"date":"2010-12-30T07:00:00","date_gmt":"2010-12-30T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2010\/12\/30\/windowfrompoint-childwindowfrompoint-realchildwindowfrompoint-when-will-it-all-end\/"},"modified":"2010-12-30T07:00:00","modified_gmt":"2010-12-30T07:00:00","slug":"windowfrompoint-childwindowfrompoint-realchildwindowfrompoint-when-will-it-all-end","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20101230-00\/?p=11873","title":{"rendered":"WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?"},"content":{"rendered":"<p>Oh wait, there&#8217;s also <code>ChildWindowFromPointEx<\/code>.\n There are many ways of identifying the window that appears beneath a point. The documentation for each one describes how they work, but I figured I&#8217;d do a little compare\/contrast to help you decide which one you want for your particular programming problem.\n The oldest functions are <code>WindowFromPoint<\/code> and <code>ChildWindowFromPoint<\/code>. The primary difference between them is that <code>WindowFromPoint<\/code> returns the deepest window beneath the point, whereas <code>ChildWindowFromPoint<\/code> returns the shallowest.\n What do I mean by deep and shallow?\n Suppose you have a top-level window&nbsp;P and a child window&nbsp;C. And suppose you ask one of the above functions, &#8220;What window is beneath this point?&#8221; when the point is squarely over window&nbsp;C. The <code>WindowFromPoint<\/code> function looks for the most heavily nested window that contains the point, which is window&nbsp;C. On the other hand <code>ChildWindowFromPoint<\/code> function looks for the least nested window that contains the point, which is window&nbsp;P, assuming you passed <code>GetDesktopWindow<\/code> as the starting point.\n That&#8217;s the most important difference between the two functions, but there are others, primarily with how the functions treat hidden, disabled, and transparent windows. Some functions will pay attention to hidden, disabled, and\/or transparent windows; others will skip them. Note that when a window is skipped, the entire window hierarchy starting from that window is skipped. For example, if you call a function that skips disabled windows, then all children of disabled windows will also be skipped (even if the children are enabled).\n Here we go in tabular form.<\/p>\n<table border=\"1\" style=\"border-collapse: collapse\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Function<\/th>\n<th>Search<\/th>\n<th>Hidden?<\/th>\n<th>Disabled?<\/th>\n<th>Transparent?&sup1;<\/th>\n<\/tr>\n<tr>\n<td><code>WindowFromPoint<\/code><\/td>\n<td>Deep<\/td>\n<td>Skip<\/td>\n<td>Skip<\/td>\n<td><a href=\"http:\/\/www.time.com\/time\/business\/article\/0,8599,1895694,00.html\">It&#8217;s Complicated<\/a>&sup2;<\/td>\n<\/tr>\n<tr>\n<td><code>ChildWindowFromPoint<\/code><\/td>\n<td>Shallow<\/td>\n<td>Include<\/td>\n<td>Include<\/td>\n<td>Include<\/td>\n<\/tr>\n<tr>\n<td><code>ChildWindowFromPointEx<\/code><\/td>\n<td>Shallow<\/td>\n<td>Optional<\/td>\n<td>Optional<\/td>\n<td>Optional<\/td>\n<\/tr>\n<tr>\n<td><code>RealChildWindowFromPoint<\/code><\/td>\n<td>Shallow<\/td>\n<td>Skip<\/td>\n<td>Include<\/td>\n<td>Include&sup3;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p> The return values for the various <code>...FromPoint...<\/code> functions are the same:<\/p>\n<ul>\n<li>Return the handle of the found window, if a window was found. <\/li>\n<li>Return the handle of the parent window     if the point is inside the parent window but not inside     any of the children.     (This rule obviously does not apply to <code>WindowFromPoint<\/code>     since there is no parent window passed into the function.) <\/li>\n<li>Otherwise, return <code>NULL<\/code>. <\/li>\n<\/ul>\n<p> The entries for <code>ChildWindowFromPointEx<\/code> are marked <i>Optional<\/i> because you, the caller, get to specify whether you want them to be skipped or included based on the <code>CWP_*<\/code> flags that you pass in.\n &sup1;There is a lot hiding behind the word <i>Transparent<\/i> because there are multiple ways a window can be determined transparent. The <code>...ChildWindowFromPoint...<\/code> functions define transparent as <i>has the <code>WS_EX_TRANSPARENT<\/code> extended window style<\/i>.\n &sup2;On the other hand, <code>WindowFromPoint<\/code> defines transparent as <i>returns <code>HTTRANSPARENT<\/code> in response to <code>WM_NCHITTEST<\/code><\/i>. Actually, that&#8217;s still not true. If the window belongs to a <strike>process<\/strike> <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/12\/30\/10110077.aspx#10110646\">thread<\/a> different from the one calling <code>WindowFromPoint<\/code>, then <code>WindowFromPoint<\/code> will not send the message and will simply treat the window as opaque (<i>i.e.<\/i>, not transparent).\n &sup3;The <code>RealChildWindowFromPoint<\/code> includes transparent windows in the search, but <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/07\/12\/10036953.aspx#10037230\"> has a special case for group boxes<\/a>: The <code>RealChildWindowFromPoint<\/code> function skips over group boxes, <i>unless<\/i> the return value would have been the parent window, in which case it returns the group box after all.\n Why is <code>RealChildWindowFromPoint<\/code> so indecisive?\n The <code>RealChildWindowFromPoint<\/code> function was added as part of the changes to Windows to support accessibility. The intended audience for <code>RealChildWindowFromPoint<\/code> is accessibility tools which want to return a &#8220;reasonable&#8221; window beneath a specific point. Since group boxes usually enclose other controls, <code>RealChildWindowFromPoint<\/code> prefers to return one of the enclosed controls, but if the point belongs to the group box frame, then it&#8217;ll return the group box.\n One place I see confusion over the various <code>...WindowFromPoint...<\/code> functions is code which uses one of the functions, and then massages the result, unaware that there is already a function that returns the pre-massaged result for you. For example, I&#8217;ve seen code which calls <code>WindowFromPoint<\/code> followed by <code>GetAncestor(GA_ROOT)<\/code>. This does a pointless down-and-up traversal of the window tree, searching for the deepest window that lies beneath the specified point, then walking back up the tree to convert it to a shallow window. This is the Rube Goldberg way of calling <code>ChildWindowFromPointEx(GetDesktopWindow(), ...)<\/code>.<\/p>\n<p> Next time, a look at the mysterious <code>RealGetWindowClass<\/code> function. What makes this function more real? <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oh wait, there&#8217;s also ChildWindowFromPointEx. There are many ways of identifying the window that appears beneath a point. The documentation for each one describes how they work, but I figured I&#8217;d do a little compare\/contrast to help you decide which one you want for your particular programming problem. The oldest functions are WindowFromPoint and ChildWindowFromPoint. [&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-11873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Oh wait, there&#8217;s also ChildWindowFromPointEx. There are many ways of identifying the window that appears beneath a point. The documentation for each one describes how they work, but I figured I&#8217;d do a little compare\/contrast to help you decide which one you want for your particular programming problem. The oldest functions are WindowFromPoint and ChildWindowFromPoint. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/11873","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=11873"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/11873\/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=11873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=11873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=11873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}