Сообщений 1    Оценка 126        Оценить  
Система Orphus

Как создать многострочный тултип?

Автор: Александр Шаргин

Версия текста: 1.0

Начиная с версии 4.70 библиотеки Comctl32.dll тултипы поддерживают многострочный режим работы. По умолчанию он выключен, и всё, что требуется от нас - активизировать его. Для этого предназначено сообщение TTM_SETMAXTIPWIDTH, которое позволяет задать ширину тултипа (в пикселях). По умолчанию ширина установлена в -1, что соответствует однострочному режиму работы. В этом режиме тултип игнорирует все пары '\r\n' в тексте подсказки, выдавая его в одну строку. Задание любого положительного значения ширины переводит тултип в многострочный режим работы.

В многострочном режиме тултип корректно обрабатывает комбинации '\r\n', переходя на новую строку. Кроме того, он старается вписать текст в заданную ширину, разбивая его на строки самостоятельно. Переход на новую строку возможен только между словами, поэтому если в тексте подсказки есть длинные слова, заданная ширина может быть превышена. Если вы не хотите, чтобы тултип разбивал текст на строки по своему усмотрению, задайте значение ширины, заведомо превышающее ширину экрана. Например:

SendMessage(hTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)0xFFFFFF);

В MFC аналогичного эффекта можно добиться, используя фукцию CToolTipCtrl::SetMaxTipWidth. Единственный параметр, который она получает - новое значение ширины тултипа. Например:

// m_tt - объект класса CToolTipCtrl
m_tt.SetMaxTipWidth(0xFFFFFF);

Проблемы возникают только в том случае, когда вы используете встроенную поддержку тултипов класса CWnd. В этом случае тултип создаётся и уничтожается в недрах MFC, причём документированного способа добраться до него не существует. Выйти из положения можно, воспользовавшись недокументированным: MFC сохраняет указатель на созданный ею объект класса CToolTipCtrl в структуре _AFX_THREAD_STATE, и можно получить к нему доступ, используя выражение AfxGetThreadState()->m_pToolTip.

Вторая проблема состоит в том, что MFC сама следит за временем жизни тултипа, и мы не можем точно знать, когда он уничтожается и создаётся заново. Поэтому ширину тултипа необходимо заново задавать всякий раз, когда тултип "собирается" появиться на экране. Удобнее всего делать это в ответ на уведомление TTN_NEEDTEXT, например:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFFFFFF, OnToolTipText)
END_MESSAGE_MAP()

BOOL CMainFrame::OnToolTipText(...)
{
    CToolTipCtrl* ptt = AfxGetThreadState()->m_pToolTip;

    ptt->SetMaxTipWidth(0xFFFFFF);

    return CFrameWnd::OnToolTipText(...);
}

Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 1    Оценка 126        Оценить