如何迭代CListCtrl的元素?

3
简要描述:
我得到了一个CTreectrl类的实例,其中存储对象,当选择一个对象时,相应的列表报告将显示该对象。
我需要调整CListCtrl派生的MyListCtrl类的实例列宽,以便用户可以在不调整列宽的情况下查看该列中的数据。 我的任务方法:
我实现了InitColumnWidth方法,当从树中选择对象时,该方法被调用。
    void COwnListCtrl::InitColumnWidth ( unsigned const * defwidth, BOOL chars )
        {
            /* find the largest string in each column and set column width accordingly
            so that user no longer need to manually adjust columns width */

            RECT r;
            GetClientRect ( & r );
            int* arrOfMaxColumnWidth = new int[NumCol]; // array where max length for columns will be stored
            for (int i = 0; i < NumCol; ++i)
                arrOfMaxColumnWidth[i] = 0; // initialize
            tstring dataInColumn;
            double Scale = ( defwidth && chars ) ? GetCharAveWidth ( * GetFont () ) : ( r.right * 0.01 );
            int numberOfVisitedItems = 0;
            do
            {
                dataInColumn = _T(""); // initialize
                for (int col = 0; col < NumCol; ++col)
                {
                    //DWORD const itemData = this->GetItemData(numberOfVisitedItems);

                    dataInColumn = this->GetSubItemString(this->GetItemData(numberOfVisitedItems), col); 
                /* 1-st varaint returns only first row of the list 
           because GetItemData always returns zero, but I need to visit all rows */
                    dataInColumn = this->GetSubItemString(numberOfVisitedItems, col); 
   /* 2-nd variant, works for most objects from CTreeCtrl, but for a few of them assertion is raised, system reports on the corrupted heap and application terminates*/
                    if (dataInColumn.length() > arrOfMaxColumnWidth[col])
                        arrOfMaxColumnWidth[col] = dataInColumn.length();
                }
                ++numberOfVisitedItems;
            }
            while(dataInColumn.length() != 0); /* do{} while loop is used to get number of rows in the table
                                       as long as an empty string is read, which means that all rows were read*/
            for (int col = 0; col < NumCol; ++col)
                int tmp = ColWidth[col] = arrOfMaxColumnWidth[col] * Scale;
            ColWidth[0] = 100;

Need help!

2个回答

4

使用以下代码替换你的for (int col = 0; col < NumCol; ++col):

for (int col = 0; col < NumCol; ++col)
{
    int len = 0;
    for(int row = 0; this->GetItemCount(); ++row)
    {
        CString item = this->GetItemText(row, col);
        if(item.GetLength() > len) len = item.GetLength();
    }
    if (len > arrOfMaxColumnWidth[col])
        arrOfMaxColumnWidth[col] = len; // should you multiple it to Scale?
}

这不起作用是因为this->GetItemCount()返回0,那可能是那个原因吗? - spin_eight
如果您有一个虚拟列表,您需要调用SetItemCount()方法。 - cha
那么我需要找到添加项目到我的列表的代码片段,并在那里调用SetItemCount(),参数为我要添加的项目数量吗? - spin_eight
不是的。你只需要找到这段代码并检查使用作为行数的全局变量是什么。我敢打赌它会是 NumRow - cha
没有NumRow或任何与之相似的变量,而是找到了插入和修改项目的代码片段,并对其进行了修改,每次插入一个项目时更新项目计数,但这不会影响COwnListCtrl::Insert(DWORD itemData, int pos)函数。 int newItemCount = this->GetItemCount() + 1; this->SetItemCount(newItemCount); /* OK 24.04.2013,最初没有实现,这导致在使用COwnListCtrl时出现了很多错误(例如宽度调整)*/ return InsertItem(LVIF_PARAM, pos, _T(""), 0, 0, 0, itemData); - spin_eight
显示剩余2条评论

1
不需要重新发明轮子。如果您只想调整列的大小以适应文本,请尝试:
for (int i = 0; i < NumCol; ++i)
    ListView_SetColumnWidth( m_hWnd, i, LVSCW_AUTOSIZE );

你应该为最后一列设置 LVSCW_AUTOSIZE_USEHEADER,使其使用剩余空间。 - IInspectable
我想这只是个人口味问题,但我只会在固定宽度的列表控件中这样做,比如在对话框中,而不是在可调整大小的框架中包含的列表视图中。 - Abraxas
真的。再次阅读我的评论,那不是我想要说的。更像是:你可能想考虑在你的答案中提到LVSCW_AUTOSIZE_USEHEADER - IInspectable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接