C++ MFC combo box和list control控件的使用

Combo Box用法:
 
combo box控件由两部分组成:编辑框和选择框(列表框)组成,对应的类是CComboBox

1、改变下拉框大小:先点向下的箭头,就可以调整下拉框大小

2、如果 ComboBox 的 Sorted 属性设置为 true,
   则新添加项将按字母顺序插入到列表中。
   否则,在列表的结尾处插入项。

3、要立即响应选择框的改变(即选择框一改变选项,就立刻将结果传递进去)!
   响应他的哪个消息比较好?

   如果是只能选择的响应ON_CBN_SELCHANGE
   如果是可以编辑的,那么要立刻响应编辑就是ON_CBN_EDITCHANGE

4、CBN_SELENDOK是什么作用?
   This notification message is sent when the user clicks a list item,
   or selects an item and then closes the list.
   It indicates the user's selection is to be processed

5、介绍一下列表框几种常用的消息映射宏:

   ON_CBN_DBLCLK 鼠标双击
   ON_CBN_DROPDOWN 列表框被弹出
   ON_CBN_KILLFOCUS / ON_CBN_SETFOCUS 在输入框失去/得到输入焦点时产生
   ON_CBN_SELCHANGE 列表框中选择的行发生改变
   ON_CBN_EDITUPDATE 输入框中内容被更新
   使用以上几种消息映射的方法为定义原型如:afx_msg void memberFxn( );的函数,
   并且定义形式如ON_Notification( id, memberFxn )的消息映射。
   如果在对话框中使用组合框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。

6、改变ComboBox的下拉列表框宽度
   一般情况下,列表框的宽度和选择框是一样宽的,为了让列表框变的更宽,可以用
   m_Combobox.setdroppedwidth(int width); 来调整 他的宽度

7、如何使控键ComboBox不能输入只能在下拉菜单中选择?
   VC6中style属性设为csDropDownList   //DropList?!
   VC2005中Type属性设为Drop List

8、设置当前项或得到当前是第几项
   
   m_ComboBox1.SetCurSel(N);    //SetCurSel函数可改变标签控件当前选定的项目
    //这个N可以是-1,表示无选择,0表示第一项,1表示第二项。。
   m_ComboBox1.GetCurSel();     //得到当前是第几项.0是第一项,1是第二项

List Control的用法:

List Control控件,是个列表,对应的类为CListCtrl。下面没有说明的,默认风格都为report

1、风格
    LVS_ICON: 为每个item显示大图标
    LVS_SMALLICON: 为每个item显示小图标
    LVS_LIST: 显示一列带有小图标的item
    LVS_REPORT: 显示item详细资料
    直观的理解:windows资源管理器,“查看”标签下的“大图标,小图标,列表,详细资料”

2、设置listctrl 风格及扩展风格
      LONG lStyle;
      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
 
      DWORD dwStyle = m_list.GetExtendedStyle();
      dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
      m_list.SetExtendedStyle(dwStyle); //设置扩展风格

3、插入数据
    m_list.InsertColumn( 0, "姓名", LVCFMT_LEFT, 40 );//插入列
    m_list.InsertColumn( 1, "部门", LVCFMT_LEFT, 50 );
    int nRow = m_list.InsertItem(0, “”);//插入行
    m_list.SetItemText(nRow, 0, “张三”);//设置数据,第1列
    m_list.SetItemText(nRow, 1, “软件部”);//设置数据,第2列

4、已知选中item
   选中style中的Show selection always选项,设置为true,或者在上面第2点中设置LVS_SHOWSELALWAYS
   设置为true后,当选中某一个item,这个item就会一直被选中,知道选中下一个或者都不选。

5、选中和取消选中一行
    int nIndex = 0;
    //选中
    m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
    //取消选中
    m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

6、得到listctrl中所有行的checkbox的状态
      m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
      CString str;
      for(int i=0; i<m_list.GetItemCount(); i++)
      {
           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
           {
                str.Format(_T("第%d行的checkbox为选中状态"), i);
                AfxMessageBox(str);
           }
      }

7、得到listctrl中所有选中行的序号

      方法一:
      CString str;
      for(int i=0; i<m_list.GetItemCount(); i++)
      {
           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
           {
                str.Format(_T("选中了第%d行"), i);
                AfxMessageBox(str);
           }
      }

      方法二:
      POSITION pos = m_list.GetFirstSelectedItemPosition();
      if (pos == NULL)
           TRACE0("No items were selected!\n");
      else
      {
           while (pos)
           {
                int nItem = m_list.GetNextSelectedItem(pos);
                TRACE1("Item %d was selected!\n", nItem);
                // you could do your own processing on nItem here
           }
      }

8、得到item的信息
      TCHAR szBuf[1024];
      LVITEM lvi;
      lvi.iItem = nItemIndex;
      lvi.iSubItem = 0;
      lvi.mask = LVIF_TEXT;
      lvi.pszText = szBuf;
      lvi.cchTextMax = 1024;
      m_list.GetItem(&lvi);

9、得到listctrl的所有列的header字符串内容
      LVCOLUMN lvcol;
      char  str[256];
      int   nColNum;
      CString  strColumnName[4];//假如有4列

      nColNum = 0;
      lvcol.mask = LVCF_TEXT;
      lvcol.pszText = str;
      lvcol.cchTextMax = 256;
      while(m_list.GetColumn(nColNum, &lvcol))
      {
           strColumnName[nColNum] = lvcol.pszText;
           nColNum++;
      }

10、使listctrl中一项可见,即滚动滚动条
    m_list.EnsureVisible(i, FALSE);

11、得到listctrl列数
    int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();

12、删除所有列
      方法一:
         while ( m_list.DeleteColumn (0))
       因为删除了第一列后,后面的列会依次向上移动。

      方法二:
      int nColumns = 4;
      for (int i=nColumns-1; i>=0; i--)
          m_list.DeleteColumn (i);

13、得到单击的listctrl的行列号
      添加listctrl控件的NM_CLICK消息相应函数
      void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           // 方法一:
           /*
           DWORD dwPos = GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
           m_list.ScreenToClient(&point);
           LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
           lvinfo.flags = LVHT_ABOVE;
           int nItem = m_list.SubItemHitTest(&lvinfo);
           if(nItem != -1)
           {
                CString strtemp;
                strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
                AfxMessageBox(strtemp);
           }
          */
  
          // 方法二:
          /*
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {
                CString strtemp;
                strtemp.Format("单击的是第%d行第%d列",
                                pNMListView->iItem, pNMListView->iSubItem);
                AfxMessageBox(strtemp);
           }
          */
           *pResult = 0;
      }

14、判断是否点击在listctrl的checkbox上
      添加listctrl控件的NM_CLICK消息相应函数
      void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           DWORD dwPos = GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
  
           m_list.ScreenToClient(&point);
  
           LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
           lvinfo.flags = LVHT_ABOVE;
    
           UINT nFlag;
           int nItem = m_list.HitTest(point, &nFlag);
           //判断是否点在checkbox上
           if(nFlag == LVHT_ONITEMSTATEICON)
           {
                AfxMessageBox("点在listctrl的checkbox上");
           }
           *pResult = 0;
      }

15、右键点击listctrl的item弹出菜单
      添加listctrl控件的NM_RCLICK消息相应函数
      void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {      
                m_pRClickMenu = new CMenu();
         ASSERT(m_pRClickMenu != NULL);
                m_pRClickMenu->CreatePopupMenu();
              m_pRClickMenu->AppendMenu(MF_STRING, IDC_BTN_SEND_EMAIL, "发送邮件");
         m_pRClickMenu->AppendMenu(MF_STRING, IDC_BTN_COPY, "复制到剪切板");
                // DWORD dwPos = GetMessagePos();
               // CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
                CPoint point;
  GetCursorPos(&point);
  m_pRClickMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this, NULL);
           }
           *pResult = 0;
  }

16、item切换焦点时(包括用键盘和鼠标切换item时),状态的一些变化顺序
      添加listctrl控件的LVN_ITEMCHANGED消息相应函数
      void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           // TODO: Add your control notification handler code here
   
           CString sTemp;
 
           if((pNMListView->uOldState & LVIS_FOCUSED) == LVIS_FOCUSED &&
            (pNMListView->uNewState & LVIS_FOCUSED) == 0)
           {
                sTemp.Format("%d losted focus",pNMListView->iItem);
           }
           else if((pNMListView->uOldState & LVIS_FOCUSED) == 0 &&
               (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
           {
                sTemp.Format("%d got focus",pNMListView->iItem);
           }
 
           if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED &&
            (pNMListView->uNewState & LVIS_SELECTED) == 0)
           {
                sTemp.Format("%d losted selected",pNMListView->iItem);
           }
           else if((pNMListView->uOldState & LVIS_SELECTED) == 0 &&
            (pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED)
           {
                sTemp.Format("%d got selected",pNMListView->iItem);
           }
           *pResult = 0;
      }

17、listctrl内容进行大数据量更新时,避免闪烁。
      m_list.SetRedraw(FALSE);
      //更新内容
      m_list.SetRedraw(TRUE);
      // m_list.Invalidate();
      // m_list.UpdateWindow();

18、listctrl第一列始终居左,解决办法
    把第一列当成虚列,然后插入第二列及数据,最后删除第一列,以后列还是从0开始。
    pListCtrl->InsertColumn(0, "", LVCFMT_CENTER, 0); 
    pListCtrl->InsertColumn(1, "姓名", LVCFMT_CENTER, 80);
    pListCtrl->InsertColumn(2, "性别", LVCFMT_CENTER, 100);
    pListCtrl->InsertColumn(3, "国籍", LVCFMT_CENTER, 100);
    pListCtrl->DeleteColumn(0);

19、使listctrl可编辑
  做法是:当单击listctrl时使整行高亮显示,双击listctrl时让编辑框移动到你双击所在列的位置上,此时编辑框获得焦点并且将listctrl的值更新到编辑框上,
          此时可以修改内容,当鼠标点击其他位置时,编辑框失去焦点,同时将编辑框的内容更新到listctrl中,从而完成对listctrl子项的修改。
   1) 首先在对话框中添加一个CEdit控件,并定义CEdit变量m_edit。当对话框初始化函数中隐藏该控件。
      m_edit.ShowWindow(SW_HIDE);

   2) 然后对CListCtrl添加消息NM_DBLCLK(双击事件),在消息中添加代码
     NM_LISTVIEW* pNMListView=(NM_LISTVIEW*)pNMHDR;
     CRect rc;
     if(pNMListView->iItem!=-1)
     {
        m_row=pNMListView->iItem;//m_row为被选中行的行序号(int类型成员变量)
        m_column=pNMListView->iSubItem;//m_column为被选中行的列序号(int类型成员变量)
        m_list.GetSubItemRect(pNMListView->iItem, pNMListView->iSubItem,LVIR_LABEL,rc);//取得子项的矩形
        rc.left+=3;
        rc.top+=2;
    rc.right+=3;
     rc.bottom+=2;
    char * ch=new char [128];
    m_list.GetItemText(pNMListView->iItem, pNMListView->iSubItem,ch,128);//取得子项的内容
    m_edit.SetWindowText(ch);//将子项的内容显示到编辑框中
    m_edit.ShowWindow(SW_SHOW);//显示编辑框
    m_edit.MoveWindow(&rc);//将编辑框移动到子项上面,覆盖在子项上
    m_edit.SetFocus();//使编辑框取得焦点
    m_edit.CreateSolidCaret(1,rc.Height()-5);//创建一个光标
   m_edit.ShowCaret();//显示光标
    m_edit.SetSel(-1);//使光标移到最后面
      }
      *pResult = 0;

   3) 然后,添加CEdit失去焦点时的消息EN_KILLFOCUS。在该消息中添加代码使编辑框中的内容更新到CListCtrl中。
 CString str;
 m_edit.GetWindowText(str);//取得编辑框的内容
 m_list.SetItemText(m_row,m_column,str);//将该内容更新到CListCtrl中
 m_edit.ShowWindow(SW_HIDE);//隐藏编辑框


 

posted on 2012-11-05 10:09  ssy黑桃a  阅读(16532)  评论(0编辑  收藏  举报