ListCtrl und Tooltip bei bestimmten Eintrag



  • Hey,

    ich habe ne MDI-Anwendung mit nem ListCtrl drauf und will, dass ich ein Tooltip angezeigt bekomme, wenn ich z.B. in der 4. Spalte auf einen Eintrag mit der Maus zeige.
    Will das deshalb, weil es zuviel Infos sind, um sie komplett in einer Spalte anzuzeigen.
    Kann mir da jemand helfen ??

    Und noch ein frohes neues Jahr !!
    Thx schonmal !



  • hat da jemand ne Idee ?? 😮



  • Schaust du hier:

    http://www.codeproject.com/KB/list/ctooltiplistctrl.aspx

    viel Spass

    Gruß Matthias



  • es tut mir ja leid, aber irgendwie versteh ich diese Beschreibung nicht


  • Mod

    Und was verstehst Du nicht?



  • das Ganze 🙂
    ist es so umständlich, ein Tooltip zu einem bestimmten Item im ListCtrl anzuzeigen ?
    verstehe die vielen Funktionen nicht, die da verwendet werden

    hatte eigentlich gedacht, dass es einfacher möglich wäre

    hätte mir auch gerne das Demo-Projekt angesehen, da würde ich es besser verstehen, aber das gibts ja nicht (mehr)


  • Mod

    Du bekommst eine Nachricht, die den Tooltip anfragt...
    Das ist gar nicht sachwer!

    Versuch es zu verstehen und stelle detailierte Fragen!



  • OK, also ich versteh erstmal nicht, für was der Autor DeleteItems usw. braucht !?

    SetItemToolTipText sagt es ja schon, GetItemToolTipText auch, aber für was brauche ich SetToolTipHitMask ?? 😕

    und ich müsste die WM_NOTIFY Message abfangen bzw. WM_NOTIFY_EX_RANGE !?
    Habe mir dazu noch http://www.codeguru.com/cpp/controls/listview/tooltiptitletip/article.php/c909/ angeschaut, was ich (teilweise) etwas besser verstehe. 🙂
    nur funktioniert das nicht bei mir, weiß noch nicht, wo mein Fehler liegt

    bin bei diesem Thema ziemlich schwer von Begriff 🙂



  • Ich muss mich nochmal melden 🙂
    Habe jetzt wieder dafür Zeit gefunden und nach einigen Code-Project Seiten habe ich es so gelöst:
    - habe mir eine OnInfoTip-Funktion erstellt

    void CTestDlg::OnInfoTip(NMHDR* pNMHDR, LRESULT* pResult) {}
    

    - habe in der Messagemap WM-NOTIFY mit meiner Funktion verknüpft
    - erstelle dann 2 Spalten mit je einem Item in OnInitDialog (habe jetzt erstmal ein Test-Projekt)

    Ich kriege aber immer nur ein Tooltip für das erste Item in der ersten Spalte, ich weiß noch nicht, wie ich einem SubItem einen lParam zuordnen kann, bei dem ersten Item nehm ich dazu ja SetItemData.

    Ich werte ja in einer switch den lParam der Items aus (den ich ja vorher mit SetItemData gesetzt hab), nur weiß ich eben nicht, wie das für SubItems geht !

    Wäre fein, wenn mir nochmal jemand helfen könnte !
    Danke schonmal ! 😉



  • hat jemand einen Vorschlag ?


  • Mod

    1. Gibt es GetMessagePos um die aktuelle Cursorposition herauszubekommen.
    2. Gibt es CListCtrl::SubItemHitTest um aus der aktuellen Cursorposition das Subitem zu errechnen.

    Das steht alles in dem ersten Sample drin, das CTecS genannt hat.



  • OK, danke, hab das total übersehen !
    Werde mich nochmal melden ! 🙂



  • gut, funktioniert alles, habe die Klasse (aus dem Link von CTecS) in meinem Test-Projekt verwendet und bin jetzt dabei, alles zu verstehen !

    Du bekommst eine Nachricht, die den Tooltip anfragt...
    Das ist gar nicht sachwer!

    hattest vollkommen Recht, habe bloß etwas mehr Zeit gebraucht 🙂

    Tausend Dank für die Unterstützung !!



  • Hi,

    bei mir funktioniert alles wie es soll, der Tooltip ist auch multiline.
    Ich habe da aber noch eine kleine Frage zum Thema:
    im Sample in der Metode OnToolTipText würde ich gerne wissen wollen, was der LRESULT Pointer pResult für einen Sinn hat und wieso der dann auf 0 gesetzt wird ??

    Wenn die Methode aufgerufen wird, steht da ja soweiso 0 drin !
    Danke für die Hilfe schonmal im Voraus. 😉


  • Mod

    1. Ist es ein [out] Übergabe-Parameter, selbst wenn 0 drin steht.
    2. Ist es der Returncode von WM_NOTIFY für für jeden Notify Code steht in der Doku, was man zurückgeben soll. Im Zweifel 0!

    MSDN Lesen bildet ungemein... 🕶



  • Alles klar, vielen Dank

    Martin Richter schrieb:

    MSDN Lesen bildet ungemein... 🕶

    Das tue ich auch immer, nur war ich diesesmal anscheinend zu blöd dafür ! 👍



  • Ich muss mich doch nochmal zum diesem Thema melden. 🙂
    Das mit dem Tooltip anzeigen klappt ja, nur im Release wird der Tooltip nicht korrekt angezeigt, manchmal nur 5 Zeilen von den 8; meistens gibts die eigenartigen Vierecke in der ersten Zeile des Tips, der Rest stimmt.

    Tritt aber nur im Release auf, im Debug stimmt alles ! 😕
    Hier der Code der beiden Funktionen zum Anzeigen des Tips:

    BEGIN_MESSAGE_MAP(CToolTip, CListCtrl)
    	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
    END_MESSAGE_MAP()
    
    // für Mouse-Movement und um Item zu erhalten, auf welches Maus zeigt; wird bei jedem Mousemove aufgerufen
    int CToolTip::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
    {
    	LVHITTESTINFO lvhitTestInfo;
    	lvhitTestInfo.pt = point;
    
    	int nItem = ListView_SubItemHitTest(this->m_hWnd, &lvhitTestInfo);
    	int nSubItem = lvhitTestInfo.iSubItem;
    	TRACE("nItem: %i\n", nItem);
    	TRACE("nSubItem: %i\n", nSubItem);
    	if (lvhitTestInfo.flags == 4 && nSubItem == 11 && (nItem == 0 || nItem == 1 || nItem == 2 || nItem == 3 || nItem == 4
    		|| nItem == 5 || nItem == 6 || nItem == 7 || nItem == 8))
    	{
    		RECT rcClient;
    		GetClientRect(&rcClient);
    		pTI->hwnd = m_hWnd;
    		pTI->uId = (UINT)(nItem * 100 + nSubItem);
    		pTI->lpszText = LPSTR_TEXTCALLBACK;			// sendet TTN_GETDISPINFO message an Owner-Window um Text zu erhalten
    		pTI->rect = rcClient;
    		return (int)pTI->uId;	// eindeutigen Wert zurückgeben, um sicher zu sein, dass bei Mouseover auf anderes Item anderer Tooltip gezeigt wird
    	}
    	else     
    		return -1;
    }
    
    // um Text für Tooltip zu holen
    BOOL CToolTip::OnToolTipText(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
    {
    	TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
    	*pResult = 0;
    	// Mausposition holen
    	CPoint point;
    	GetCursorPos(&point);
    	ScreenToClient(&point);		// Mauskoordinaten in Client-Koordinaten umrechnen
    
    	LVHITTESTINFO lvhitTestInfo;
    	lvhitTestInfo.pt = point;
    
    	int nItem = SubItemHitTest(&lvhitTestInfo);
    	int nSubItem = lvhitTestInfo.iSubItem;
    	if(lvhitTestInfo.flags == 4 && LVHT_ONITEMLABEL)
    	{
    		CString key, strText;
    		key.Format("%i", nItem + nSubItem);
    		if (TextFlags.Lookup(key, strText))
    		{
    			::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, strText.GetLength());	// multiline 
    			USES_CONVERSION;
    			LPWSTR newStr = A2W(strText);
    			pTTTW->lpszText = newStr;
    			return FALSE;
    		}
    	}
    	return FALSE;
    }
    

    TextFlags ist eine CMapStringToString und wird damit gefüllt:

    // Tooltip-Text für bestimmtes Item setzen
    BOOL CToolTip::SetToolTipText(int Item, int SubItem, CString strToolTipText)
    {
    	CString key;
    	key.Format("%i", Item + SubItem);
    	TextFlags.SetAt(key, strToolTipText);
    	return TRUE;
    }
    

    z.B. so:

    m_tool.SetItemText(0, 11, "8");
    

    m_tool ist Ctrl-Variable meines Listcontrols

    Verstehe nicht ganz, wo hier noch ein Fehler liegt, meine Anwendung hat (zwangsweise) MBCS, keine Unicode !
    Vllt gibts ja nochmal Hilfe dazu !??


Log in to reply