{"id":39663,"date":"2004-04-23T06:59:00","date_gmt":"2004-04-23T06:59:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/04\/23\/how-to-retrieve-text-under-the-cursor-mouse-pointer\/"},"modified":"2004-04-23T06:59:00","modified_gmt":"2004-04-23T06:59:00","slug":"how-to-retrieve-text-under-the-cursor-mouse-pointer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040423-00\/?p=39663","title":{"rendered":"How to retrieve text under the cursor (mouse pointer)"},"content":{"rendered":"<p>\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msaa\/msaastart_9w2t.asp\">\nMicrosoft Active Accessibilty<\/a> is the technology that\nexposes information about objects on the screen to accessibility\naids such as screen readers.\nBut that doesn&#8217;t mean that only screen readers can use it.\n<\/p>\n<p>\nHere&#8217;s a program that illustrates the use of Active Accessibility\nat the most rudimentary level: Reading text.  There&#8217;s much more to\nActive Accessibility than this. You can navigate the objects on the\nscreen, read various properties, even invoke commands on them,\nall programmatically.\n<\/p>\n<p>\nStart with our\n<a HREF=\"\/oldnewthing\/archive\/2003\/07\/23\/54576.aspx\">\nscratch program<\/a> and change these two functions:\n<\/p>\n<pre>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n  <font COLOR=\"blue\">SetTimer(hwnd, 1, 1000, RecalcText);<\/font>\n  return TRUE;\n}\nvoid\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\n{\n  <font COLOR=\"blue\">if (g_pszText) {\n      RECT rc;\n      GetClientRect(hwnd, &amp;rc);\n      DrawText(pps-&gt;hdc, g_pszText, lstrlen(g_pszText),\n               &amp;rc, DT_NOPREFIX | DT_WORDBREAK);\n  }<\/font>\n}\n<\/pre>\n<p>\nOf course, the fun part is the function <code>RecalcText<\/code>,\nwhich retrieves the text from beneath the cursor:\n<\/p>\n<pre>\n#include &lt;oleacc.h&gt;\nPOINT g_pt;\nLPTSTR g_pszText;\nvoid CALLBACK RecalcText(HWND hwnd, UINT, UINT_PTR, DWORD)\n{\n  POINT pt;\n  if (GetCursorPos(&amp;pt) &amp;&amp;\n    (pt.x != g_pt.x || pt.y != g_pt.y)) {\n    g_pt = pt;\n    IAccessible *pacc;\n    VARIANT vtChild;\n    if (SUCCEEDED(AccessibleObjectFromPoint(pt, &amp;pacc, &amp;vtChild))) {\n      BSTR bsName = NULL;\n      BSTR bsValue = NULL;\n      pacc-&gt;get_accName(vtChild, &amp;bsName);\n      pacc-&gt;get_accValue(vtChild, &amp;bsValue);\n      LPTSTR pszResult;\n      DWORD_PTR args[2] = { (DWORD_PTR)(bsName ? bsName : L\"\"),\n                            (DWORD_PTR)(bsValue ? bsValue : L\"\") };\n      if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |\n                        FORMAT_MESSAGE_FROM_STRING |\n                        FORMAT_MESSAGE_ARGUMENT_ARRAY,\n                        TEXT(\"Name: %1!ws!\\r\\n\\r\\nValue: %2!ws!\"),\n                        0, 0, (LPTSTR)&amp;pszResult, 0, (va_list*)args)) {\n        LocalFree(g_pszText);\n        g_pszText = pszResult;\n        InvalidateRect(hwnd, NULL, TRUE);\n      }\n      SysFreeString(bsName);\n      SysFreeString(bsValue);\n      VariantClear(&amp;vtChild);\n      pacc-&gt;Release();\n    }\n  }\n}\n<\/pre>\n<p>\nLet&#8217;s take a look at this function.\nWe start by grabbing the cursor position\nand seeing if it changed since the last time we checked.\nIf so, then we ask\n<code>AccessibleObjectFromPoint<\/code> to identify the object\nat those coordinates and give us an <code>IAccessible<\/code>\npointer plus a child identifier.  These two pieces of information\ntogether represent the object under the cursor.\n<\/p>\n<p>\nNow it&#8217;s a simple matter of asking for\nthe name (<code>get_accName<\/code>)\nand value (<code>get_accValue<\/code>)\nof the object and format it nicely.\n<\/p>\n<p>\nNote that we handled the NULL case of the BSTR in accordance with\n<a HREF=\"http:\/\/weblogs.asp.net\/ericlippert\/archive\/2003\/09\/12\/52976.aspx\">\nEric&#8217;s Complete Guide to BSTR Semantics<\/a>.\n<\/p>\n<p>\nFor more information about accessibility,\ncheck out\n<a HREF=\"http:\/\/blogs.msdn.com\/saraford\">Sara Ford&#8217;s WebLog<\/a>,\nin particular the bit titled\n<a HREF=\"http:\/\/blogs.msdn.com\/saraford\/archive\/2004\/01\/06\/48083.aspx\">\nWhat is Assistive Technology Compatibility<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Microsoft Active Accessibilty is the technology that exposes information about objects on the screen to accessibility aids such as screen readers. But that doesn&#8217;t mean that only screen readers can use it. Here&#8217;s a program that illustrates the use of Active Accessibility at the most rudimentary level: Reading text. There&#8217;s much more to Active Accessibility [&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-39663","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Microsoft Active Accessibilty is the technology that exposes information about objects on the screen to accessibility aids such as screen readers. But that doesn&#8217;t mean that only screen readers can use it. Here&#8217;s a program that illustrates the use of Active Accessibility at the most rudimentary level: Reading text. There&#8217;s much more to Active Accessibility [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/39663","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=39663"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/39663\/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=39663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=39663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=39663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}