我写了一个类,继承于CWnd,功能是接收数据画出饼图,现在想实现一个功能就是鼠标停留在饼图某一块时显示相关信息
不知怎么弄 大家帮帮忙啊

解决方案 »

  1.   

    我做过类似的
    就是直接画的
    如果鼠标悬停一段时间就将一个变量置真
    然后OnPaint里
    if(变量)
    {
    //绘制tip
    }
    如果鼠标移动就将其置假
      

  2.   

    那就在OnMouseMove是判断你的鼠标是否在饼图上,如果在饼图上停留一定时间后就用一个窗口显示其信息,并过一段时间后自动关闭这个窗口。
      

  3.   

    谢谢各位啊 
    我要的效果是在饼图中不同的 扇形 内悬停显示不同信息
    我也想过自己建窗口显示,不过还是感觉麻烦
    上网找过ctooltipctrl的资料,有些例子是限制在一个矩形内(大家能详细讲讲这个咋用么),不过我试过不行我尝试过把扇形的问题转化成矩形,都没成功
      

  4.   

    恩 这个知道 我是想知道怎样让ctooltipctrl显示出来 谢谢啦
      

  5.   

    创建一个ctooltipctrl,把你的扇区作为参数调用AddTool()。
      

  6.   


    我用的方法是直接在主绘图窗口的OnPaint里画
    if(变量)
    {
    //绘制tip
    }
    然后控制if里的变量就好了
    真就画、假就不画
      

  7.   

    现在不管是在哪个扇形区域,只要进入这个子窗口就显示信息(先不做显示不同扇形区域的信息)
    我这样这样写的
    类MyPie:public CWnd
    有一个成员变量CToolTipCtrl ctt;
    初始化:
    ctt.Create(this);
    ctt.Activate(TRUE);
    ctt.AddTool(this,TEXT("ttt"));BOOL MyPie::PreTranslateMessage(MSG* pMsg)
    {
    ctt.RelayEvent(pMsg);
    return CWnd::PreTranslateMessage(pMsg);
    }
    这样为什么不行啊  难道要在父窗口写吗 大家帮帮忙
      

  8.   


    你是说自己用DrawText这些api来显示信息吗 我想用那个控件 能否讲解下
      

  9.   

    这个需求用控件恐怕不太合适
    ctooltipctrl是针对控件的提示
    需要有相应控件句柄的
    如果要用它在控件中再分区域
    相当于在一个控件的不同位置设置不同的显示信息
    不过我记得ctooltipctrl的提示信息是一次设置的
    你要想通过ctooltipctrl实现恐怕要重载一下
    而自定义ctooltipctrl要处理非常多的消息才能实现tip的销毁
    也是基于以上原因我当时没有采用这种方法
    不过网上可能有这种方法的例子
    但是就其具体实现来说应该是因人而异
    所以我恐怕爱莫能助了
      

  10.   

    可以把一个控件内不同区域定义为Tool,再加(Add)到TT中去,以前我对TreeCtrl和LstBox编写过。
      

  11.   

    //下面的代码是好多年前的,现在TreeCtrl可以响应各个item的TT
    void CLeftView::PrepareToolRect()
    {
    CMainFrame  *pMain=(CMainFrame*)AfxGetMainWnd();
    if(!pMain)  return;// init
    if(!IsWindow(pMain->m_hWnd)) return;
    //
    CLeftView*  pLeftView=pMain->GetLeftPane(); // tree
    CTreeCtrl&  LeftTree=pLeftView->GetTreeCtrl();
    CToolTipCtrl* pttc=LeftTree.GetToolTips();// the tooltip of the tree
    if(!pttc) return;
    if(!IsWindow(pttc->m_hWnd)) return;
    CRect rc(0,0,0,0);
    LeftTree.GetWindowRect(&rc);// get tree size
    if(rc.bottom==rc.top && rc.left==rc.right) return;// rc=0 
    // item size . do not use GetRootItem()!
    HTREEITEM hTreeItem=LeftTree.GetFirstVisibleItem();
    if(!hTreeItem) return;
    //
    UINT TreeHeight=rc.bottom-rc.top;
    LeftTree.GetItemRect(hTreeItem,&rc,0);// one line 
    UINT height=rc.bottom-rc.top;// item height excludes first top. not+1
    UINT ToolTotal=TreeHeight/height+1; // how many tools
    if(ToolTotal<1) return;
    UINT count=pttc->GetToolCount();
    if (ToolTotal==count-1 && rc.right==ToolsRC[0].right) return; 
    ToolsRC[0]=rc;// save for hit test 
    // delete old
    for (UINT j=0;j<count;j++) pttc->DelTool((CWnd*)&LeftTree,j);
    // create new tools
    for (UINT i=1;i<=ToolTotal;i++)
    {
    pttc->AddTool((CWnd*)&LeftTree,"TOOL",&rc,i); 
    // create tools with increase rect
    ToolsRC[i-1]=rc;// save for hit test 
    rc.top=rc.bottom+1;rc.bottom+=height;
    }

    //
    ////
    void CLeftView::OnSize(UINT nType, int cx, int cy) 

    CTreeView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    // recalculates tool rect
    PrepareToolRect();
    }
    //
    BOOL CLeftView::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message== WM_MOUSEMOVE)
    {
    // CTreeView* LeftView=this->GetLeftPane();
    CTreeCtrl&  LeftTree=this->GetTreeCtrl();
    CToolTipCtrl* pttc=LeftTree.GetToolTips();
    if(pttc)
    {
    CToolInfo toolinfo;
    char text[MAX_PATH];
    char sTips[MAX_PATH];

    CString txt;
    text[0]=0;
    CPoint pt=pMsg->pt;
    UINT     Flag;
    // convert to client 
    ScreenToClient(&pt);
    // convert to tree 
    MapWindowPoints((CWnd*)&LeftTree,&pt,1); // to tree 
    // get tree subitem text
    HTREEITEM hti=LeftTree.HitTest(pt,&Flag);
    if(hti)
    { // get tips
    txt=LeftTree.GetItemText(hti);
    GetLanTip(txt.GetBuffer(4),sTips);
    }
    else
    {// tip=""
    sTips[0]=0;
    }
    int toolNo=MyToolHitTest(ToolsRC,pt);
    pttc->GetToolInfo(toolinfo,(CWnd*)&LeftTree,toolNo);
    if(strcmp(toolinfo.lpszText,sTips)!=0) // if <>
    {
    toolinfo.lpszText=sTips; // new tip 
    pttc->SetToolInfo(&toolinfo); // set new tip
    }
    }
    }

    return CTreeView::PreTranslateMessage(pMsg);
    }
      

  12.   

    //NT下HitTest有问题,用下面代替:
    ////
    UINT CLeftView::MyToolHitTest(CRect * toolsRC,CPoint pt)
    {
    UINT toolNo;
    toolNo=0;
    for (UINT i=0;i<RCtotal;i++) //60
    {
    if(toolsRC[i].PtInRect(pt))
    {
    toolNo=i+1;
    return (toolNo);
    }
    }
    if (i>=RCtotal) toolNo=0 ;/* not hitted */
    return (toolNo);
    }
      

  13.   

    我给你重搞了一个。创建一个基于dlg的工程
    protected:
    HICON m_hIcon;
    CToolTipCtrl m_TT;//类中新成员
    //
    //}}AFX_MSG
    afx_msg  BOOL OnToolTipText(UINT /*id*/, NMHDR * pNMHDR, LRESULT * pResult);
    //
    DECLARE_MESSAGE_MAP()
    //
    //}}AFX_MSG_MAP
    ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTipText) END_MESSAGE_MAP()
    //把dlg分成4个区,在dlg init调一下
    void CPieHasTTDlg::InitTT()
    {
    CRect rect;
    GetClientRect(&rect);
    int nX= rect.Width() / 2;
    int nY= rect.Height() / 2;
    CRect rc1(0,0,nX,nY);
    CRect rc2(nX,0,2*nX,nY);
    CRect rc3(0,nY,nX,2*nY);
    CRect rc4(nX,nY,2*nX,2*nY);

    m_TT.Create(this);
    m_TT.AddTool(this,LPSTR_TEXTCALLBACK,&rc1,1);
    m_TT.AddTool(this,LPSTR_TEXTCALLBACK,&rc2,2);
    m_TT.AddTool(this,LPSTR_TEXTCALLBACK,&rc3,3);
    m_TT.AddTool(this,LPSTR_TEXTCALLBACK,&rc4,4);
    //
    m_TT.Activate(TRUE);
    }
    //处理tip
    BOOL CPieHasTTDlg::OnToolTipText(UINT /*id*/, NMHDR * pNMHDR, LRESULT * pResult)
    {
    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR; 
    UINT nID = pNMHDR->idFrom;
    // idFrom is actually the HWND of the 1000=IDC_TREE
    switch(nID)
    {
    case 1:
    pTTT->lpszText ="1";
    break;
    case 2:
    pTTT->lpszText ="2";
    break;
    case 3:
    pTTT->lpszText ="3";
    break;
    case 4:
    pTTT->lpszText ="4";
    break;
    }
    //
    return FALSE; // we didn't handle the message, let the 
    // framework continue propagating the message
    }
    //需要把WM_MOUSEMOVE中继到TT
    BOOL CPieHasTTDlg::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class

    if((IsWindow(m_hWnd))  && (pMsg->message==WM_MOUSEMOVE)) m_TT.RelayEvent(pMsg);
    return CDialog::PreTranslateMessage(pMsg);
    }
      

  14.   

    把Tool改为一个,就在Pie上,等有了:
    BOOL CPieHasTTDlg::OnToolTipText(UINT /*id*/, NMHDR * pNMHDR, LRESULT * pResult)
    {
    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR; 
    UINT nID = pNMHDR->idFrom;
    char TipNow[80];
    // idFrom is actually the HWND of the 1000=IDC_TREE
    if(nID==1)
    {
    CPoint mouse;
    GetCursorPos(&mouse);
    ScreenToClient(&mouse);
    double dx=mouse.x-m_PieCenter.x;
    double dy=mouse.y-m_PieCenter.y; if(sqrt(dx*dx+dy*dy)<=m_PieRadius)
    {
    double angle=atan(fabs(dy)/fabs(dx))*180.0/3.14156;// < 0 y axis up
    if (dy<0 && dx>0) angle=atan(fabs(dy)/fabs(dx))*180.0/3.14156;
    else if (dy<0 && dx<0) angle=90+atan(fabs(dx)/fabs(dy))*180.0/3.14156;
    else if (dy>0 && dx<0) angle=180+atan(fabs(dy)/fabs(dx))*180.0/3.14156;
    else    angle=270+atan(fabs(dx)/fabs(dy))*180.0/3.14156;
    //
    sprintf(TipNow,"Inside Pie: %d",int(angle/30.0));
    //afxDump << TipNow << "\n";
    pTTT->lpszText = TipNow;
    }
    }
    //
    return FALSE;// we didn't handle the message,
    }
    //good luck