title: Get Win32 legacy control's tooltip text programmatically
body: <p>I would like to get the tooltip text for win32 legacy control (not WPF controls that inherently support <a href="https://msdn.microsoft.com/en-us/library/ms747327.aspx" rel="nofollow noreferrer">UI Automation</a>).</p>
  
  <p><img src="https://i.stack.imgur.com/JaSNo.png" alt="Screenshot of the buttons"></p>
  
  <p>What I have done:</p>
  
  <ul>
  <li>Given a button of interest, I've got its <code>AutomationElement</code>, and its bounding rect</li>
  <li>I moved the mouse over this button (in code);</li>
  <li><code>Thread.Sleep(1500)</code> to wait for the tooltip control to popup;</li>
  <li>Enumerate Desktop's all child windows, and get the child window <code>tooltipAutomationElement</code>, whose type is <code>"Tooltip"</code>;</li>
  <li>From <code>tooltipAutomationElement</code>, get this tooltip's name property, which corresponds to the tooltip string.</li>
  </ul>
  
  <p>This actually works, but the penalty is: I have to <code>sleep(1500)</code> and manually wait for the tooltip to appear (5-20 buttons are to be scanned for the tooltip strings), which does not match performance requirement.</p>
  
  <p>What is expected (not sure if it is feasible)</p>
  
  <ul>
  <li>Programmatically get the button's tooltip string without requiring the tooltip to appear</li>
  <li>Without having to place mouse over each button one-by-one.</li>
  </ul>
  
  <p><strong>Update 1</strong>: For <code>TTN_NEEDTEXT</code>, MSDN doc seems not very clear, and I have no clue how to program this using C#. One of the relevant link for low level structures/messages related to tooltip control can be found <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb760250%28v=vs.85%29.aspx" rel="nofollow noreferrer">here</a>.</p>
  
  <p><strong>Update 2</strong>: Those who believe this could be done by ... , I would say, it is easier said than done. I welcome those who have tried, to comment on this, and some ostensibly feasible solutions are welcome if you <em>can offer some evidence</em> to show its applicability and efficacy.</p>
  
  <p><strong>Update 3</strong>: If we try to minimize the <code>TTM_SETDELAYTIME</code> so that <code>N</code> in the <code>sleep(N)</code> can be minimized, this does not work after some experimentation. We can only adjust this once the tooltip window handle exists. e.g.</p>
  
  <pre><code>SendMessage(_tooltipCtrl.Handle, TTM_SETDELAYTIME, _TTDT_INITIAL, 10); //10 ms
  </code></pre>
  
  <p><strong>Update 4</strong>: using <code>TTM_GETTEXTA</code> message seems to be a solution, however, it is similar to Update 3, where we need the handle of the <code>tooltipCtrl</code>, which is only available AFTER the tooltip is created, since to have this tooltip created, we have no choice but to hover mouse cursor above the tool, which seems to have performance issues (<code>Thread.Sleep</code>) as outlined above.</p>
  
  <pre><code>SendMessage(_tooltipCtrl.Handle, TTM_GETTEXTA, 0, ti);
  </code></pre>
  
  <p><strong>Update 5</strong>: "How to get the tooltip text" using InterOp (PInvoke) or Automation UI using traditional approach (mouse hovering on the tool window, find the Hwnd handle, then get its text...) is not the concern of this post. What is expected: <strong>Can we extract the tooltip string of a control (say a button) with no need of hovering upon the control</strong>? If yes, how? </p>
  
  <p><strong>Update 6</strong>: using WM_MOUSEHOVER to activate the tooltip window seems not working, I have tested that out using SendMessage(...) with proper wparam and lparam filled, but in vein.</p>