• 控件CListCtr详解


    1.CListCtrl控件

    CListCtrl控件在数据库编程中是用得比较多的控件之一,也是Window控件中较难掌握的一个控件。他可以有四显示方式,Report、List、Icon、SmallIcon。Report报告式列表视图方式在数据库开发中是最常用的一种方式。在控件"properties"的Styles选项卡中在View项可以选择Report方式。Report方式中列表控件的显示方式是有行和列的,行又叫做Item,但有多列是我们只能操作每一行的第零列,也就是最前列。

    2.与CListCtrl控件相关的数据类型
    (1)LV_COLUMN结构
    该结构仅用于报告式列表视图,用来描述表项的某一列。要想向表项中插入新的一列,需要用到该结构。
    LV_COLUMN结构定义如下:
    typedef struct_LV_COLUMN{
    UINT mask;         //屏蔽位的组合,表明哪些成员是有效的
    int  fmt;          //该列的表头和子项的标题显示格式(LVCF_FMT)
    int  cx;           //以象素啊为单位的列的宽度(LVCF_FMT)
    LPTSTR  pszText;   //指向存放列表头标题正文的缓冲区(LVCF_TEXT)
    int  cchTextMax;   //标题正文缓冲区的长度(LVCF_TEXT)
    int  iSubItem;     //说明该列的索引(LVCF_SUBITEM)
    }LVCOLUMN;

    (2)LV_ITEM结构
    该结构用来描述一个表项或一个子项,它包含了项的各种属性,定义为:
    typedef struct_LV_ITEM{
    UINT mask;         //屏蔽位的组合,表明哪些成员是有效的
    int  iItem;        //从0开始编号的表项索引(行索引)
    int  iSubItem;     //从1开始编号的子项索引(列索引),因为编号0的列使用InsertItem时已经写入数据
    UINT state;        //项的状态(LVIF_STATE)
    UINT stateMask;    //项的状态屏蔽
    LPTSTR pszText;    //指向存放项的正文的索引区(LVIF_TEXT)
    int  cchTextMax;   //标题正文缓冲区的长度(LVCF_TEXT)
    int  iImage;       //图标的索引(LVIF_IMAGE)
    LPARAM lParam;     //32位的附加数据(LV_PARAM)
    }LV_ITEM;

    3.CListCtrl类的成员函数
    (1)列的插入和删除项
    在初始化列表视图时,先要调用InsertColumn插入各个列,该函数的声明为:
    int InsertColumn(int nCol,const LV_COLUMN *pColumn);
    其中参数nCol是新列的索引,参数pColumn指向一个LV_COLUMN结构,函数根据该结构来创建新的列。若插入成功,函数返回新的索引;否则返回-1。
    要删除某列,应调用DeleteColumn()函数,其声明为:
    BOOL DeleteColumn(int nCol);

    (2)表项的插入
    要插入新的表项,应调用InsertItem。如果要显示图标,则应该创建一个CImageList对象并使该对象包含用作显示图标的位图序列,然后调用

    SetImageList为列表视图设置位图序列。函数的声明为:
    int InsertItem(const LV_ITEM *pItem);
    或者
    int InsertItem( int nItem, LPCTSTR lpszItem);
    int InsertItem( int nItem, LPCTSTR lpszItem,  int nImage );
    使用的时候多用第二种和第三种。因此省去了定义并初始化LV_ITEM数据类型这一步。
    参数pItem指向一个LV_ITEM结构,该结构提供了对表项的描述。若插入成功,返回新表项的索引;否则返回-1。
    参数nItem是表项的索引(行索引,从0开始);参数lpszItem为控件头的名字。

    (3)函数GetItemText()和函数SetItemText()用于查询和设置表项以及子项显示的正文。
    SetItemText()函数的一个重要用途就是对子项进行初始化。函数声明为:
    int GetItemText(int nItem,int nSubItem,LTPSTR lpszText,int nLen) const;
    CString GetItemText(int nItem,int nSubItem) const;
    BOOL SetItemText(int nItem,int nSubItem,LPTSTR lpszText);
    其中,参数nItem是表项的索引(行索引),nSubItem是子项的索引(列索引),若nSubItem为0说明函数是针对表项的。参数lpszText指向正文缓冲区,参数nLen说明缓冲区的大小。

    4.例1:在一个对话框中初始化列表框
    在对话框的初始化函数中添加对CListCtr控件的初始化代码
    BOOL CDlgall::OnInitDialog()
    {
     CDialog::OnInitDialog();
     LV_COLUMN lvc;        //定义一个LV_COLUMN数据类型用来描述一个列
     char *display[4]={"学号","姓名","性别","出生日期"};
            lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH;
     lvc.fmt = LVCFMT_LEFT;        //设置对齐方式
     lvc.cx = 80;                  //设置各列的宽度为80象素
     for(int i = 0; i < 4; i++)    //插入各列的表头
     {
      lvc.iSubItem = i;
      lvc.pszText = display[i];
      m_List.InsertColumn(i,&lvc);  //设置的是第i列的表头,具体样式以定义的lvc的属性为准
      //上句等价于m_List.InsertColumn(i,display[i],LVCF_LEFT,80); 即设置各列表头的样式
     }
     m_List.SetExtendedStyle(m_List.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
     //改变列表控件的显示风格为全部选中状态
     CDlgall::OnLoadAll();

     return TRUE;  // return TRUE unless you set the focus to a control
                   // EXCEPTION: OCX Property Pages should return FALSE
    }


    例2:从数据源中读取数据并在列表控件中进行显示

    void CDlgall::OnLoadAll()
    {
     char buffer[256];
     m_List.DeleteAllItems();  //清空所有条目
     if(!pset->IsOpen())       //判断记录集是否打开。如果关闭就打开记录集
      pset->Open(); 
     CString str1;
     pset->MoveFirst();        //将游标指向记录集的第一条记录

     for(int i = 0;!pset->IsEOF();i++)   //插入表项
     {
         m_List.InsertItem(i,LPCTSTR(pset->m_number));
         //InsertItem向CListCtr控件申请一行用来存放数据,同时写入一行的头名称(即编号为0列的数据)
         //以后各列使用SetItemText()函数来存放数据。
        
         m_List.SetItemText(i,1,LPCTSTR(pset->m_name)); 
         //设置第i行第1列的的数据为数据源中读取的当前记录某个字段的值
        
         m_List.SetItemText(i,2,LPCTSTR(pset->m_sex));   //以下类似
         str1 = pset->m_date.Format("%x");              
         m_List.SetItemText(i,3,str1);
         pset->MoveNext();           //游标下移
     }
     SetDlgItemText(IDC_EDIT2,itoa(pset->GetRecordCount(),buffer,10));
     //获取总的记录数并在控件IDC_EDIT2中进行显示
     pset->Close();
    }

    例3.点击列表控件的列时实现自动排序
    (1)首先在对话框的头文件中加入自定义排序函数SortList(CString &str)的函数声明。
    (2)然后定义SortList()函数
    void CDlgall::SortList(CString &str)
    {
        m_list.DeleteAllItems();  //清空所有条目
        pset->m_strSort = str;    //设定要排序的字段
        CDlgall::OnLoadAll();     //显示所有记录
        return;
    }
    说明:成员m_strSort是CRecordset类的公共成员数据,用于指定排序。m_strSort实际上包含了ORDER BY子句的内容,但它不含ORDER BY关键字。m_strSort的一个例子为:
    m_pSet->m_strSort=“name DESC”; //按CourseID的降序排列记录
    m_pSet->Open();


    (3)为列表控件的LV_COLUMNCLICK消息添加消息响应函数
    void CDlgall::OnColumnclickList1(NMHDR* pNMHDR, LRESULT* pResult)
    {
     NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
     //根据列字段进行排序
     switch(pNMListView->iSubItem)
     {
     case 0:
      Sortlist(CString("number"));
      break;
     case 1:
      Sortlist(CString("[name]"));
      break;
     case 2:
      Sortlist(CString("[date]"));
      break;
     case 3:
      Sortlist(CString("[sex]"));
      break;
     case 4:
      Sortlist(CString("[age]"));
      break;
     }
     *pResult = 0;
    }

    例4 双击CListCtrl中的某条记录进行修改

    void CDlgall::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
    {
        CDlgall::OnModify(); //双击某条记录则表示要修改记录
        *pResult = 0;
    }

    例5 根据输入的字段进行查询
    void CDlgall::OnFind()
    {
        m_List.DeleteAllItems();  //清空列表以显示查询到的记录
        UpdateData(true);  
        //对m_number进行字符处理,根据检查号位数在检查号前加零
        int len = strlen(m_number);
        char temp[10];
        switch(len) {
            case 1:
                strcpy(temp,"00000");break;
            case 2:
                strcpy(temp,"0000");break;
            case 3:
                strcpy(temp,"000");break;
            case 4:
                strcpy(temp,"00");break;
            case 5:
                strcpy(temp,"0");break;
            default:
                    strcpy(temp,"");
        }
        strcat(temp,m_number);
        m_number =temp;
        //查找对应的参数
        CSetdata*pset = new CSetdata();
        pset->m_strFilter = "number=?";  //设定过滤记录集的参数
        pset->Open();
        pset->number = m_number;
        pset->Requery();  //查询到符合条件的所有记录,并存放在记录集中
        //在列表控件中显示记录
        CString str1;
        if(!pset->IsEOF())
        {
            //以下插入单条记录
            char buffer[256];
            LV_ITEM lvi;
            lvi.mask = LVIF_TEXT;
            lvi.iSubItem = 0;
            int i = 0;
            m_List.InsertItem(i,LPCTSTR(pset->m_number),0);
            m_List.SetItemText(i,1,LPCTSTR(pset->m_name));
            str1 = pset->m_date.Format("%x");
            m_List.SetItemText(i,2,str1);
            m_List.SetItemText(i,3,LPCTSTR(pset->m_sex));
            m_List.SetItemText(i,4,LPCTSTR(ltoa(pset->m_age,buffer,10)));
            m_List.SetItemText(i,5,LPCTSTR(pset->m_zy));
            m_List.SetItemText(i,6,LPCTSTR(pset->m_mode));
            m_List.SetItemText(i,7,LPCTSTR(pset->m_bl));
            pset->Close();
        }
        else
        {
            CDlgall::OnLoadAll();  //如果没有找到相关记录,显示所有的记录
            AfxMessageBox("对不起,没有相关记录!");
        }  
    }
  • 相关阅读:
    eclipse优化与标准化记录
    eclipse easyexplorer openexplorer
    java获取class所在jar
    ajax提交复杂对象数据
    bootstrap dialog自行控制窗口的关闭
    jquery重置html form
    html button自动提交表单问题
    jquery TypeError: 'undefined' is not a function (evaluating 'elem.nodeName.toLowerCase()') [jquery.js:1904]错误原因
    推荐两个很好用的javascript模板引擎
    API的非向后兼容性无论如何通常代表着一种比较差的设计
  • 原文地址:https://www.cnblogs.com/flyptt/p/3635074.html
Copyright © 2020-2023  润新知