Исчерпывающее руководство по написанию всплывающих подсказок | страница 19
> CString strItem;
> GetText(nIndex, strItem);
> if (!strItem.IsEmpty()) {
> // Вычислить длину идеального текста.
> CClientDC DC(this);
> CFont* pOldFont = DC.SelectObject(GetFont());
> CSize ItemSize = DC.GetTextExtent(strItem);
> DC.SelectObject(pOldFont);
> // Взять максимум от обычной ширины и идеальной ширины.
> const int cxEdgeSpace = 2;
> lpRect->right = max(lpRect->right, lpRect->left + ItemSize.cx + (cxEdgeSpace * 2));
> }
> } else {
> TRACE("Owner-draw listbox detected – override CTitleTipListBox::GetIdeaItemRect()\n");
> }
> return nStatus;
>}
>void CTitleTipListBox::AdjustTitleTip(int nNewIndex) {
> if (!::IsWindow(m_TitleTip.m_hWnd)) {
> VERIFY(m_TitleTip.Create(this));
> }
> if (nNewIndex == m_nNoIndex) {
> m_TitleTip.Hide();
> } else {
> CRect IdealItemRect;
> GetIdealItemRect(nNewIndex, IdealItemRect);
> CRect ItemRect;
> GetItemRect(nNewIndex, ItemRect);
> if (ItemRect == IdealItemRect) {
> m_TitleTip.Hide();
> } else {
> // Поправить координаты рядом с краем экрана.
> ClientToScreen(IdealItemRect);
> int nScreenWidth = ::GetSystemMetrics(SM_CXFULLSCREEN);
> if (IdealItemRect.right > nScreenWidth) {
> IdealItemRect.OffsetRect(nScreenWidth – IdealItemRect.right, 0);
> }
> if (IdealItemRect.left < 0) {
> IdealItemRect.OffsetRect(-IdealItemRect.left, 0);
> }
> m_TitleTip.Show(IdealItemRect, nNewIndex);
> }
> }
> if (m_TitleTip.IsWindowVisible()) {
> // Удостовериться, что мышь захвачена, чтобы отследить
> // момент отключения подсказки.
> if (!m_bMouseCaptured && GetCapture() != this) {
> CaptureMouse();
> }
> } else {
> // Подсказка невидима, поэтому освободить мышь.
> if (m_bMouseCaptured) {
> VERIFY(ReleaseCapture());
> m_bMouseCaptured = FALSE;
> }
> }
>}
>void CTitleTipListBox::CaptureMouse() {
> ASSERT(!m_bMouseCaptured);
> CPoint Point;
> VERIFY(GetCursorPos(&Point));
> ScreenToClient(&Point);
> m_LastMouseMovePoint = Point;
> SetCapture();
> m_bMouseCaptured = TRUE;
>}
>/////////////////////////////////////////////////////////////////////////////
>// CTitleTipListBox message handlers
>LONG CTitleTipListBox::OnContentChanged(UINT, LONG) {
> // Turn off title tip.
> AdjustTitleTip(m_nNoIndex);
> return Default();
>}
>void CTitleTipListBox::OnMouseMove(UINT nFlags, CPoint point) {
> if (point != m_LastMouseMovePoint && IsAppActive()) {
> m_LastMouseMovePoint = point;
> int nIndexHit = m_nNoIndex;
> CRect ClientRect;
> GetClientRect(ClientRect);
> if (ClientRect.PtInRect(point)) {
> // Hit test.
> for (int n = 0; nIndexHit == m_nNoIndex && n < GetCount(); n++) {