Search code examples
c++mfctooltiplistcontrol

How to get multiline tooltip for a list control on a dialog box?


As text on my list box is very huge I am trying to get multiline a tooltip on the list control.

BOOL CTestDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    mylist.EnableToolTips(TRUE);
    mylist.SetExtendedStyle(LVS_EX_INFOTIP | mylist.GetExtendedStyle());

    mylist.InsertColumn(0, L"suri", LVCFMT_LEFT, 10000);
    CString str1 = L"nonNegativeInteger GetVehicleOwnerHolderByRegNumAndDateResponse.GetVehicleOwnerHolderByRegNumAndDateResult[optional].GetVehicleOwnerHolderByRegNumAndDateResultType.VHOwnerHolderResponse.VHOwnerHolderResponseType.Body.VehicleCountries.VehicleCountriesType.VehicleCountry[1, unbound].VehicleCountryType.VehCountryReplies.VehCountryRepliesType.VehCountryReply[1, unbound].Messages[optional].Message[1, unbound].MessageType.MessageCode"; 
    for (int i = 0; i < 20 ; i++) {
        CString str2;
        str2.Format(L"%d",i);
        str2 = str2 + str1;
        mylist.InsertItem(LVIF_TEXT | LVIF_PARAM, i, str2, 0, 0, 0, NULL);
    }

    return TRUE;  // return TRUE  unless you set the focus to a control
}

I am getting following output which is truncated text i.e complete text is missing. enter image description here

How to get text on tooltip multiline?

EDIT: I used following also. still same result.

CToolTipCtrl* pToolTip = AfxGetModuleThreadState()->m_pToolTip;
   if (pToolTip)
      pToolTip->SetMaxTipWidth(SHRT_MAX);

Solution

  • You can get multi-line tooltips using newlines-charecters with SetMaxTipWidth() set to a large value. And if calling SetMaxTipWidth() with a small value, then it will automatically break into multiple lines when meeting a space-character.

    You need to subclass your tooltip/infotip in order to use it:

    BEGIN_MESSAGE_MAP(CListCtrl_InfoTip, CListCtrl)
        ON_NOTIFY_REFLECT_EX(LVN_GETINFOTIP, OnGetInfoTip)
        ON_NOTIFY_EX(TTN_NEEDTEXTA, 0, OnToolNeedText)
        ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnToolNeedText)
    END_MESSAGE_MAP()
    
    void CListCtrl_InfoTip::PreSubclassWindow()
    {
        CListCtrl::PreSubclassWindow();
        SetExtendedStyle(LVS_EX_INFOTIP | GetExtendedStyle());
    }
    
    BOOL CListCtrl_InfoTip::OnGetInfoTip(NMHDR* pNMHDR, LRESULT* pResult)
    {
        // Will only request tooltip for the label-column
        NMLVGETINFOTIP* pInfoTip = (NMLVGETINFOTIP*)pNMHDR;
        CString tooltip = GetToolTipText(pInfoTip->iItem, pInfoTip->iSubItem);
        if (!tooltip.IsEmpty())
        {
            _tcsncpy(pInfoTip->pszText, static_cast<LPCTSTR>(tooltip), pInfoTip->cchTextMax);
        }
        return FALSE;    // Let parent-dialog get chance
    }
    
    BOOL CListCtrl_InfoTip::OnToolNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
    {
    ...
       // Break tooltip into multiple lines if it contains newlines (\r\n)
       CToolTipCtrl* pToolTip = AfxGetModuleThreadState()->m_pToolTip;
       if (pToolTip)
          pToolTip->SetMaxTipWidth(SHRT_MAX);
    ...
    }