簡體   English   中英

MFC CListCtrl OnToolTipNotify

[英]MFC CListCtrl OnToolTipNotify

我試圖為CListCtrl覆蓋OnToolTipNotify,以具有支持80個以上字符的工具提示。 我希望工具提示針對特定的單元格出現。 我看過很多與此相關的文章,但是沒有一篇文章可以完全幫助我了解執行此操作的最佳方法。 這是到目前為止的內容,但是我擔心使用T2W的寬字符代碼。 我讀到T2W占用了堆棧的內存,當函數返回時它將被清除。 因此,lpszText將變得無效。 雖然這似乎可行,但我找不到其他方法。

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;
    }

    ...
}

我已盡力了解您的問題。 您只是說可以使用CString ,但是如果沒有T2W轉換宏,則不能直接使用廣泛轉換。 如果這是問題,您可以簡單地使用CStringWtipStr分配給此類型的變量,然后將其傳遞給lpszText

但是,我發現您的代碼有問題-您假設如果code不是TTN_NEEDTEXTA ,它必須是TTN_NEEDTEXTW這個假設是錯誤的。

編輯: 從本文開始 ,我發現您需要動態分配它。 希望這可以幫助!

如果使用TTN_NEEDTEXT消息處理程序,並且想要顯示超過80個字符的工具提示,則必須分配所需的文本緩沖區,並將TOOLTIPTEXT :: lpszText指針設置為消息處理程序中的此文本緩沖區(必須取消分配此文本緩沖區)手動):

這是我使用的代碼:tiptext是包含要顯示的文本的CString,m_pchTip和m_pwchTip是我的列表控件的成員。

    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;
        }

這就是我最終要做的。 由於我在我的應用程序中找不到需要處理TTN_NEEDTEXTA == notifMsg->code case的情況,因此我不支持它。 我從消息映射中刪除了ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA...) ,並且在CListCtrlEx::OnToolTipNotify如果TTN_NEEDTEXTA == notifMsg->code我返回FALSE。 當我更好地理解ANSI與UNICODE時,我將重新審視它。

在我的單元格類中,按照@IInspectable的建議,將CString tooltip成員CStringW為CStringW。 CListCtrlEx :: OnToolTipNotify函數可以訪問單元格的CStringW成員,因此我設置了lpszText = const_cast<LPWSTR>((LPCWSTR)m_Data[row]->colvals[col]->tooltip)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM