I'm looking for a way to get the tooltip control (if any) which is associated with a given HWND. The text of the tooltip control would be sufficient, too. The closest thing I found is the TTM_GETTEXT message, but it's meant to be sent to the tooltip control itself instead of the tool it's associated with. I don't have a handle to the tooltip control though. Does anybody know how to do this?
All this is done using plain Windows API in C++.
There doesn't seem to be a specific message to get the tip or its text from the control, but this is how MFC's CWnd class implements OnToolHitTest(), which you should be able to adapt to Win32:
INT_PTR SomeFunction(HWND hWndChild, TOOLINFO *pTI)
{
if (hWndChild != NULL) // Your HWND being tested
{
// return positive hit if control ID isn't -1
INT_PTR nHit = _AfxGetDlgCtrlID(hWndChild);
// Replace with GetDlgCtrlID().
// hits against child windows always center the tip
if (pTI != NULL && pTI->cbSize >= sizeof(AFX_OLDTOOLINFO))
{
// setup the TOOLINFO structure
pTI->hwnd = m_hWnd;
pTI->uId = (UINT_PTR)hWndChild;
pTI->uFlags |= TTF_IDISHWND;
pTI->lpszText = LPSTR_TEXTCALLBACK;
// set TTF_NOTBUTTON and TTF_CENTERTIP if it isn't a button
if (!(::SendMessage(hWndChild, WM_GETDLGCODE, 0, 0) & DLGC_BUTTON))
pTI->uFlags |= TTF_NOTBUTTON|TTF_CENTERTIP;
}
return nHit;
}
return -1; // not found
}
Hopefully this will be useful.
To get tooltip text from some control you could use TTN_NEEDTEXT
message. It was designed to be used by the ToolTip control, but I cannot see any reason why you could not send it from other place.
You could enumerate the windows looking for a tooltip control that has a parent of the required window. You'll need to supply the window together with the tool id (normally from GetDlgCtrlID
)...:
HWND hToolTipWnd = NULL;
BOOL GetToolTipText(HWND hWnd, UINT nId, std::wstring& strTooltip)
{
hToolTipWnd = NULL;
EnumWindows(FindToolTip, (LPARAM)hWnd);
if (hToolTipWnd == NULL)
return FALSE;
WCHAR szToolText[256];
TOOLINFO ti;
ti.cbSize = sizeof(ti);
ti.hwnd = hWnd;
ti.uId = nId;
ti.lpszText = szToolText;
SendMessage(hToolTipWnd, TTM_GETTEXT, 256, (LPARAM)&ti);
strTooltip = szToolText;
return TRUE;
}
BOOL CALLBACK FindToolTip(HWND hWnd, LPARAM lParam)
{
WCHAR szClassName[256];
if (GetClassName(hWnd, szClassName, 256) == 0)
return TRUE;
if (wcscmp(szClassName, L"tooltips_class32") != 0)
return TRUE;
if (GetParent(hWnd) != (HWND)lParam)
return TRUE;
hToolTipWnd = hWnd;
return FALSE;
}
I don't know if the window whose tooltip you want to retrieve is a child of a window you have created.
If this is the case, you can handle the NM_TOOLTIPSCREATED notification, which is sent by a child window to its parent when it creates a tooltip (or should be sent: it is true for common controls but I don't know for other kinds of windows). This notification includes a handle to the tooltip window.