2016-04-06 5 views
0

Ich versuche OnToolTipNotify zu überschreiben, damit die CListCtrl Tooltips mit mehr als 80 Zeichen unterstützt. Ich möchte, dass die Tooltips für bestimmte Zellen angezeigt werden. Ich habe eine Reihe von Posts gesehen, die mir dabei geholfen haben, aber keiner hat mir völlig geholfen, den besten Weg zu verstehen, dies zu tun. Hier ist, was ich bisher habe, aber ich bin besorgt mit dem breiten Zeichencode, der T2W verwendet. Ich habe gelesen, dass T2W Speicher aus dem Stack verwendet und wenn die Funktion zurückkehrt, wird es aufgeräumt. Also wird lpszText ungültig. Dies scheint jedoch zu funktionieren und ich kann keinen anderen Weg finden, es zu tun.MFC CListCtrl OnToolTipNotify

BOOL CListCtrlEx::OnToolTipNotify(UINT tooldId, NMHDR* notifMsg, LRESULT result) 
{ 
    USES_CONVERSION; 
    TOOLTIPTEXTA* tttA = reinterpret_cast<TOOLTIPTEXTA*>(notifMsg); 
    TOOLTIPTEXTW* tttW = reinterpret_cast<TOOLTIPTEXTW*>(notifMsg); 
    ... 
    int row, col; 
    cellHitTest(row, col); 
    CString tipStr; 

    // Note getTooltip() returns const ref to cell's tooltip string 
    if (-1 < row && -1 < col) 
     tipStr = m_Data[row]->colvals[col]->getTooltip(); 

    if (tipStr.IsEmpty()) return FALSE; 

    if (TTN_NEEDTEXTA == notifMsg->code) 
    { 
     tttA->lpszText = tipStr.GetBuffer(); 
     tttA->hinst = 0; 
    } 
    else 
    { 
     // Question: Is this a problem? Will the buffer pointed to 
     // by tttW->lpszText be deleted after this function ends 
     // making the pointer invalid? 
     tttW->lpszText = T2W(tipStr.GetBuffer()); 
     tttW->hinst = 0; 
    } 

    ... 
} 
+0

Ich verwendete 'ON_NOTIFY_REFLECT (LVN_GETINFOTIP, OnGetInfoTip)' und 'void CMyListCtrlEx :: OnGetInfoTip (NMHDR * pNMHDR, LRESULT * pResult)' – sergiol

Antwort

0

Ich habe versucht, Ihre Frage mit meinen besten Bemühungen zu verstehen. Alles, was Sie sagen, dass CString kann verwendet werden, aber die breite Konvertierung kann nicht direkt ohne T2W Conversion-Makro verwendet werden. Wenn das die Frage ist, können Sie CStringW einfach verwenden - tipStr einer Variablen dieses Typs zuweisen und es an lpszText übergeben.

Aber ich sehe Problem mit Ihrem Code - Sie gehen davon aus, dass, wenn code nicht TTN_NEEDTEXTA ist, muss es TTN_NEEDTEXTW sein - diese Annahme ist falsch.

EDIT: From this article, ich fand heraus, dass Sie es dynamisch zuordnen müssen. Hoffe das hilft!

Bei Verwendung der TTN_NEEDTEXT Nachrichtenhandler und man will Tooltip länger als 80 Zeichen angezeigt werden, dann muss man das wollte Textpuffer zuweisen und stellen Sie den TOOLTIPTEXT :: lpszText Zeiger auf diesen Text-Puffer in der Nachricht Handler (man hat diesen Text Puffer manuell freigeben):

+0

Das war keine Hilfe. Was Sie sagen, ist ein Problem in meinem Code ähnelt MSDN-Dokumentation - https://msdn.microsoft.com/en-us/library/sa23xxsww.aspx. Beachten Sie, dass das Beispiel szText verwendet, das die 80-Zeichen-Grenze hat. Ich versuche, lpszText zu verwenden, um Tooltips größer als 80 Zeichen zu erlauben. – user2971092

+0

Bearbeitete die Antwort. Ich sehe, dass 'tagNMTTDISPINFOW :: szText' definiert ist, um' 80' Größe Array zu sein/ – Ajay

+0

Ich habe diesen Artikel gesehen, aber nicht verstehen, wann/wo/wie den Text-Puffer freigeben. Gibt es einen weiteren Rückruf, wenn die QuickInfo-Nachricht verschwindet und ich die Zuordnung rückgängig machen kann? Ich nehme an, ich könnte 'tipStr.AllocSysString()' für die Zuordnung in dem obigen Code anstelle von 'T2W' verwenden? – user2971092

0

Dies ist der Code, den ich verwenden: Tiptext ist der CString mit dem Text ich m_pchTip und m_pwchTip sind Mitglieder meiner Liste Kontrolle angezeigt werden soll.

if(m_pchTip != NULL) 
    { 
     delete[] m_pchTip; 
     m_pchTip = nullptr; 
    } 

    if(m_pwchTip != NULL) 
    { 
     delete[] m_pwchTip; 
     m_pwchTip = nullptr; 
    } 

     if(pNMHDR->code == TTN_NEEDTEXTA) 
     { 
      TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; 
      m_pchTip = new char[tiptext.GetLength() + 1]; 
      lstrcpyn(m_pchTip,tiptext,tiptext.GetLength() + 1); 
      m_pchTip[tiptext.GetLength()] = 0; 
      pTTTA->lpszText = m_pchTip; 
     } 
     else 
     { 
      TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; 
      m_pwchTip = new WCHAR[tiptext.GetLength() + 1]; 
      _mbstowcsz(m_pwchTip,tiptext,tiptext.GetLength() + 1); 
      m_pwchTip[tiptext.GetLength()] = 0; 
      pTTTW->lpszText = (WCHAR*)m_pwchTip; 
     } 
+0

Ihre Antwort sieht vielversprechend aus. Ich werde es versuchen. Für den Fall TTN_NEEDTEXTA wäre nicht "pTTTA-> lpszText = tiptext.GetBuffer();" ausreichend? – user2971092

+0

Wenn tiptext den Gültigkeitsbereich verlässt, ist der Zeiger ungültig. – dwo

+0

In meinem Fall ist 'tiptext' ein const ref für das Mitglied der Zelle, also denke ich, dass es in Ordnung sein kann. Aber jetzt stelle ich die Notwendigkeit in Frage, "TTN_NEEDTEXTA" zu unterstützen. 'pNMHDR-> code' entspricht immer 'TTN_NEEDTEXTW' für mich, also bin ich mir nicht sicher, wie ich den' TTN_NEEDTEXTA' Fall sogar testen würde. – user2971092

0

Hier ist, was ich getan habe. Da ich einen Fall in meinen Anwendungen nicht finden konnte, wo ich den TTN_NEEDTEXTA == notifMsg->code Fall behandeln muss, unterstütze ich es nicht. Ich entfernte ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA...) von der Nachrichtenabbildung und in CListCtrlEx::OnToolTipNotify gebe ich FALSE zurück, wenn TTN_NEEDTEXTA == notifMsg->code. Ich werde es wieder besuchen, wenn ich ANSI vs. UNICODE besser verstehe.

In meiner Zellklasse änderte ich das CString tooltip Mitglied zu CStringW als @Ilnspectable vorgeschlagen. Die CListCtrlEx :: OnToolTipNotify Funktion hat Zugriff auf das CStringw-Element der Zelle, so dass ich lpszText = const_cast<LPWSTR>((LPCWSTR)m_Data[row]->colvals[col]->tooltip) festlegte.