Dialog - CToolTipCtrl



  • heiho

    ich hab mit hilfe der MSDN tooltips versucht zu implementieren {in der CChildView klasse}

    class CChildView : public CWnd
    {
    private:
        CToolTipCtrl m_tooltip;
        CButton m_OwnButton;
    ....
    
    CChildView::CChildView()
    {
        m_tooltip.Create(this);
    }
    
    int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
        if (CWnd ::OnCreate(lpCreateStruct) == -1)
            return -1;
    
        ....
        m_OwnButton.Create(csText, CBSTYLES, rect, this, ID_OWNBUTTON);
        ....
        m_NumberFiles.EnableToolTips();
        m_tooltip.AddTool(&m_OwnButton, IDS_ATTACHBACK);
        m_tooltip.Activate(TRUE);
        ....
    

    debugger sagt das alle funktionen immer erfolgreich sind - was mach ich falsch ?
    ich bekomm nie tooltips angezeigt - compiliert alles fehlerfrei und programm laeuft stabil #gruebel



  • // ------------------------------------------------------------------------------------------------
    // Für den Tooltip
    // ------------------------------------------------------------------------------------------------
    BOOL CChildView::PreTranslateMessage(MSG* pMsg) 
    {
    	if (NULL != m_pToolTip)
    	{
    		m_tooltip->RelayEvent(pMsg);
    	}
    
    	return CFormView::PreTranslateMessage(pMsg);
    }
    

    🙂



  • YES - funzt - vielen dank dir {=



  • 1. Der Test NULL!=m_pToolTip ist ungenügend. Wenn der Tooltip aus irgendeinem Grund nicht angelegt wurde, dann schmiert das Programm bei RelayEvent gnadenlos ab.
    Besser

    if (m_pToolTip->GetSafeHwnd()!=NULL...
    

    2. RelayEvent sollte nur für die notwendigen Nachrichten aufgerufen werden!

    WM_LBUTTONDOWN WM_MOUSEMOVE WM_LBUTTONUP WM_RBUTTONDOWN WM_MBUTTONDOWN WM_RBUTTONUP WM_MBUTTONUP

    Also kurzgefasst:

    if (m_pToolTip->GetSafeHwnd()!=NULL && 
        pMsg->message>=WM_MOUSEFIRST && pMsg->message<=WM_MOUSELAST)
        {
            m_tooltip->RelayEvent(pMsg);
        }
    

    oder

    if (m_pToolTip->GetSafeHwnd()!=NULL && 
        (pMsg->message==WM_MOUSEMOVE || 
         pMsg->message==WM_LBUTTONDOWN || 
         pMsg->message==WM_MBUTTONDOWN ||
         pMsg->message==WM_RBUTTONDOWN ||
         pMsg->message==WM_LBUTTONUP ||
         pMsg->message==WM_MBUTTONUP || 
         pMsg->message==WM_RBUTTONUP)) 
        {
            m_tooltip->RelayEvent(pMsg);
        }
    


  • ich hab da noch eine andere frage

    und zwar wuerd ich gern die tooltips auf die statusleiste umleiten {der alte thread hier hilft nicht weiter}

    ich hab das so

    eine eigene klasse abgeleitet von CToolTipCtrl
    da hab ich die methoden
    OnTtnTooltipShow und
    OnTtnTooltipPop

    zudem nimmt die klasse ein zeiger an der auf die statusleiste verweist

    in OnTtnToolTipShow kann ich nu den string in der statusleiste manipulieren
    und da ist die frage - wie kann ich sagen welcher text gezeigt werden soll - {eine ID aus der string table}

    am besten waehre das ich sagen kann das der text genommen werden soll der eh angezeigt wird ueber den "normalen" einblendenden tooltip

    jemand ne idee ?

    (in OnTtnTooltipPop leere ich die statuszeile wieder)



  • Der alte Thread enthält alle Infos: WM_SETMESSAGESTRING und die entsprechende TN! Dort steht alles beschrieben wie man diese Nachricht verwendet!

    Du benötigst übrigens keinen Zeiger auf die Statuszeile, sende die nachricht einfach an AfxGetMainWnd!



  • kaum hab ich gefragt hatte ichs rausgefunden #gg

    void COwnToolTips::OnTtnTooltipShow(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	CString csTip = _T("");
    	GetText(csTip, m_cWnd, pNMHDR->idFrom);
    	m_pStatusBar->SetWindowTextA(csTip);
    	*pResult = 0;
    }
    

    das mit dem zeiger auf die statusleiste werd ich mir mal anschaun - danke



  • AfxGetMainWnd()->SendMessage(WM_SETMESSAGESTRING, NULL, (LPARAM)(LPCTSTR)csTip);
    

    funzt nicht, da WM_SETMESSAGESTRING unbekannt ist



  • Hey, da gibts ja doch noch einen mit der Idee. 👍

    Also, du scheinst ja mein Problem "Über welchem Control bin ich?" gelöst zu haben. (Guck ich gleich in Ruhe nochmal.)

    Ich kriege den Text so in die Statusleiste:

    m_wndStatusBar.SetPaneText(m_wndStatusBar.CommandToIndex(IDS_STATUS_VIEWTEXT), pView->GetTipText());
    

    Der Code steht im CMainFrame. GetTipText gibt einfach nur den anzuzeigenden Text zurück.



  • bei meiner loesung ist es egal ueber welchen objekt man ist - er holt einfach den anzuzeigenden tooltip und zeigt den "zusaetzlich" in der toolbar an

    und da ist mein problem auch - ich weiss nicht wie ich das richtige tooltip weg bekomm #gg

    mit .MoveWindow(0, 0, 1, 1) erscheint nur ein kleiner punkt den man kaum sieht, aber wenn man die maus schneller bewegt flackerts kurz auf, da ist MoveWindow nicht schnell genug #gg

    ne andere idee war das ich in den tooltip nur kurz den namen zeigen lass und in der statusleiste genauere informationen - nur dann ist das problem - woher soll die tooltip klasse wissen welche IDS er anzeigen soll



  • Kannst du nochmal genauer erklären, wie du das mit dem anzuzeigenden Text machst?
    Du hast also deine eigene Tooltipklasse und die gibt den Text wohin?

    Weil ich ja auch fast genau den Ansatz verfolge:

    bei meiner loesung ist es egal ueber welchen objekt man ist - er holt einfach den anzuzeigenden tooltip und zeigt den "zusaetzlich" in der toolbar an

    Nur dass die Statusleiste auch leer sein sollte, wenn die Maus allgemein über der View steht.
    Wäre kein Beinbruch, wenn da was steht, aber unschön.

    PS: Ach, du willst Statusleiste ANSTATT Tooltip? 😮
    Hm, da weiß ich auch nicht so recht... müsste sich in der Tooltipklasse regeln lassen.



  • eigentlich ganz einfach, ich uebergebe das CWnd des fensters und ein pointer zu der statusleiste an die eigene tooltip klasse

    habe dort "OnTtnTooltipShow" und "OnTtnTooltipPop" ueberschrieben

    void COwnToolTips::OnTtnTooltipShow(NMHDR *pNMHDR, LRESULT *pResult)
    {
        if(m_cWnd != NULL && m_pStatusBar != NULL)
        {
            CString csTip = _T("");
            GetText(csTip, m_cWnd, pNMHDR->idFrom); // hole tooltip-text
            m_pStatusBar->SetWindowTextA(csTip);    // setzen diesen text als statustext
        }
    }
    
    void COwnToolTips::OnTtnTooltipPop(NMHDR *pNMHDR, LRESULT *pResult)
    {
        // wenn die maus das objekt verlaesst und das tooltip verschwindet, statusleiste leeren
        if(m_pStatusBar != NULL)
            m_pStatusBar->SetWindowTextA(_T(""));
        *pResult = 0;
    }
    

    in den fenster mit den ganzen elementen einfach das normale

    m_tooltip.AddTool(&m_Button, IDS_TTLIST);
    

    ausgefuehrt

    das alles fuerht dazu das in der statusleiste immer das selbe angezeigt wird wie im tooltip - beides gleichzeitig - erscheint und verschwindet zur selben zeit

    estartu schrieb:

    PS: Ach, du willst Statusleiste ANSTATT Tooltip? 😮
    Hm, da weiß ich auch nicht so recht... müsste sich in der Tooltipklasse regeln lassen.

    da bin ich noch am probieren, aber bisher bekomm ich nichts hin /= - evtl schaffst du das {o;
    meine letzte idee war das ich das tooltip aus den sichtbaren bereich verschiebe - aber da ist MoveWindow nicht schnell genug {bei schnellen mausbewegungen flackerts kurz auf}



  • ah, movewindow geht doch - es flackert nur auf wenn die tooltip box zu klein ist fuer den text

    so gehts

    void COwnToolTips::OnTtnTooltipShow(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	MoveWindow(10000, 10000, 12000, 12000);
    	if(m_cWnd != NULL && m_pStatusBar != NULL)
    	{
    		CString csTip = _T("");
    		GetText(csTip, m_cWnd, pNMHDR->idFrom);
    		m_pStatusBar->SetWindowTextA(csTip);
    	}
    }
    

    man sieht es aber wenn man ein monitor verwendet der mehr als 12000 pixel darstellt #gg

    // dazuedit - wenn man beim aufruf noch

    m_tooltip.SetDelayTime(TTDT_INITIAL, 0);
    

    davorsetzt - erscheint es auch sofort - nu sind alle tooltips in der statusleiste genau wie bei nem menue



  • Kann ich leider frühestens Morgen gucken.
    Mein großer Monitor hat seit einigen Minuten ständig Zuckungen im Bild. Konzentrieren ist da nicht. 😞



  • Mr Evil schrieb:

    man sieht es aber wenn man ein monitor verwendet der mehr als 12000 pixel darstellt #gg

    Dann hol dir doch die Größe des Desktops und rechne dann was drauf und zeig an:

    CClientDC dc(NULL);
    	int nXRes = dc.GetDeviceCaps(HORZRES);
    	int nYRes = dc.GetDeviceCaps(VERTRES);
    

    😉



  • Kannst du bitte mal zeigen, wie das in der MessageMap der Tooltipklasse aussehen muss?
    Was muss da als zweiter Parameter rein?

    ON_NOTIFY(TTN_TOOLTIP_SHOW, /*???*/, OnTtnTooltipShow)
    


  • ich habs automatisch erstellen lassen

    BEGIN_MESSAGE_MAP(COwnToolTips, CToolTipCtrl)
    	ON_NOTIFY_REFLECT(TTN_SHOW, &COwnToolTips::OnTtnTooltipShow)
    	ON_NOTIFY_REFLECT(TTN_POP, &COwnToolTips::OnTtnTooltipPop)
    END_MESSAGE_MAP()
    


  • Moin!

    Danke für die MessageMap, mein Assistent weigert sich leider, irgendwas in der Art zu kennen. 😞

    Mr Evil schrieb:

    // dazuedit - wenn man beim aufruf noch

    m_tooltip.SetDelayTime(TTDT_INITIAL, 0);
    

    davorsetzt - erscheint es auch sofort - nu sind alle tooltips in der statusleiste genau wie bei nem menue

    Super, danke für den Tip. 👍

    Hast du eine Idee, wie man den Tooltip länger anzeigen lassen kann?
    Ich möchte den am liebsten so lange anzeigen lassen, wie der Mauszeiger über dem Control ist - hab aber noch nicht durchschaut, wie ich mit in die Hittest-Funktion einklinken kann.

    Ich hab es dann mal so versucht:

    m_pToolTip->SetDelayTime(TTDT_AUTOPOP, 100000);
    

    Laut MSDN müsste das richtig sein.

    TTDT_AUTOPOP Retrieve the length of time the tool tip window remains visible if the pointer is stationary within a tool's bounding rectangle.



  • estartu schrieb:

    Moin!

    Danke für die MessageMap, mein Assistent weigert sich leider, irgendwas in der Art zu kennen. 😞

    womit compilierst du ?
    das ist bei mir eines der wenigen projekte die ich direkt in 2005 Prof bau

    estartu schrieb:

    Hast du eine Idee, wie man den Tooltip länger anzeigen lassen kann?
    Ich möchte den am liebsten so lange anzeigen lassen, wie der Mauszeiger über dem Control ist - hab aber noch nicht durchschaut, wie ich mit in die Hittest-Funktion einklinken kann.

    Ich hab es dann mal so versucht:

    m_pToolTip->SetDelayTime(TTDT_AUTOPOP, 100000);
    

    Laut MSDN müsste das richtig sein.

    TTDT_AUTOPOP Retrieve the length of time the tool tip window remains visible if the pointer is stationary within a tool's bounding rectangle.

    versuchs mal so:

    m_pToolTip->SetDelayTime(100000)

    das hatte ich am anfang probiert als ich es so einstellen wollte das es sofort erscheint - und festgestellt das das dann die dauer regelt {probiers indem du es auf 10 oder so stellst {bedenke das es in milli sekunden ist}}

    bei mir zeigt das schon immer solange bis die maus aus den bereich raus ist

    //dazuedit, habs grad bei mir mal geschaut, ich hab gemerkt das es bei mir auch nach einer weile verschwindet - hatte nur so lange mit der maus geruht #gg

    es scheint als das es eine maximum possible obergrenze gibt - sobald man ueber ein wert hinaus geht bewirkt es nichts mehr - weniger geht immer #gruebel



  • Ich arbeite mit VC6 und 2003.
    Probiert habe ich es bisher nur mit VC6.

    Trage ich den Code von Hand ein, klappt ja alles. Ich denke mal, dass da wieder irgendwas rumzickt. 🙄


Anmelden zum Antworten