CListBox自动换行显示

需要在ListBox控件中显示一些信息。
为方便查看,不使用水平滚动条。当要输出的字符串占用的宽度超过ListBox的宽度时,截断字符串,剩余的在下一行显示。

1. 计算ListBox所占的宽度,用GetClientRect。

GetClientRect返回的是客户区的大小。当ListBox中有垂直滚动条时,那么客户区的大小会相应调整。GetClientRect返回的是去掉滚动条占用区域后剩余的区域,即完全用来显示内容的区域的大小。

2. 计算字符串占用的宽度,用GetTextExtent方法。
一开始计算的不正确,明显比实际占用的值大。
上网查,发现ListBox的ClientDC并没有包含列表框字体信息。也就是说,对话框创建时所使用字体并没有“选入”ClientCD。
要获得字符串真正占用的宽度,应该先调用GetFont获得列表框的字体信息,然后将此字体选入ClientDC中。

例如:
CFont *pFont = m_List1.GetFont();
CDC *pDC = m_List1.GetDC();

CFont *pOldFont = pDC->SelectObject(pFont);

CSize sz = pDC->GetTextExtent(str);

pDC->SelectObject(pOldFont);

 

3. 源码

void ShowInfo(CListBox *pListBox, CString infoStr)
{
    CRect clientRect;
    pListBox->GetClientRect(&clientRect);
    int maxWidth = clientRect.Width();

    int len = infoStr.GetLength();

    CFont *pFont = pListBox->GetFont();
    CDC *pDC = pListBox->GetDC();

    CFont *pOldFont = pDC->SelectObject(pFont);    

    CSize sz = pDC->GetTextExtent(infoStr, len);

    while(sz.cx > maxWidth)
    {
        len--;
        sz = pDC->GetTextExtent(infoStr, len);
    }

    pDC->SelectObject(pOldFont);

    pListBox->AddString(infoStr.Left(len));

    int strLen = infoStr.GetLength();
    if(len != strLen)
    {
        ShowInfo(pListBox, infoStr.Right(strLen - len));
    }
}

 

posted @ 2017-03-03 11:39  小鱼1982  阅读(2783)  评论(0编辑  收藏  举报