您的位置:首页 > 编程语言 > C语言/C++

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

2013-09-22 17:35 645 查看
本文转自:http://www.cnblogs.com/crearo-ssy/archive/2012/11/05/2754641.html

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);//隐藏编辑框
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: