如何将列的宽度调整为CListCtrl中最长字符串的宽度?

时间:2013-05-28 13:44:37

标签: c++ mfc clistctrl device-context

我在尝试:

tstring subItemText;
    CDC* pDc = GetListCtrl().GetDC(); 
    for (int row = GetItemCount() - 1; row >= 0; --row) 
    {
      subItemText = _T("");
      for (int col = 0; col < NumCol; ++col)  
      {
        subItemText = this->GetSubItemString( GetItemData(row), col);
        CSize sz; 
        // get length of the string in logical units, by default 1 unit == 1 pixel, type of font is accounted
        sz = pDc->GetOutputTextExtent(subItemText.c_str());
        if (static_cast<int>(sz.cx) > ColWidth[col])
          ColWidth[col] = sz.cx; 
      }
    } 
    GetListCtrl().ReleaseDC (pDc);
    for (int col = 0; col < NumCol; ++col) 
    {
      SetColumnWidth(col, ColWidth[col]);
    }

结果列的宽度比该列中最大字符串之一大20/30%。 我希望列的宽度等于最大长度的字符串宽度。

提前致谢!

2 个答案:

答案 0 :(得分:3)

这可能是因为您没有在设备上下文中选择正确的字体。试试这个:

    tstring subItemText;
    CDC* pDc = GetListCtrl().GetDC(); 

    CFont *normalfont = GetListCtrl().GetFont() ;
    CFont *oldfont = pDc->SelectObject(normalfont) ;

    for (int row = GetItemCount() - 1; row >= 0; --row) 
    {
      subItemText = _T("");
      for (int col = 0; col < NumCol; ++col)  
      {
        subItemText = this->GetSubItemString( GetItemData(row), col);
        CSize sz; 
        // get length of the string in logical units, by default 1 unit == 1 pixel, type of font is accounted
        sz = pDc->GetOutputTextExtent(subItemText.c_str());
        if (static_cast<int>(sz.cx) > ColWidth[col])
          ColWidth[col] = sz.cx; 
      }
    } 

    pDc->SelectObject(oldfont) ;

    GetListCtrl().ReleaseDC (pDc);
    for (int col = 0; col < NumCol; ++col) 
    {
      SetColumnWidth(col, ColWidth[col]);
    }

答案 1 :(得分:2)

我认为你需要的只是:

SetColumnWidth(col, LVSCW_AUTOSIZE);

在我的项目中,我从CListCtrl派生自己的类并使用以下函数

void CMyListCtrl::AutoSizeColumnWidths()
{
    // size column widths to content
    int nNumColumns = GetHeaderCtrl()->GetItemCount();

    // for all columns ...
    for (int i = 0; i < nColumnCount; i++)
    {
        // find max of content vs header
        SetColumnWidth(i, LVSCW_AUTOSIZE);
        int nColumnWidth = GetColumnWidth(i);
        SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
        int nHeaderWidth = GetColumnWidth(i); 

        // set width to max 
        SetColumnWidth(i, max(nColumnWidth, nHeaderWidth));
    }
    SetRedraw(TRUE);
} 

这可以确保没有内容的列仍然根据标题文本进行调整。