CListCtrl编程示例(设计MyView)

CListCtrl编程示例(设计MyView

目标:

l         实现大图标,小图标,详细列表,列表视图的实现

l         当双击ModelBar时,若为目录,则在MyView中列出其子结点;若为模型,列出其所在目录的结点

l         Myview下若双击目录,进入下一级,若双击模型,则提供预览

l         提供向上,后退,前进功能

 

第一步:设定CListCtrl

1

定义变量:

    CListCtrl& m_list ;

    CImageList *m_pLargeImageList;

    CImageList *m_pSmallImageList;

    CImageList *m_pMiddleImageList;

    ViewMode m_viewMode;

 

2

设置风格

void CMyView::OnInitialUpdate()

{

……

    DWORD dwStyle = m_list.GetExtendedStyle();

    dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl

    //dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl

    m_list.SetExtendedStyle(dwStyle); //设置扩展风格

 

    m_pLargeImageList = new CImageList();

    ASSERT(m_pLargeImageList != NULL);    // serious allocation failure checking

    m_pLargeImageList->Create(64, 64, ILC_COLOR32, 4, 4);

    m_pLargeImageList->Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));

    m_pLargeImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1));

 

    m_pSmallImageList = new CImageList();

    ASSERT(m_pSmallImageList != NULL);    // serious allocation failure checking

    m_pSmallImageList->Create(16, 16, ILC_COLOR32, 4, 4);

    m_pSmallImageList->Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));

    m_pSmallImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1));

 

    m_pMiddleImageList = new CImageList();

    ASSERT(m_pMiddleImageList != NULL);    // serious allocation failure checking

    m_pMiddleImageList->Create(32, 32, ILC_COLOR32, 4, 4);

    m_pMiddleImageList->Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));

    m_pMiddleImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1));

 

    //默认情况下是小图标模式

    m_list.SetImageList(m_pMiddleImageList, LVSIL_SMALL);

 

    m_list.InsertColumn( 0, "名称", LVCFMT_LEFT, 250 );//插入列

    m_list.InsertColumn( 1, "大小", LVCFMT_LEFT, 150);

    m_list.InsertColumn( 2, "类型", LVCFMT_LEFT, 50);

    m_list.InsertColumn( 3, "修改日期", LVCFMT_LEFT, 150);

    m_list.InsertColumn( 4, "创建者", LVCFMT_LEFT, 150);

    m_list.InsertColumn( 5, "描述信息", LVCFMT_LEFT, 250);

 

    //默认是详细report视图

    LONG lStyle=GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style

    lStyle &= ~LVS_TYPEMASK; //清除显示方式位

    lStyle |= LVS_REPORT; //设置style

    SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style

    m_list.SetImageList(m_pSmallImageList, LVSIL_SMALL);

    m_list.Arrange(LVA_ALIGNTOP);//自动调整位置,防止重叠

    ……

}

 

第二步:编写updateModelView

根据指定的位置进行更新CmyView

若为目录,则在MyView中列出其子结点;若为模型,列出其所在目录的结点

 

void CMyView::updateModelView(int modelIndex)

{

    m_list.DeleteAllItems();

    m_viewMode=MODEL_VIEW;

    //确保modelIndex有效

    ASSERT(modelIndex>=0&&modelIndex<(int)DBM.m_modelItemVec.size());

    //若为模型,列出其所在目录的结点

    if (!(DBM.m_modelItemVec[modelIndex].flag))

    {

        modelIndex=DBM.m_modelItemVec[modelIndex].parent;

    }

    //const CModelItem &itemT=DBM.m_modelItemVec[modelIndex];

    for (size_t i=0;i<DBM.m_modelItemVec[modelIndex].children.size();i++)

    {

        int j=DBM.m_modelItemVec[modelIndex].children[i];

        const CModelItem &itemT=DBM.m_modelItemVec[j];

        CString str;

        int nRow = m_list.InsertItem(j,itemT.name.c_str(),itemT.flag);//插入行

        if (!itemT.flag)//若是模型

        {

            int sizeKB=(double)itemT.dataSize/1024.0+0.5;//四舍五入

            str.Format("%d KB",sizeKB);

            m_list.SetItemText(nRow, 1, str);//设置数据

        }

        itemT.flag?str.Format("文件夹"):str.Format("模型");

        m_list.SetItemText(nRow, 2, str);

        m_list.SetItemText(nRow, 3, itemT.dateTime.substr(0,16).c_str());

        m_list.SetItemText(nRow, 4, itemT.owner.c_str());

        m_list.SetItemText(nRow, 5, itemT.description.c_str());

    }

}

 

第三步:树型控件的双击函数,此时激活CMyView并且列表显示

 

void CModelBar::CMyTreeCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)

{

    // TODO: Add your control notification handler code here

    //双击应该响应MyView

    HTREEITEM ht=this->GetSelectedItem();

    int depthT=0;//当前选择所在的层数,根据层数和名字可以唯一确定选择项目

    string nameT=GetItemText(ht);

    while(GetParentItem(ht)!=NULL)

    {

        depthT++;

        ht=GetParentItem(ht);

    }

    int indexT=DBM.getIndexByDepthAndName(depthT,nameT);

    ASSERT(indexT!=MY_NOTEXIST);

    ((CMyView *)(GLB.m_pMyView))->updateModelView(indexT);

    *pResult = 1;

}

 

第四步:编写CMyView的的双击函数,进入下一级,若为模型,则提供预览

 

void CMyView::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)

{

    int   nItem=-1;  

    nItem   =   m_list.GetNextItem(nItem,   LVNI_SELECTED);  

    if(nItem==-1)   return;  

    int indexT=atoi(m_list.GetItemText(nItem,6).GetBuffer());

    indexT=DBM.getIndexByID(indexT);

    if (DBM.m_modelItemVec[indexT].flag)//若是目录

    {

        updateModelView(indexT);

    }

    else

    {

        //预览

    }

    *pResult = 0;

}

 

第五步:设置后退,前进,向上的功能

 

 

第六步:自动排序(IDSize按照数字大小,其它按照字母顺序)

1

定义数据结构

    struct SortData

    {

        CListCtrl *m_list;

        BOOL flags[20];//1从小到大

        unsigned int curPos;

    };

 

2

定义比较函数

注意:务必调用m_list.SetItemData(nRow,nRow);给每个设置唯一标识,最好是元素位置

 

int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

{

    CMyView::SortData *sd=(CMyView::SortData *)lParamSort;

    LVFINDINFO findInfo;

    findInfo.flags = LVFI_PARAM;

    findInfo.lParam = lParam1;

    int iItem1 = sd->m_list->FindItem(&findInfo, -1);

    findInfo.lParam = lParam2;

    int iItem2 = sd->m_list->FindItem(&findInfo, -1);

    CString strItem1 =sd->m_list->GetItemText(iItem1,sd->curPos);

    CString strItem2 =sd->m_list->GetItemText(iItem2,sd->curPos);

    if ((sd->curPos==6)||(sd->curPos==1))//ID和大小按照数字大小排序

    {

        ……

    }

    else//其它按照字母顺序排序

    {

        ……

    }

}

 

3.

响应点击列的函数,找到列号和排序方向

void CMyView::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)

{

    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

    // TODO: Add your control notification handler code here

    m_sortData.curPos=pNMLV->iSubItem;

    m_sortData.flags[m_sortData.curPos]=!m_sortData.flags[m_sortData.curPos];

    m_sortData.m_list=&m_list;

    m_list.SortItems(MyCompareProc,(LPARAM)&m_sortData);

    *pResult = 0;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值