I'm using PInvoke in C#, trying to read tooltips visible in a window with a known handler, but the apps who's windows I try to inspect in this manner crash with memory access violation errors, or simply don't reveal the tooltip text in the lpszText TOOLINFO member.
I'm calling EnumWindows with a callback and then sending a message to the tooltip window in that function:
public delegate bool CallBackPtr(IntPtr hwnd, IntPtr lParam);
static void Main(string[] args)
{
callBackPtr = new CallBackPtr(Report);
IntPtr hWnd = WindowFromPoint(<mouse coordinates point>);
if (hWnd != IntPtr.Zero)
{
Console.Out.WriteLine("Window with handle " + hWnd +
" and class name " +
getWindowClassName(hWnd));
EnumWindows(callBackPtr, hWnd);
Console.Out.WriteLine();
}
public static bool Report(IntPtr hWnd, IntPtr lParam)
{
String windowClassName = getWindowClassName(hWnd);
if (windowClassName.Contains("tool") &&
GetParent(hWnd) == lParam)
{
string szToolText = new string(' ', 250);
TOOLINFO ti = new TOOLINFO();
ti.cbSize = Marshal.SizeOf(typeof(TOOLINFO));
ti.hwnd = GetParent(hWnd);
ti.uId = hWnd;
ti.lpszText = szToolText;
SendMessage(hWnd, TTM_GETTEXT, (IntPtr)250, ref ti);
Console.WriteLine("Child window handle is " + hWnd + " and class name " + getWindowClassName(hWnd) + " and value " + ti.lpszText);
}
return true;
}
Here's how I defined the TOOLINFO structure:
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
private int _Left;
private int _Top;
private int _Right;
private int _Bottom;
}
struct TOOLINFO
{
public int cbSize;
public int uFlags;
public IntPtr hwnd;
public IntPtr uId;
public RECT rect;
public IntPtr hinst;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszText;
public IntPtr lParam;
}
the TTM_GETTEXT value
private static UInt32 WM_USER = 0x0400;
private static UInt32 TTM_GETTEXT = (WM_USER + 56);
and the SendMessage overload
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref TOOLINFO lParam);
So, is there any obvious error that I'm missing in my code, what should I change so that this situation is resolved?
Edit: Here is the whole code, so you could test.