Исчерпывающее руководство по написанию всплывающих подсказок

Джек Роджер

Всплывающие подсказки (ToolTips) облегчают использование приложений. Если вам неясно назначение кнопки на панели инструментов (ToolBar), вы просто наводите на нее курсор мыши и ждете появления подсказки. Конечно, с помощью строки состояния можно получить больше информации, но в случае с всплывающими подсказками вам не приходится опускать взгляд вниз окна.

Существуют также другие виды подсказок: TitleTips – для расширения заголовков элементов управления "список" и "древовидный список", и DataTips – для получения дополнительной информации о данных в окне, и всплывающие подсказки для Web-страниц. Эта статья является подробным учебником по использованию подсказок в ваших приложениях, начиная от добавления простых подсказок средствами MFC до написания своих собственных подсказок. По пути я покажу, как добавлять подсказки к вашим Web-страницам, включая всплывающие подсказки для простого ActiveX-элемента "кнопка". Но прежде чем приступать к обсуждению деталей, давайте посмотрим, какую поддержку всплывающих подсказок предоставляют классы MFC.

Поддержка подсказок MFC-классами

Библиотека MFC располагает двумя классами для поддержки всплывающих подсказок: CToolTipCtrl и CWnd. CToolTipCtrl инкапсулирует функциональность стандартного элемента управления ToolTip (из библиотеки элементов управления общего назначения – Common Controls DLL) и может, таким образом, использоваться для создания и управления элементом подсказки напрямую. Один элемент ToolTip может поддерживать много инструментов (tools), которые представляют собой прямоугольники в окне, и могут быть (а могут и не быть) дочерними окнами. Один инструмент также может заполнять все окно. Информация об инструменте в некоторых случаях передается в структуре TOOLINFO со следующими полями: хэндл окна, содержащего инструмент, ID или хэндл окна самого инструмента, координаты инструмента (прямоугольник), и информация о тексте для этого инструмента. Один из самых важных методов – это CToolTipCtrl::RelayEvent, который используется для ретрансляции (relay) сообщений мыши элементу ToolTip для обработки. Передача сообщений мыши элементу необходима для того, чтобы ToolTip смог определить момент, когда следует показать или скрыть подсказку. К сожалению, CToolTipCtrl не полностью инкапсулирует функциональность элемента ToolTip. К примеру, CToolTipCtrl::SetDelayTime не поддерживает все допустимые интервалы задержки. Иногда мне приходилось напрямую использовать сообщения и уведомления Windows® из-за подобных ограничений.

[1]

Имена всех сообщений (messages) элемента ToolTip начинаются с префикса "TTM_", а имена всех уведомлений (notifications) – с префикса "TTN_". Далее я буду много использовать этот класс, поэтому пока что не стану заострять на нем внимание.

Не так давно Microsoft расширила DLL, содержащую элемент ToolTip (comctl32.dll), с выпуском Microsoft® Internet Explorer 4.0 (IE 4.0). Статья в MSJ из двух частей – "Предварительный обзор библиотеки элементов управления общего назначения для Microsoft Internet Explorer" (первая часть которой была опубликована в октябре 1996 года) – прекрасно описывает новые возможности библиотеки. В эти возможности входят пользовательская отрисовка подсказок (owner-draw), многострочные подсказки, подсказки произвольного цвета, а также поддержка подсказок, перемещающихся за мышью. Появилось сообщение TTM_GETDELAYTIME для получения различных значений интервалов задержки и сообщение TTM_POP для скрытия элемента ToolTip. Увы, на тот момент, когда я пишу эти строки, Microsoft еще не добавила поддержку новых возможностей в CToolTipCtrl. Поэтому для примеров в этой статье я вынужден использовать CWnd::SendMessage. (В выходящем скоро Visual Studio файл commctl.h должен содержать все необходимые объявления – ред.)

Класс CWnd представляет базовую поддержку добавления подсказок к окну. Рисунок 1 показывает методы CWnd для поддержки подсказок. CWnd::EnableToolTips разрешает или запрещает подсказки для окна, и должна быть вызвана до вызова других методов. Нужно заметить, что в работе CWnd::EnableToolTips есть недостаток: когда вы передаете CWnd::EnableToolTips значение FALSE, этот метод вызывает еще один метод, который посылает сообщение для деактивации элемента ToolTip. Когда же вы вызываете CWnd::EnableToolTip со значением TRUE, он не активирует ToolTip заново.

Рис.1. Поддержка подсказок классом CWnd