开发者

Can't display Tool Tips in VC++6.0

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 CRect开发者_运维问答Tracker

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;
        }


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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜