Search code examples
mfctooltip

MFC tooltip does not show any text


I've got a project on vs2008 without unicode support and there is no tooltip text showing. I've tried the same code on another project with unicode support and it works alright. What am I doing wrong?

BOOL CListCtrl_ToolTip::OnToolNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
    CPoint pt(GetMessagePos());
    ScreenToClient(&pt);

    int nRow, nCol;
    CellHitTest(pt, nRow, nCol);

    CString tooltip = GetToolTipText(nRow, nCol);
    //MessageBox(tooltip,NULL, MB_OK);
    if (tooltip.IsEmpty())
        return FALSE;

    // Non-unicode applications can receive requests for tooltip-text in unicode
    TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
    TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;

#ifndef _UNICODE
    if (pNMHDR->code == TTN_NEEDTEXTA)

        lstrcpyn(pTTTA->szText, static_cast<LPCTSTR>(tooltip), sizeof(pTTTA->szText));
    else

#else
    if (pNMHDR->code == TTN_NEEDTEXTA)
        _wcstombsz(pTTTA->szText, static_cast<LPCTSTR>(tooltip), sizeof(pTTTA->szText));
    else
        lstrcpyn(pTTTW->szText, static_cast<LPCTSTR>(tooltip), sizeof(pTTTW->szText)/sizeof(WCHAR));
#endif
    // If wanting to display a tooltip which is longer than 80 characters,
    // then one must allocate the needed text-buffer instead of using szText,
    // and point the TOOLTIPTEXT::lpszText to this text-buffer.
    // When doing this, then one is required to release this text-buffer again
    return TRUE;
}

The tooltip string is filled with the needed value but the text doesn't show up. The problem occurs when the pTTW->szText is assigned. I've tried to assign address of my string to lpszText, but the tooltip showed chinese symbols or something.


Solution

  • Probably the listview control is always getting unicode messages for TTN_NEEDTEXT, and it doesn't matter if the project is unicode or ANSI. Therefore you cannot rely on #define UNICODE

    Related issue: TTN_NEEDTEXTA/TTN_NEEDTEXTW

    This should work for both unicode and non-unicode:

    BEGIN_MESSAGE_MAP(TList, CListCtrl)
       ON_NOTIFY_EX(TTN_NEEDTEXTA, 0, OnToolNeedText)
       ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnToolNeedText)
    END_MESSAGE_MAP()
    
    BOOL TList::OnToolNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
    {
       CPoint pt(GetMessagePos()); 
       ScreenToClient(&pt);
    
       int nRow, nCol;
       CellHitTest(pt, nRow, nCol);
       CString tooltip = GetToolTipText(nRow, nCol);
       if (tooltip.IsEmpty())
          return FALSE;
    
       if (pNMHDR->code == TTN_NEEDTEXTW)
       {
          TOOLTIPTEXTW* ttext = (TOOLTIPTEXTW*)pNMHDR;
          CStringW sw(tooltip);
          lstrcpynW(ttext->szText, sw, sizeof(ttext->szText)/sizeof(wchar_t));
       }
       else 
       {
          TOOLTIPTEXTA* ttext = (TOOLTIPTEXTA*)pNMHDR;
          CStringA sa(tooltip);
          lstrcpynA(ttext->szText, sa, sizeof(ttext->szText));
       }
    
       return TRUE;
    }