{"id":623,"date":"2014-06-30T07:00:00","date_gmt":"2014-06-30T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/06\/30\/getting-the-location-of-the-close-button-in-the-title-bar-from-windows-2000-or-windows-xp\/"},"modified":"2014-06-30T07:00:00","modified_gmt":"2014-06-30T07:00:00","slug":"getting-the-location-of-the-close-button-in-the-title-bar-from-windows-2000-or-windows-xp","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140630-00\/?p=623","title":{"rendered":"Getting the location of the Close button in the title bar, from Windows 2000 or Windows XP"},"content":{"rendered":"<p>\nToday&#8217;s Little Program locates the &times; button in the corner\nof the window and\ndisplays a balloon tip pointing at it.\nWe did this\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/05\/05\/10522553.aspx\">\nsome time ago<\/a>\nwith the help of the\n<code>WM_GET&shy;TITLE&shy;BAR&shy;INFO&shy;EX<\/code> message,\nwhich is new for Windows Vista.\nBut what if you don&#8217;t have that message available,\nsay, because you&#8217;re running on Windows 2000 or Windows&nbsp;XP\nor (gasp) Windows&nbsp;98?\n<\/p>\n<p>\nYou can use the classic Accessibility interface\n<code>IAccessible<\/code>\nto enumerate the buttons in the title bar and see which\none the window reports as the Close button.\n<\/p>\n<p>\nLet&#8217;s take the program from last time and change the\n<code>Get&shy;Close&shy;Button&shy;Center<\/code> function:\n<\/p>\n<pre>\n<font COLOR=\"blue\">#include &lt;oleacc.h&gt;\n#include &lt;atlbase&gt;<\/font>\nBOOL GetCloseButtonCenter(HWND hwnd, POINT *ppt)\n{\n <font COLOR=\"blue\">CComPtr&lt;IAccessible&gt; spacc;\n if (FAILED(AccessibleObjectFromWindow(hwnd, OBJID_TITLEBAR,\n                   IID_PPV_ARGS(&amp;spacc)))) return FALSE;\n CComQIPtr&lt;IEnumVARIANT&gt; spenum(spacc);\n if (!spenum) return FALSE;\n for (CComVariant vtChild; spenum-&gt;Next(1, &amp;vtChild, nullptr) == S_OK;\n      vtChild.Clear()) {\n  CComVariant vtState;\n  if (FAILED(spacc-&gt;get_accState(vtChild, &amp;vtState))) continue;\n  if (vtState.vt != VT_I4) continue;\n  if (vtState.lVal &amp; (STATE_SYSTEM_INVISIBLE |\n                      STATE_SYSTEM_OFFSCREEN |\n                      STATE_SYSTEM_UNAVAILABLE)) continue;\n  long left, top, width, height;\n  if (FAILED(spacc-&gt;accLocation(&amp;left, &amp;top, &amp;width, &amp;height,\n                                vtChild))) continue;\n  POINT pt = { left + width \/ 2, top + height \/ 2 };\n  if (SendMessage(hwnd, WM_NCHITTEST, 0,\n                  MAKELPARAM(pt.x, pt.y)) == HTCLOSE) {\n   *ppt = pt;\n   return TRUE;\n  }\n }\n return FALSE;<\/font>\n}\n<\/pre>\n<p>\nWe obtain the <code>IAccessible<\/code> interface for the title bar\nand proceed to enumerate its children.\nFor each child, we get its location, and then use the\n<code>WM_NC&shy;HIT&shy;TEST<\/code> message to determine\nprogrammatically what that location corresponds to.\nIf the answer is &#8220;This is the Close button,&#8221;\nthen we found the button and report its center.\n<\/p>\n<p>\nNote that this once again highlights\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/02\/18\/10131176.aspx\">\nthe distinction between\n<code>WM_NC&shy;MOUSE&shy;MOVE<\/code> and\n<code>WM_NC&shy;HIT&shy;TEST<\/code><\/a>.\nHit-testing can occur for reasons other than mouse movement.\n<\/p>\n<p>\n<b>Exercise<\/b>:\nWhy couldn&#8217;t we use the\n<code>IAccessible::get_accName<\/code>\nmethod to figure out which button each child represents?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today&#8217;s Little Program locates the &times; button in the corner of the window and displays a balloon tip pointing at it. We did this some time ago with the help of the WM_GET&shy;TITLE&shy;BAR&shy;INFO&shy;EX message, which is new for Windows Vista. But what if you don&#8217;t have that message available, say, because you&#8217;re running on Windows [&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-623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Today&#8217;s Little Program locates the &times; button in the corner of the window and displays a balloon tip pointing at it. We did this some time ago with the help of the WM_GET&shy;TITLE&shy;BAR&shy;INFO&shy;EX message, which is new for Windows Vista. But what if you don&#8217;t have that message available, say, because you&#8217;re running on Windows [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/623","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=623"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/623\/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=623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}