Чтение онлайн

на главную - закладки

Жанры

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

Джек Роджер

Шрифт:

 }

 CListBox::OnMouseMove(nFlags, point);

}

void CTitleTipListBox::OnSelchange {

 int nSelIndex;

 if (GetStyle & LBS_MULTIPLESEL) {

nSelIndex = GetCaretIndex;

 } else {

nSelIndex = GetCurSel;

 }

 AdjustTitleTip(nSelIndex);

 m_TitleTip.InvalidateRect(NULL);

 m_TitleTip.UpdateWindow;

}

void CTitleTipListBox::OnKillFocus(CWnd* pNewWnd) {

 CListBox::OnKillFocus(pNewWnd);

 if (pNewWnd != &m_TitleTip) {

AdjustTitleTip(m_nNoIndex);

 }

}

void CTitleTipListBox::OnDestroy {

 AdjustTitleTip(m_nNoIndex);

 m_TitleTip.DestroyWindow;

 CListBox::OnDestroy;

}

void CTitleTipListBox::OnLButtonDown(UINT nFlags, CPoint point) {

 //
Временно отключить захват мыши, так как базовый класс может

 // захватить мышь.

 if (m_bMouseCaptured) {

ReleaseCapture;

m_bMouseCaptured = FALSE;

 }

 CListBox::OnLButtonDown(nFlags, point);

 if (m_TitleTip.IsWindowVisible) {

m_TitleTip.InvalidateRect(NULL);

if (this != GetCapture) {

CaptureMouse;

}

 }

}

void CTitleTipListBox::OnLButtonUp(UINT nFlags, CPoint point) {

 CListBox::OnLButtonUp(nFlags, point);

 if (this != GetCapture && m_TitleTip.IsWindowVisible) {

CaptureMouse;

 }

}

BOOL CTitleTipListBox::PreTranslateMessage(MSG* pMsg) {

 switch (pMsg->message) {

 case WM_RBUTTONDOWN:

 case WM_RBUTTONUP:

 case WM_LBUTTONDBLCLK:

 case WM_RBUTTONDBLCLK:

 // Активизировать окно представления, потому что такое

 // поведение подразумевается по сообщению WM_MOUSEACTIVATE,

 // когда над окном нет никаких подсказок.

AdjustTitleTip(m_nNoIndex);

CFrameWnd* pFrameWnd = GetParentFrame;

if (pFrameWnd) {

BOOL bDone = FALSE;

CWnd* pWnd = this;

while (!bDone) {

pWnd = pWnd->GetParent;

if (!pWnd || pWnd == pFrameWnd) {

bDone = TRUE;

}

else if (pWnd->IsKindOf(RUNTIME_CLASS(CView))) {

pFrameWnd->SetActiveView((CView*)pWnd);

bDone = TRUE;

}

}

}

break;

 }

 return CListBox::PreTranslateMessage(pMsg);

}

Функция CTitleTipListBox::GetIdealItemRect вычисляет размер и координаты идеальной строки списка. Параметр nIndex – это индекс нужной строки. Параметр lpRect используется для того, чтобы вернуть идеальный размер

и координаты в клиентской системе координат. Вы должны переопределить этот метод для элемента "список" с пользовательской отрисовкой, и далее я покажу, как с этим справляется CODListBox. Если не переопределить этот метод для элемента "список" с пользовательской отрисовкой, то метод CTitleTipListBox::GetIdealItemRect выдаст TRACE-сообщение об ошибке. Однако для обычных элементов "список" этот метод автоматически вычисляет размер и координаты идеальной строки списка. Сначала он вызывает функцию CListBox::GetItemRect для вычисления высоты и ширины строки. Ширина строки, возвращенная CListBox::GetItemRect является шириной самого элемента "список", а не шириной текста. Чтобы вычислить настоящую ширину текста подсказки, я получаю текст и шрифт для строки и вызываю CDC::GetTextExtent. Затем в lpRect подставляется максимум от ширины строки и вычисленной ширины строки (плюс немного места по краям из эстетических соображений).

Функция CTitleTipListBox::AdjustTitleTip показывает или прячет элемент TitleTip. Параметр nNewIndex является индексом строки для отображения. Он может принимать значение константы m_nNoIndex, если подсказка не нужна ни для одной строки. Функция создает элемент ToolTip, если он еще не создан. Если в качестве индекса строки передается m_nNoIndex, функция прячет текущую подсказку. В противном случае функция получает размеры идеальной строки вызовом CTitleTipListBox::GetIdealItemRect. Если размеры идеальной строки совпадают с размерами, возвращенными функцией CListBox::GetItemRect, то в подсказке нет необходимости, и подсказка прячется. Если размеры отличаются, то функция изменяет размеры идеальной строки таким образом, чтобы она поместилась на экране и показывает подсказку. Если элемент TitleTip видима, делается захват мыши, чтобы узнать момент, когда подсказку следует скрыть. Другими словами, если курсор мыши не находится ни над одной строкой, функция должна скрыть подсказку; если элемент TitleTip невидим, то функция освобождает мышь. Для захвата курсора мыши используется функция CTitleTipListBox::CaptureMouse. Она сохраняет позицию курсора в клиентской системе координат в переменной CTitleTipListBox::m_LastMouseMovePoint, а также устанавливает флаг m_bMouseCaptured в значение TRUE для индикации того, что курсор мыши теперь захвачен.

Метод CTitleTipListBox::IsAppActive возвращает TRUE, если приложение, в котором находится элемент "список", активно. Активность приложения определяется получением активного окна и проверкой, является ли оно окном верхнего уровня приложения (или одним из его дочерних окон). Этот метод используется в CTitleTipListBox::OnMouseMove для того, чтобы удостовериться, что подсказка отображается только при активном приложении.

CTitleTipListBox::OnContentChanged прячет подсказку и вызывается по наступлению различных событий, которые могут изменить содержимое элемента "список". Например, сообщение LB_INSERTSTRING, которое вставляет строку в список, может сделать подсказку неактуальной, потому что после вставки курсор мыши может оказаться над совсем другой строкой. Список таких событий можно увидеть в карте сообщений (message map) по макросам ON_MESSAGE. Вы спросите, почему я не использовал CWnd::PreTranslateMessage для перехвата этих сообщений? Честно говоря, я пытался так и сделать, но CWnd::PreTranslateMessage перехватывает только сообщения из очереди сообщений, а интересующие нас сообщения являются результатом вызова самой Windows функции SendMessage, которая минует очередь сообщений.

CTitleTipListBox::OnMouseMove проверяет, не попадает ли курсор мыши на какую-нибудь строку, чтобы показать подсказку для этой строки. Эта проверка осуществляется только когда приложение с элементом "список" активно и курсор мыши действительно изменил свое положение. Я выяснил, что Windows иногда посылает несколько сообщений WM_MOUSEMOVE для одной и той же позиции курсора, поэтому я использую переменную m_LastMouseMovePosition для фильтрации этих лишних сообщений. Далее CTitleTipListBox::OnMouseMove проверяет, находится ли курсор мыши в клиентской области списка. Курсор вполне может оказаться за пределами клиентской области из-за захвата курсора мыши. Забавный побочный эффект наблюдается, если не делать такой проверки – подсказка может появиться для строк, невидимых в списке в данный момент. Если же курсор мыши находится в клиентской области списка, CTitleTipListBox::OnMouseMove проходит по списку и выясняет, над какой именно строкой находится курсор. Если это так, функция использует этот индекс для передачи CTitleTipListBox::AdjustTitleTip.

Поделиться:
Популярные книги

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Привет из Загса. Милый, ты не потерял кольцо?

Лисавчук Елена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Привет из Загса. Милый, ты не потерял кольцо?

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

У врага за пазухой

Коваленко Марья Сергеевна
5. Оголенные чувства
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
У врага за пазухой

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит