Как получить текст всплывающей подсказки для данного HWND?

Я ищу способ получить элемент управления всплывающей подсказкой (если есть), который связан с данным HWND. Текста всплывающей подсказки тоже будет достаточно. Самое близкое, что я нашел, это TTM_GETTEXT. сообщение, но оно предназначено для отправки самому элементу управления всплывающей подсказкой, а не инструменту, с которым он связан. Однако у меня нет ручки для управления всплывающей подсказкой. Кто-нибудь знает, как это сделать?

Все это делается с помощью простого Windows API на C++.


person Frerich Raabe    schedule 26.08.2009    source источник


Ответы (4)


Кажется, не существует специального сообщения для получения подсказки или ее текста из элемента управления, но именно так класс MFC CWnd реализует OnToolHitTest(), который вы сможете адаптировать к 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
}

Надеюсь, это будет полезно.

person JTeagle    schedule 26.08.2009
comment
А, интересно! Хорошая идея заглянуть туда - я впервые вижу LPSTR_TEXTCALLBACK. - person Frerich Raabe; 26.08.2009

Чтобы получить текст всплывающей подсказки из какого-либо элемента управления, вы можете использовать TTN_NEEDTEXT< /a> сообщение. Он был разработан для использования элементом управления ToolTip, но я не вижу причин, по которым вы не могли бы отправить его из другого места.

person Kirill V. Lyadvinsky    schedule 26.08.2009
comment
Выглядит интересно - к сожалению, всплывающая подсказка отправляет его только в том случае, если в поле TOOLINFO::lpszText всплывающей подсказки было установлено значение LPSTR_TEXTCALLBACK. Таким образом, каждый раз, когда отображается всплывающая подсказка, она будет запрашивать элемент управления для отображения текста. Возможно, это распространенный случай (я надеюсь на это), но я подозреваю, что все еще существует множество всплывающих подсказок со статическим текстом (например, TOOLINFO::lpszText устанавливается в статическую строку). - person Frerich Raabe; 26.08.2009

Вы можете перечислить окна, ища элемент управления всплывающей подсказкой, у которого есть родитель требуемого окна. Вам нужно будет предоставить окно вместе с идентификатором инструмента (обычно из 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;
}
person Alan    schedule 24.10.2009
comment
К сожалению, для этого требуется, чтобы всплывающая подсказка была видна. В противном случае нет дескриптора окна всплывающей подсказки, который могла бы заметить функция FindToolTip. - person Frerich Raabe; 21.07.2010

Я не знаю, является ли окно, всплывающую подсказку которого вы хотите получить, дочерним элементом окна, которое вы создали.

Если это так, вы можете обработать уведомление NM_TOOLTIPSCREATED, которое дочернее окно отправляет своему родителю при создании всплывающей подсказки (или должно быть отправлено: это верно для обычных элементов управления, но я не знаю, для других видов окна). Это уведомление включает дескриптор окна всплывающей подсказки.

person Adrien Plisson    schedule 25.10.2009