在MFC中使用CListCtrl,实现每行的行高不同

在MFC程序中,其实根据系统提供,只能将每行的高度设置成相同的。但是在实际工程中,有时需要设置不同的行高,但是又保证该控


件的使用和系统提供的相似。我觉得很难。
我也曾在网上找过相关的资料,但是都是只有提问者,回答者几乎没有。
但是我的工程中需要有这样的功能时,我便自己重写继承了下CListCtrl类,在外部使用的时候与CListCtrl控件的功能相同,只是在内


部重绘的时候修改了下绘制思路就可以了。但是现在有个问题,并且知道是哪错了,但是没有时间修改,不过行高不同的功能已经实现


了。大家可以帮我修改下。
其实,代码不重要,重要的是如何绘制的思路。


控件功能:
我的控件只要实现的是,只要在插入的数据中有'\n'等换行标识时,就让该行的高度增加。
绘图的思路:
在外部插入的时候与原来使用相同,但是在InsertItemText和SetItemText,解析插入的数据中有多少个'\n',将一个拆分成多个保存


起来。把这些拆分的字符串又当成一个一个的数据,继续使用InsertItemText和SetItemText插入。
例如:一个字符串为:m_list.InsertItemText(0,_T("这只是\n一个简单的例子\n举例说明\n是如何使用的"));
其中有3个换行符,我可以将这个字符串拆分成4段。再分别使用InsertItemText插入这4个字符串。
  CListCtrl::InserItem(0,_T("这只是"));
CListCtrl::InserItem(1,_T("一个简单的例子"));
CListCtrl::InserItem(2,_T("举例说明"));
CListCtrl::InserItem(3,_T("是如何使用的"));

此时,0、1、2、3是外部0的子集。SetItemText也是如此。

代码操作使用:
1:首先需要使用vector容器保存要修改的变量。
此时,定义一个结构体,保存需要修改的内容

struct Insert_Text   
{  
    int nItem;          //哪一行  
    int Duan_num;       //insert的段数  
    int begin_Datas;    //初始段数的开始  
    int end_Datas;      //到第几行结束  
    CString  insert_Text;   //InsertItem 未分解的字符串  
    int nStats;         //是否被选择的状态  
    DWORD_PTR dwData;   //使用在SetItemData中,相当于定义的别名  
};  

vector<Insert_Text> m_VectorInsert;
2:重写InsertItem、SetItemText这两个函数

int UIChangeListCtrl::InsertItem(_In_ int nItem, _In_z_ LPCTSTR lpszItem)  
{  
    CString str = lpszItem;  
    int size = Decompostion_CStrings(str);  
    Insert_Text it;  
      
    //保存显示的取值范围  
    if (nItem == 0)  
    {  
        it.nItem = nItem;  
        it.Duan_num = size;  
        it.insert_Text = str;  
        it.begin_Datas = 0;  
        it.end_Datas = size-1;  
        it.nStats = 0;  
    }  
    else   
    {  
        it.nStats = 0;  
        it.nItem = nItem;  
        it.Duan_num = size;  
        it.insert_Text = str;  
        int m = m_VectorInsert[nItem-1].end_Datas;  
        it.begin_Datas = m+1;  
        it.end_Datas = it.begin_Datas+size-1;  
    }  
    m_VectorInsert.push_back(it);  
    InPutDatas();  
    return TRUE;  
}  

int UIChangeListCtrl::SetItemText(int nItem,int nSubItem, LPCTSTR lpszText)  
{     
    CString str = lpszText;  
    int size = Decompostion_CStrings(str);  
      
    //判断vector中是否有相同的nItem  
    int vec_size = m_VectorInsert.size();  
    for (int i = 0; i < vec_size;i++)  
    {  
        if (m_VectorInsert[i].nItem == nItem)  
        {  
            //此时判断,无论nSubItem,获取最高的size  
            int max_Duan =  m_VectorInsert[i].Duan_num;  
            max_Duan = max(max_Duan,size);  
            m_VectorInsert[i].Duan_num = max_Duan;  
        }  
    }  
    SetItem_text sit;  
    sit.nItem = nItem;  
    sit.nSubItem = nSubItem;  
    sit.set_Text = lpszText;  
    m_vectorSet.push_back(sit);  
    InPutDatas();  
    return TRUE;  
}  

3:定义InPutDatas重新规划CListCtrl内部插入数据,其实,改变行高这是最关键的部分。表示的可能有些繁琐,凑合着看

//重新规划CListCtrl  
void UIChangeListCtrl::InPutDatas()  
{  
    if (m_VectorInsert.size() ==0)  
    {  
        return;  
    }  
    //1、将所有的InsertItem、SetItemText的内容都存入map,并且当nItem相等时再画出这一行内容  
    int insert_size = m_VectorInsert.size();  
    //2、绘制InsertItem,把不足的begin,end补齐  
    for (int i = 0; i < insert_size;i++)  
    {  
        if (m_VectorInsert[i].nItem == 0)  
        {  
            m_VectorInsert[i].begin_Datas = 0;  
            m_VectorInsert[i].end_Datas   = m_VectorInsert[i].begin_Datas+m_VectorInsert[i].Duan_num-1;  
            continue;  
        }  
        else  
        {  
            //此时的Text_begin 应该是上一个的nItem的Text_end  
            int nItem = m_VectorInsert[i].nItem-1;  
            int LastEnd = m_VectorInsert[nItem].end_Datas;  
            m_VectorInsert[i].begin_Datas = LastEnd+1;  
            m_VectorInsert[i].end_Datas   = m_VectorInsert[i].begin_Datas+m_VectorInsert[i].Duan_num-1;  
        }  
    }  
    //循环解析字符串  
    for (int si = 0;si < m_VectorInsert.size();si++)  
    {  
        //把SetItemData的别名存入里面  
        for(int st = 0; st < m_vectorSave_datas.size();st++)  
        {  
            if (m_vectorSave_datas[st].nItem == m_VectorInsert[si].nItem)  
            {  
                m_VectorInsert[si].dwData = m_vectorSave_datas[st].save_dwData;  
                continue;  
            }  
        }  
        //对于InsetItemText的输入  
        InsetDrawText(si);  
        //SetItemText的解析  
        int set_sizes = m_vectorSet.size();  
        int nItem = m_VectorInsert[si].nItem;  
        CUIntArray SaveSetArray;  
        for (int set = 0; set < m_vectorSet.size();set++)  
        {  
            if (nItem == m_vectorSet[set].nItem)  
            {  
                SaveSetArray.Add(m_vectorSet[set].nSubItem);  
            }  
        }  
        int set_num = SaveSetArray.GetSize();  
        for (int m = 0; m < m_vectorSet.size();m++)  
        {  
            if (m_VectorInsert[si].nItem == m_vectorSet[m].nItem)  
            {  
                for (int snum = 0;snum < set_num;snum++)  
                {  
                    //再判断nSbuItem相等时,取出字符串  
                    if (m_vectorSet[m].nSubItem == (snum+1))  
                    {  
                        CString strSet = m_vectorSet[m].set_Text;  
                        //解析字符串  
                        CStringArray SetItemArray;  
                        int m = 0;  
                        for (CString sItem = strSet.Tokenize(_T("\n"),m);m>= 0;sItem = strSet.Tokenize(_T("\n"),m))  
                        {  
                            SetItemArray.Add(sItem);  
                        }  
                        if (SetItemArray.GetSize() < m_VectorInsert[si].Duan_num)  
                        {  
                            for (int m = SetItemArray.GetSize();m < m_VectorInsert[si].Duan_num;m++)  
                            {  
                                SetItemArray.InsertAt(m,_T(""));  
                            }  
                        }  
                        int begin = m_VectorInsert[si].begin_Datas;  
                        int itext = 0;  
                        ZuoBiao zb;  
                        while(itext< m_VectorInsert[si].Duan_num)  
                        {  
                            if (m_VectorInsert[si].end_Datas)  
                            {  
                                if (m_manySetDraw.size() == 0)  
                                {  
                                    CListCtrl::SetItemText(begin,snum+1,SetItemArray[itext]);  
                                    zb.beginm = begin;  
                                    zb.colum = snum+1;  
                                    m_manySetDraw.push_back(zb);  
                                    CString str = SetItemArray[itext];  
                                    begin++;  
                                    itext++;  
                                }  
                                else if (m_manySetDraw.size() != 0)  
                                {  
                                    for (int j = 0;j < m_manySetDraw.size();j++)  
                                    {  
                                        //如果再次进入循环的begin值和mm_manyDraw中有一个是相同的  
                                        if (m_manySetDraw[j].beginm == begin && m_manySetDraw[j].colum == snum+1)  
                                        {  
                                            begin++;  
                                            itext++;  
                                            continue;  
                                        }  
                                    }  
                                    if (begin <= m_VectorInsert[si].end_Datas)  
                                    {  
                                        CListCtrl::SetItemText(begin,snum+1,SetItemArray[itext]);  
                                        zb.beginm = begin;  
                                        zb.colum = snum+1;  
                                        m_manySetDraw.push_back(zb);  
                                        CString str = SetItemArray[itext];  
                                        begin++;  
                                        itext++;  
                                    }  
                                }  
                            }  
                        }  
                    }  
                }  
            }  
        }  
    }  
}  


此时使用这三个函数,再加上自绘的DrawItem已经可以实现界面上的行号不同了。


显示代码很多,我就不依次列举了。如有需要可以下载上传文件,我将.h和.cpp放在一起了。拆分后可以运行。
功能包括:表头的自绘、表本身实现系统的操作

点击打开链接

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糯诺诺米团

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值