【问题标题】:How to iterate through elements of CListCtrl?如何遍历 CListCtrl 的元素?
【发布时间】:2013-04-16 19:08:28
【问题描述】:

简要说明:
I got an instance of CTreectrl class where objects are stored, when an object is selected corresponding list report for that object is displayed.
我需要调整从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;

需要帮助!

【问题讨论】:

    标签: c++ mfc clistctrl


    【解决方案1】:

    使用这个(用下面的代码替换你的for (int col = 0; col &lt; 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,可能是这种情况???
    • 如果有虚拟列表,需要调用SetItemCount()方法。
    • 所以我需要找到将项目添加到我的列表的代码 sn-p 并在那里调用 SetItemCount() 参数 == 我要添加的项目数???
    • 并非如此。您只需要找到此代码并检查使用哪些全局变量作为行数。我敢打赌它会是NumRow
    • 不,没有 NumRow 或任何更相似的变量,而是我找到了插入项目的代码 sn-p 并对其进行了修改,每次插入项目时都会更新项目计数,但这不需要效果 int 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,项目数据); }
    【解决方案2】:

    无需重新发明轮子。如果您只想调整列的大小以适应文本,请尝试:

    for (int i = 0; i < NumCol; ++i)
        ListView_SetColumnWidth( m_hWnd, i, LVSCW_AUTOSIZE );
    

    【讨论】:

    • 你应该为最后一列设置LVSCW_AUTOSIZE_USEHEADER,让它使用剩余的空间。
    • 我想这是个人喜好问题,但我只对固定宽度的列表控件(例如在对话框中)这样做,而不是对包含在调整大小框架中的列表视图。
    • 是的。再次阅读我的评论,这不是我想说的。更像:您可能需要考虑在回答中提及LVSCW_AUTOSIZE_USEHEADER
    猜你喜欢
    • 2021-10-04
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多