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

Шрифт
Интервал

стр.

Я посылаю несколько сообщений элементу DataTip, чтобы подготовить его к использованию. TTM_SETMAXTIPWIDTH посылается с заведомо большим значением (SHRT_MAX) в параметре lParam для установки максимальной ширины подсказки.[2] Это заставляет элемент ToolTip распознавать символы новой строки в строке подсказки (новая возможность IE 4.0 Common Controls DLL). Затем я три раза посылаю сообщение TTM_SETDELAYTIME.[3] В первый раз параметр wParam имеет значение TTDT_AUTOPOP, для установки времени, которое должно пройти до того, как ToolTip исчезнет. Время инициализируется в параметре lParam заведомо большим значением (SHRT_MAX), чтобы отключить автоисчезание подсказок.[4] Теперь я могу контролировать их время жизни. Во второй раз в wParam передается TTDT_INITIAL, что задает интервал между моментом остановки курсора мыши и первым появлением подсказки. Этот интервал устанавливается в 200 миллисекунд, поэтому подсказка появляется довольно быстро. И, наконец, TTDT_RESHOW устанавливает временной интервал между появлением следующей подсказки при перемещении курсора в другой круг. Этот интервал также установлен в 200 миллисекунд. Почему я не использовал CToolTipCtrl::SetDelayTime для установки интервалов? К сожалению, CToolTipCtrl::SetDelayTime позволяет задать только интервал для TTDT_AUTOMATIC.

Реализации CDTDemoView::OnDraw и CDTDemoView::HitTest довольно прозрачны. CDTDemoView::OnDraw проходит по массиву кругов, вызывая для каждого круга CCircle::Draw. Функция CDTDemoView::HitTest проверяет, находится ли переданная ему точка над каким-нибудь кругом, вызывая для каждого круга в массиве CCircle::HitTest. Обратите внимание, что эта проверка выполняется в порядке, обратном используемому в CDTDemoView::OnDraw. Это делается для учитывания z-сортировки (z-order) кругов. Например, если круг Б нарисован поверх круга A, тогда сначала должна вызваться функция проверки круга Б.

Функция CDTDemoView::OnToolTipNeedText перехватывает нотификационные сообщения TTN_NEEDTEXT от элемента, на который указывает переменная m_ToolTip. Главное предназначение этой функции – определить, над каким кругом находится курсор и определить текст подсказки. Сначала она получает координаты курсора мыши и конвертирует их в клиентскую систему координат. Затем идет проверка на принадлежность координат клиентской части представления. Если этого не сделать, пропадут подсказки на панели инструментов, так как нотификационное сообщение TTN_NEEDTEXT используется также панелью инструментов. CDTDemoView::OnToolTipNeedText автоматически будет получать все сообщения TTN_NEEDTEXT при активном окне представления. Переменная bHandledNotify показывает, должно ли сообщение передаваться дальше главному окну. Если курсор находится в клиентской части окна, я проверяю его координаты на принадлежность какому-нибудь кругу и сохраняю результаты проверки в переменной m_pCircleHit. Эта переменная также используется в функции CDTDemoView::OnMouseMove. Если курсор попадает в один из кругов, я создаю строку подсказки, в которую заношу координаты центра, радиус и цвет круга. Эта строка копируется в поле szText переданной структуры TOOLTIPTEXT. И, наконец, я устанавливаю цвет текста подсказки с помощью сообщения TTM_SETTIPTEXTCOLOR.[5] Параметр wParam этого сообщения содержит новое значение цвета текста, и устанавливается равным цвету круга (еще одна новая возможность IE 4.0 Common Controls DLL). Если курсор не попадает ни в один круг, поле szText указывает на пустую строку.

Функция CDTDemoView::PreTranslateMessage ретранслирует некоторые сообщения мыши элементу DataTip с помощью функции CToolTipCtrl::RelayEvent. CDTDemoView::PreTranslateMessage вызывается для каждого сообщения, посылаемого окну. Проще всего вызывать CToolTipCtrl::RelayEvent здесь, потому что в этом случае мне не нужно переопределять перехватчики каждого сообщения мыши для передачи этих сообщений элементу DataTip. Подобным же образом работает и поддержка подсказок классом CWnd.

Функция CDTDemoView::OnMouseMove прячет и показывает подсказку в зависимости от принадлежности координат курсора какому-нибудь кругу, что определяется функцией HitTest. Если курсор мыши не находится над кругом либо если он находится не над тем кругом, над которым он находился во время последнего показа подсказки, то CDTDemoView::OnMouseMove прячет подсказку вызовом m_ToolTip.Activate(FALSE). Значение FALSE показывает, что элемент DataTip должен быть спрятан. Далее, если курсор находится над другим кругом, подсказка снова выводится на экран вызовом m_ToolTip.Activate(TRUE), а в переменную CDTDemoView::m_pCircleHit заносится указатель на новый круг. Таким образом, при перемещении курсора с одного круга на другой, я выключаю подсказку и сразу включаю ее. Это делается для того, чтобы элемент DataTip запросил новый текст подсказки через сообщение TTN_NEEDTEXT, что позволяет инициализировать подсказку новой информацией о круге. В IE 4.0 для скрытия подсказки предназначено сообщение TTM_POP, но это сообщение отсутствовало в той версии файла commctrl.h, которая у меня была.


стр.

Похожие книги