Frage zu CListCtrl-Tooltips
-
sri schrieb:
Dann geh mal vor's Haus und eine Runde durch die Natur. Das hilft.

Da hast du wohl recht, bin aber schon seit heut früh etwas verwirrt !

Egal, also ich hab im View meine Funktion, in der mein ListCtrl fülle. Darin setze ich auch den Text der beiden Tooltips zusammen und übergebe den dem struct, in dem dann am Ende 2 verschiedene CStrings enthalten sind.
Dann erhält lvItem.lParam die Adresse des structs mit den beiden Tooltip-Texten.
Und dann müsste ich mir noch überlegen, wie ich über SetTooltipText dann für jede Zeile die LVITEM-Struktur "speichere".Und das mit dem dynamischen Anlegen versteh ich noch nicht.

Man muss mir normalerweise nicht alles so aus der Nase ziehen !
Ich danke dir schonmal für die Geduld mit mir heute !!!
-
1. Struktur
typedef struct tagTOOLTIPINFO { CString str13; CString str14; } TOOLTIPINFO, *LPTOOLTIPINFO;2. Beim Einfügen in die Liste:
LVITEM lvItem; ... lvItem initialisieren lvItem.lParam = reinterpret_cast<LPARAM>(new TOOLTIPINFO);3. Tooltips setzen (SetTooltipText)
LPTOOLTIPINFO pToolTipInfo = reinterpret_cast<LPTOOLTIPINFO>(GetItemData(nItem)); pToolTipInfo->str13 = ...; pToolTipInfo->str14 = ...;4. Struktur beim Entfernen löschen
void CMyListCtrl::OnLvnDeleteItem(__in LPNMHDR pNMHDR, __out LRESULT* pResult) { LPNMLISTVIEW pNMListView = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); delete reinterpret_cast<LPTOOLTIPINFO>(pNMListView->lParam); }
-
Ok, war wohl etwas langsam, wollte gerade mein jetzige Lösung posten, die so ähnlich aussieht.

Bis auf das Entfernen der struct hab ich das so !
Hätte noch die Frage zum dynamischen Erzeugen gehabt, aber das hat sich ja jetzt erledigt.
Vielen Dank für deine Hilfe und Geduld !!

-
Hi,
habe acuh gerade so dieses Problem, will auch in bestimmten Spalten Tooltips anzeigen und bin auf diesen Fred gestoßen.
Habe ein paar Fragen dazu:
- bei diesem SetToolTipText verstehe ich nicht ganz, wieso da GetItemData verwendet wird !?
- muss dann aber auch beim Setzen SetItemData aufrufen und da was übergeben ?
- habe meine struct in einer anderen Klasse, weiß nicht wie die in einer anderen Klasse dynamisch erzeugen kann !?Verstehe das alles noch nicht so wirklich, vielleicht kann mich jemand aufklären !
-
Also ich kam jetzt erst wieder dazu, meine Lösung (was doch noch keine ist
)in Ruhe anzuschauen und mir ist noch etwas aufgefallen.m_strData.Format("Tip Nr.1"); CToolTip::tagTOOLTIPINFO *tool = new CToolTip::tagTOOLTIPINFO; tool->str1 = m_strData; m_strData.Format("Tip Nr.2"); tool->strFlags = m_strData; lvItem.lParam = reinterpret_cast<LPARAM>(tool); delete tool; tool = 0;Aber wieso ist beim Holen des Tooltips:
LPTOOLTIPINFO pToolTipInfo = reinterpret_cast<LPTOOLTIPINFO>(GetItemData(nItem)); if (nSubItem != 12 || nSubItem != 13 || pToolTipInfo == NULL) return ""; return (nSubItem == 12) ? pToolTipInfo->strTxtNr : pToolTipInfo->strFlags;pToolTipInfo immer 0 ?
Der lParam wird ja gesetzt, über SetItemData ist es das gleiche (einmal probiert)!
SetTooltipText brauch ich ja eig. nicht mehr, da ich dass ja alles gleich beim Erzeugen des Tooltip-Textes selber mache (das in den 1. Code-Tags).
EDIT:
Falls von Interesse:
ich füge so die Items und pro Zeile ein:VITEM lvItem; lvItem.mask = LVIF_TEXT; lvItem.pszText = ""; for (int i = 0; i < m_tool.GetHeaderCtrl()->GetItemCount(); i++) { lvItem.iItem = 0; lvItem.iSubItem = i; m_tool.InsertItem(&lvItem); }und jedes Item erhält den Text dann per SetItemText !
Das alles mit InsertItem, SetItemText, Tooltip-Text setzen... geschieht alles in einer Funktion.
-
delete tool; tool = 0;Das ist suboptimal. 'tool' darf erst gelöscht werden, wenn auch der Eintrag gelöscht wird (normalerweise in LVN_DELETEITEM).
Ansonsten musst Du beim Hinzufügen in LVITEM.mask auch LVIF_PARAM setzen, das hast Du vermutlich vergessen.
-
Sry fürs so späte melden.

Nochmals danke für deine Antwort !!
Ok, hab mir das schon gedacht, aber lieber ein delete zuviel als zu wenig.
Also kann ich den Pointer auf den struct als Member anlegen, leg den dann einmal pro Programmstart per new an und dann beim Beenden der Applikation wirds per delete entsorgt.
Setze also in meiner Funktion immer nur die beiden Strings neu und übergebe das dann lvItem.lParam !
Und das Flag LVIF_PARAM hatte ich auch noch nicht !SetTooltipText brauch ich ja eigentlich auch nicht, wenn ich schon den lParam setze ??
-
Ich hätte nicht gedacht, dass das hier so komplex wird.
Kann das Projekt jetzt weitermachen, aber beim Holen des Textes für den Tooltip (GetToolTipText) ist pToolTipInfo immer noch 0:const CString CToolTip::GetToolTipText(UINT nItem, UINT nSubItem) { if (nItem < 0 || nItem > 60) return ""; ToolTipText *pToolTipInfo = reinterpret_cast<ToolTipText*>(GetItemData(nItem)); if (!pToolTipInfo) return ""; if (nSubItem != 12 || nSubItem != 13 || pToolTipInfo == NULL) return ""; return (nSubItem == 12) ? pToolTipInfo->strTxtNr : pToolTipInfo->strFlags; }Und das Füllen des Controls sieht so aus:
void C...View::FillListCtrl() { LVITEM lvItem; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.pszText = ""; for (int i = 0; i < m_tool.GetHeaderCtrl()->GetItemCount(); i++) { lvItem.iItem = 0; lvItem.iSubItem = i; m_tool.InsertItem(&lvItem); } ... ToolText *pText = new ToolText; m_strData.Format("Text Nr. %i", cnt); pText->strTxtNr = m_strData; m_strData.Format("Text Nr. %i", cnt); pText->strFlags = m_strData; lvItem.lParam = reinterpret_cast<LPARAM>(pText); ... }Mal davon abgesehen, dass ich in FillListCtrl durch das dauernde Anfordern Mem-Leaks kriege (was hier auch nur zum Test ist), kann ich es einfach nicht verstehen, wieso bei GetToolTipText pToolTipInfo immer 0 ist !
Und bei
void CToolTip::OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); delete reinterpret_cast<ToolTipText*>(pNMLV->lParam); *pResult = 0; }kriege ich ne Exception, weil lParam ungültig ist.
Aber das Setzen des lParams in FillListCtrl ist erfolgreich !Irgendwas überseh ich hier, aber was ?
-
Ist m_Tool die Listenansicht? InsertItem sollte nur einmal pro Eintrag aufgerufen werden (also pro Zeile) und nicht für jede Spalte.
Zudem musst Du lvItem.lParam natürlich auch vor dem entsprechenden InsertItem initialisieren und setzen. Im Nachhinein geht es nur über ein SetItemData.
-
Habe es grad mit SetItemData probiert (was eig auch nix anderes tut) und da funktioniert es.
So ist es, m_tool ist eine Instanz von der Klasse CToolTip, die public von CListCtrl erbt.
Ja, das stimmt natürlich, dass ich erst den lParam setzen muss, bevor ich InsertItem aufrufe!
War irgendwie klar, dass es eine einfache Sache war.Fakt ist: jetzt funktioniert es endlich !!

Ich danke dir vielmals für deine super, hilfreiche und dauernd verfügbare Hilfe !

Noch nen schönen Tag.