views:

112

answers:

1

I'm missing something fundamental, and probably both simple and obvious.

My issue: I have a view (CPlaybackView, derived from CView).
The view displays a bunch of objects derived from CRectTracker (CMpRectTracker).
These objects each contain a floating point member.
I want to display that floating point member when the mouse hovers over the CMpRectTracker. The handler method is never executed, although I can trace through OnIntitialUpdate, PreTranslateMessage, and OnMouseMove. This is in Visual C++ v. 6.0.

Here's what I've done to try to accomplish this:

1. In the view's header file:

    public:
        BOOL OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult);

    private:
        CToolTipCtrl m_ToolTip;
        CMpRectTracker *m_pCurrentRectTracker;//Derived from CRectTracker

2. In the view's implementation file:

    a. In Message Map:
        ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTipNeedText)

    b. In CPlaybackView::OnInitialUpdate:
        if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this))
        {
            m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
            m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, SHRT_MAX);
            m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 200);
            m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 200);
        }
        else
        {
            TRACE("Error in creating ToolTip");
        }
        this->EnableToolTips();

    c. In CPlaybackView::OnMouseMove:

        if (::IsWindow(m_ToolTip.m_hWnd))
        {
            m_pCurrentRectTracker = NULL;
            m_ToolTip.Activate(FALSE);
            if(m_rtMilepostRect.HitTest(point) >= 0)
            {
                POSITION pos = pDoc->m_rtMilepostList.GetHeadPosition();
                while(pos)
                {
                    CMpRectTracker tracker = pDoc->m_rtMilepostList.GetNext(pos);
                    if(tracker.HitTest(point) >= 0)
                    {
                        m_pCurrentRectTracker = &tracker;
                        m_ToolTip.Activate(TRUE);
                        break;
                    }
                }
            }
        }

    d. In CPlaybackView::PreTranslateMessage:

        if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd)
        {
            switch(pMsg->message)
            {
            case WM_LBUTTONDOWN:    
            case WM_MOUSEMOVE:
            case WM_LBUTTONUP:    
            case WM_RBUTTONDOWN:
            case WM_MBUTTONDOWN:    
            case WM_RBUTTONUP:
            case WM_MBUTTONUP:
                m_ToolTip.RelayEvent(pMsg);
                break;
            }
        }

    e. Finally, the handler method:

        BOOL CPlaybackView::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
        {
            BOOL bHandledNotify = FALSE;

            CPoint CursorPos;
            VERIFY(::GetCursorPos(&CursorPos));
            ScreenToClient(&CursorPos);

            CRect ClientRect;
            GetClientRect(ClientRect);

            // Make certain that the cursor is in the client rect, because the
            // mainframe also wants these messages to provide tooltips for the
            // toolbar.
            if (ClientRect.PtInRect(CursorPos))
            {
                TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
                CString str;
                str.Format("%f", m_pCurrentRectTracker->GetMilepost());
                ASSERT(str.GetLength() < sizeof(pTTT->szText));
                ::strcpy(pTTT->szText, str);
                bHandledNotify = TRUE;
            }
            return bHandledNotify;
        }
A: 

Got it:

Just to put it to bed, here's the result:

BEGIN_MESSAGE_MAP(CPlaybackView, CThreadView) ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTipNeedText) END_MESSAGE_MAP()

void CPlaybackView::OnInitialUpdate() { if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this)) { m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX); m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, 2000); m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 1); m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 1); m_ToolTip.Activate(FALSE); BOOL ena = EnableToolTips(TRUE); } else { TRACE("Error in creating ToolTip"); } }

void CPlaybackView::OnMouseMove(UINT nFlags, CPoint point) { CPlaybackDoc* pDoc = (CPlaybackDoc*) GetDocument();

if (::IsWindow(m_ToolTip.m_hWnd))
{
    CMpRectTracker *pRectTracker = HitTest(point);
    if(pRectTracker)
    {
        m_ToolTip.Activate(TRUE);
    }
    else
    {
        m_ToolTip.Activate(FALSE);
    }
}

}

BOOL CPlaybackView::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult) { BOOL bHandledNotify = FALSE;

CPoint CursorPos;
VERIFY(::GetCursorPos(&CursorPos));
ScreenToClient(&CursorPos);

CRect MilepostRect;
m_rtMilepostRect.GetTrueRect(MilepostRect);

// Make certain that the cursor is in the client rect, because the
// mainframe also wants these messages to provide tooltips for the
// toolbar.
if(MilepostRect.PtInRect(CursorPos))
{
    TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
    CMpRectTracker *pRectTracker = HitTest(CursorPos);
    if(pRectTracker)
    {
        CString str;
        str.Format("%f", pRectTracker->GetMilepost());
        ASSERT(str.GetLength() < sizeof(pTTT->szText));
        ::strcpy(pTTT->szText, str);
        bHandledNotify = TRUE;
    }
}
return bHandledNotify;

}

BOOL CPlaybackView::PreTranslateMessage(MSG* pMsg) { if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd) { switch(pMsg->message) { case WM_LBUTTONDOWN:
case WM_MOUSEMOVE: case WM_LBUTTONUP:
case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
case WM_RBUTTONUP: case WM_MBUTTONUP: m_ToolTip.RelayEvent(pMsg); break; } } return CView::PreTranslateMessage(pMsg); }

CMpRectTracker* CPlaybackView::HitTest(CPoint &point) { CPlaybackDoc* pDoc = (CPlaybackDoc*) GetDocument(); ASSERT_VALID(pDoc);

CMpRectTracker *pTracker = NULL;
POSITION pos = pDoc->m_rtMilepostList.GetHeadPosition();
while(pos)
{
    CMpRectTracker tracker = pDoc->m_rtMilepostList.GetNext(pos);
    if(tracker.HitTest(point) >= 0)
    {
        m_CurrentRectTracker = tracker;
        pTracker = &m_CurrentRectTracker;
        break;
    }
}
return pTracker;

}

Paul