MFC总结

1.首先是ListControl

简介: 列表视图控件List Control同样比较常见,它能够把任何字符串内容以列表的方式显示出来,这种显示方式的特点是整洁、直观,在实际应用中能为用户带来方便。

    列表视图控件是列表框控件List Box的改进和延伸。列表视图控件的列表项一般有图标(Icon)和标签(Label)两部分。图标是对列表项的图形描述,标签是文字描述。当然列表项可以只包含图标也可以只包含标签。

    列表视图控件有4种风格:Icon、Small Icon、List和Report。下面简单说下4种风格各自的特点:

    Icon大图标风格:列表项的图标通常为32×32像素,在图标的下面显示标签。

    Small Icon小图标风格:列表项的图标通常为16×16像素,在图标的右面显示标签。  

    List列表风格:与小图标风格类似,图标和文字的对齐方式不同。

    Report报表风格:列表视图控件可以包含一个列表头来描述各列的含义。每行显示一个列表项,通常可以包含多个列表子项。最左边的列表子项的标签左边可以添加一个图标,而它右边的所有子项则只能显示文字。这种风格的列表视图控件很适合做各种报表。

   我的理解就是windows资源管理器,“查看”标签下的“大图标,小图标,列表,详细资料”

创建: MFC同样为列表视图控件的操作提供了CListCtrl类。

   如果我们不想在对话框模板中直接拖入List Control来使用列表视图控件,而是希望动态创建它,则要用到CListCtrl类的成员函数Create函数,原型如下:

virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID 
);

  参数rect为列表视图控件的位置和尺寸,pParentWnd为指向父窗口的指针,nID指定列表视图控件的ID,最复杂的一个参数同样还是dwStyle,它用于设定列表视图控件的风格,可以是以下风格的组合:

风格    含义
LVS_ALIGNLEFT                         显示格式是大图标或小图标时,标签放在图标的左边
LVS_ALIGNTOP                          显示格式是大图标或小图标时,标题放在图标的上边
LVS_AUTOARRANGE 显示格式是大图标或小图标时,自动排列控件中的列表项
LVS_EDITLABELS                       用户可以修改标签文本
LVS_ICON                                  指定大图标显示格式
LVS_LIST                                   指定列表显示格式
LVS_NOCOLUMNHEADER          在报表格式中不显示列的表头
LVS_NOLABELWRAP                 显示格式是大图标时,使标签文本单行显示。默认是多行显示
LVS_NOSCROLL                        列表视图控件无滚动条,此风格不能与LVS_LIST或LVS_REPORT组合使用
LVS_NOSORTHEADER               报表格式的列表视图控件的表头不能作为排序按钮使用
LVS_OWNERDRAWFIXED         由控件的拥有者负责绘制表项
LVS_REPORT                            指定报表显示格式
LVS_SHAREIMAGELISTS            使列表视图共享图像序列
LVS_SHOWSELALWAYS            即使控件失去输入焦点,仍显示出项的选择状态
LVS_SINGLESEL                        指定只能有一个列表项被选中。默认时可以多项选择
LVS_SMALLICON                        指定小图标显示格式
LVS_SORTASCENDING              按升序排列列表项
LVS_SORTDESCENDING           按降序排列列表项

常用方法:以下未经说明,ListControl默认view,风格为report

--1.设置ListControl风格及扩展风格

 1      LONG lStyle;
 2      lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style
 3      lStyle &= ~LVS_TYPEMASK; //清除显示方式位
 4      lStyle |= LVS_REPORT; //设置style
 5      SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style
 6  
 7      DWORD dwStyle = m_list.GetExtendedStyle();
 8      dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
 9      dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
10      dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
11      m_list.SetExtendedStyle(dwStyle); //设置扩展风格

--2.插入数据

1      m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入列
2      m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );
3      int nRow = m_list.InsertItem(0, “11”);//插入行
4      m_list.SetItemText(nRow, 1, “jacky”);//设置数据

--3.一直选中item

选中style中的Show selection always,或者在上面第2点中设置LVS_SHOWSELALWAYS

--4.选中和取消选中一行

1    int nIndex = 0;
2     //选中
3    m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
4     //取消选中
5    m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

--5.得到ListControl中的所有行的checkbox的状态

 1      m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
 2      CString str;
 3      for(int i=0;i<m_list.GetItemCount();i++)
 4      {
 5           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
 6           {
 7                str.Format(_T("第%d行的checkbox为选中状态"), i);
 8                AfxMessageBox(str);
 9           }
10      }

--6.得到ListControl中所有选中行的序号

1     CString str;
2      for(int i=0; i<m_list.GetItemCount();i++)
3      {
4           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
5           {
6                str.Format(_T("选中了第%d行"), i);
7                AfxMessageBox(str);
8           }
9      }

--7.得到item的信息

1      TCHAR szBuf[1024];
2      LVITEM lvi;
3      lvi.iItem = nItemIndex;
4      lvi.iSubItem = 0;
5      lvi.mask = LVIF_TEXT;
6      lvi.pszText = szBuf;
7      lvi.cchTextMax = 1024;
8      m_list.GetItem(&lvi);

--8.得到ListControl的所有列的header字符串内容

 1      LVCOLUMN lvcol;
 2      char  str[256];
 3      int   nColNum;
 4      CString  strColumnName[4];//假如有4列
 5 
 6      nColNum = 0;
 7      lvcol.mask = LVCF_TEXT;
 8      lvcol.pszText = str;
 9      lvcol.cchTextMax = 256;
10      while(m_list.GetColumn(nColNum, &lvcol))
11      { 
12           strColumnName[nColNum] = lvcol.pszText;
13           nColNum++;
14      }

--9.使ListControl中一项可见,即滚动滚动条

    m_list.EnsureVisible(i, FALSE);

--10.得到ListControl列数

    int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();

--11.删除所有列

1        // 方法一:
2         while ( m_list.DeleteColumn (0))
3        因为你删除了第一列后,后面的列会依次向上移动。
4 
5          //方法二:
6          int nColumns = 4;
7          for (int i=nColumns-1; i>=0; i--)
8             m_list.DeleteColumn (i);

--12.得到单击的ListControl的行列号

 1    // 添加listctrl控件的NM_CLICK消息相应函数
 2      void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
 3      {
 4          CString str;
 5          for(int i=0; i<m_list.GetItemState();i++)
 6          {
 7               if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
 8               {
 9                    str.Format(_T("选中了第%d行"), i);
10                    AfxMessageBox(str);
11               }
12          }
13          
14          *pResult = 0;
15      }

--13.判断是否点击在ListControl的checkbox上

 1     //添加listctrl控件的NM_CLICK消息相应函数
 2      void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
 3      {
 4           DWORD dwPos = GetMessagePos();
 5           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
 6    
 7           m_list.ScreenToClient(&point);
 8    
 9           LVHITTESTINFO lvinfo;
10           lvinfo.pt = point;
11           lvinfo.flags = LVHT_ABOVE;
12      
13           UINT nFlag;
14           int nItem = m_list.HitTest(point, &nFlag);
15           //判断是否点在checkbox上
16           if(nFlag == LVHT_ONITEMSTATEICON)
17           {
18                AfxMessageBox("点在listctrl的checkbox上");
19           } 
20           *pResult = 0;
21      }

--14.右键点击ListControl的item弹出菜单

 1     //添加listctrl控件的NM_RCLICK消息相应函数
 2      void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
 3      {
 4           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
 5           if(pNMListView->iItem != -1)
 6           {
 7                DWORD dwPos = GetMessagePos();
 8                CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
 9     
10                CMenu menu;
11                VERIFY( menu.LoadMenu( IDR_MENU1 ) );
12                CMenu* popup = menu.GetSubMenu(0);
13                ASSERT( popup != NULL );
14                UINT Cmd =popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON| TPM_RETURNCMD, point.x, point.y, this );
15 
16             switch(Cmd)
17 
18             {
19 
20               case  ID_Log_SELECT:
21 
22               break;
23 
24               case  ID_Log_CANCEL:
25 
26               break;
27 
28             }
29           } 
30           *pResult = 0;
31   }

--14.修改某一行的某一项

m_listRecvDetail.SetItem(m_listItemCount-2,3,LVIF_TEXT,"不应答",0,0,0,NULL);

--15.失去焦点后依然高亮显示某一行或者熄灭某一行

1 //获得选中行的索引
2 m_SecCount = (int)m_lc.GetFirstSelectedItemPosition()-1;
3 
4 //设置选中行一直高亮显示
5 m_lc.SetItemState(m_SecCount,LVIS_DROPHILITED,LVIF_STATE);
6    
7 //取消在失去高亮时候选中行的高亮显示
8 m_lc.SetItemState(m_SecCount,FALSE,LVIF_STATE);

--16.单击ListControl获取行号

 1 /添加响应NM_CLICK消息
 2 
 3 void CEventAddDlg::OnNMClickListEventselect(NMHDR *pNMHDR, LRESULT *pResult)
 5 {
 6   LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR) ;
 7   int nItem = -1 ;
 8   if( pNMItemActivate != NULL )
 9   {
10     nItem = pNMItemActivate->iItem ;    // To get selected RAW NUM
11   }
12   *pResult = 0 ;
13 }

2.编辑框Edit Control

编辑框的通知消息

  编辑框发生某些事件时会向父窗口发送通知消息。在对话框模板中的编辑框上点右键,选择“Add Event Handler”,为编辑框添加消息处理函数时,可以在“Message type”列表中看到这些消息。下面简单介绍编辑框的部分通知消息。

  EN_CHANGE:编辑框的内容被用户改变了,与EN_UPDATE 不同,该消息是在编辑框显示的正文被刷新后才发出的
       EN_ERRSPACE: 编辑框控件无法申请足够的动态内存来满足需要
       EN_HSCROLL: 用户在水平滚动条上单击鼠标
       EN_KILLFOCUS: 编辑框失去输入焦点
       EN_MAXTEXT:输入的字符超过了规定的最大字符数。在没有ES_AUTOHSCROLL 或
       ES_AUTOVSCROLL: 的编辑框中,当正文超出了编辑框的边框时也会发出该消息
       EN_SETFOCUS: 编辑框获得输入焦点
       EN_UPDATE: 在编辑框准备显示改变了的正文时发送该消息
       EN_VSCROLL: 用户在垂直滚动条上单击鼠标

编辑框的创建

   MFC为编辑框提供了CEdit类。编辑框的所有操作都封装到了CEdit类中。

  与静态文本框的创建类似,除了可以在对话框模板上拖进一个编辑框,然后关联一个变量或通过API函数使用,也可以在程序中动态创建编辑框,即调用CEdit类的成员函数Create。Create成员函数的原型如下:

virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID
);

   参数说明:

  dwStyle:指定编辑框的风格。可以是MSDN中“edit styles”包含风格的任意组合。下面是“edit styles”的所有风格说明。

       ES_AUTOHSCROLL:当用户在行尾键入一个字符时,正文将自动向右滚动10 个字符,当用户按回车键时,正文总是滚向左边
       ES_AUTOVSCROLL: 当用户在最后一个可见行按回车键时,正文向上滚动一页
       ES_CENTER: 在多行编辑框中使正文居中
       ES_LEFT :左对齐正文
       ES_LOWERCASE: 把用户输入的字母统统转换成小写字母
       ES_MULTILINE:指定一个多行编辑器。若多行编辑器不指定ES_AUTOHSCROLL 风格,则会自动换行,若不指定ES_AUTOVSCROLL,则多行编辑器会在窗口中正文装满时
  发出警告声响
       ES_NOHIDESEL:默认时,当编辑框失去输入焦点后会隐藏所选的正文,当获得输入焦点时又显示出来。设置该风格可禁止这种默认行为
       ES_NUMBER :编辑框中只允许输入数字
       ES_OEMCONVERT:使编辑框中的正文可以在ANSI 字符集和OEM 字符集之间相互转换。这在编辑框中包含文件名时是很有用的
       ES_PASSWORD: 使所有键入的字符都用“*”来显示
       ES_READONLY: 将编辑框设置成只读的
       ES_RIGHT :右对齐正文
       ES_UPPERCASE: 把用户输入的字母统统转换成大写字母
       ES_WANTRETURN:使多行编辑器接收回车键输入并换行。如果不指定该风格,按回车键会选择默认的命令按钮,这往往会导致对话框的关闭

       除了上面的风格外,编辑款一般还会设置WS_CHILD、WS_VISIBLE、WS_BORDER等窗口风格。另外,编辑框可以是多行的,也就是在编辑框中显示多行文字,这就需要设置ES_MULTILINE风格,如果想要多行编辑框支持回车键,

  则还要设置ES_WANTRETURN。

       对于在对话框模板中创建的编辑框,它的属性中包含了上述的风格,例如,Multiline属性对应的就是ES_MULTILINE风格,Want Return属性对应ES_WANTRETURN风格。

       其他三个参数与静态文本框的Create函数的参数类似,就不介绍了。

CEdit类的主要成员函数

    使用编辑框最重要的莫过于,获取和设置编辑框中的正文,它们对应的成员函数分别是GetWindowText和SetWindowText,这两个函数都是继承自CWnd类的成员函数,

  另外,还可以使用CWnd类的GetWindowTextLength函数获取编辑框中正文的长度。

    下面简单介绍CEdit类的其他几个主要的成员函数:

   int LineFromChar(int nIndex = –1) const;

  返回多行编辑框中指定索引的字符所在行的行号(从零开始),只适用于多行编辑框。nIndex等于-1则返回所选择正文的第一个字符所在行的索引。如果没有选择正文,则返回当前行的行号。

  int LineIndex(int nLine = –1) const;

  返回由nLine指定行的起始字符在编辑框的整个字符串中的索引,只适用于多行编辑框。如果指定行超过编辑框的最大行数,则返回-1,而如果nLine为-1,则返回当前插入符所在行的起始字符的索引。

  void GetSel(int& nStartChar,int& nEndChar) const;

  获取选择正文的索引范围。nStartChar返回被选择正文的起始索引,nEndChar返回被选择正文的终止索引(不包括在选择范围内)。如果没有选择正文,则两者均为当前插入符的索引。

  void SetSel(int nStartChar,int nEndChar,BOOL bNoScroll=FALSE);

  选择编辑框中的正文。nStartChar为选择开始处的索引,nEndChar为选择结束处的索引。如果nStartChar为0并且nEndChar为-1,则选择所有正文,而如果nStartChar为-1则取消所有选择。bNoScroll为FALSE时滚动插入符并使之可见,为TRUE时不滚动。

  void ReplaceSel(LPCTSTR lpszNewText,BOOL bCanUndo = FALSE);

  用lpszNewText指向的字符串来替换选择的正文。如果bCanUndo为TRUE则替换可以被撤销。

   int GetLineCount() const;

  获取正文的行数,只适用于多行编辑框。如果编辑框没有正文则返回1。

  int LineLength( int nLine = –1 ) const;

       获取指定字符索引所在行的字节长度(行尾的回车和换行符不计算在内),参数nLine 说明了为字符索引。如果nLine 的值为-1,则函数返回当前行的长度(假如没有正文被选择),或选择正文占据的行的字符总数减去选择正文的字符数(假如有正文被选择)。若用于单行编辑框,则函数返回整个正文的长度。

       int GetLine( int nIndex, LPTSTR lpszBuffer ) const;
       int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;

       用来获得指定行的正文(不包括行尾的回车和换行符),只适用于多行编辑框。参数nIndex 是行号,lpszBuffer 指向存放正文的缓冲区,nMaxLength 规定了拷贝的最大字节数。若指定的行号小于编辑框的实际行数,函数返回实际拷贝的字节数,若指定的行号大于编辑框的实际行数,则函数返回0。需要注意的是,GetLine 函数不会在缓冲区中字符串的末尾添加字符串结束符(NULL)。   

       UINT GetLimitText( ) const;

       获取编辑框能够接受的正文的最大字节数。

       void LimitText(int nChars = 0);

       设置用户在编辑框中可以输入的正文的最大长度(字节数)。如果nChars为0,则最大长度为UINT_MAX个字节。

3.字符转换

  1. CString向char类型转换

1         CString str = "hello";
2         string st = (string)(CStringA)str;
3         int len = st.length();
4         char* ch = (char*)malloc(len); //动态申请char*大小的空间
5         for(int i = 0 ; i <len ; i++)
6         {
7             ch[i] = st[i];
8         }
9         ch[len] = '';

  2. int向CString类型的转换

 /*若转换时Format函数第一个参数报错可能是因为项目字符集有问题,可以修改为“使用多字节字符集”;或者将参数"%d"改为_T("%d")*/

     int myInt;//目标int类型
     CString myCString;//目标CString类型
     myCString.Format("%d",myInt);

/*转换函数,有两个参数(前一个%d表示十进制正数,不加则不能将myInt格式为CString;第二个参数即为需要转换的int类型变量)*/

Formt简单介绍: 
有俩种形式,分别是俩个参数和三个参数,三个参数的线程安全但是不常用,俩个参数的较为常用,需要着重掌握。

  3. CString向int类型转换

 int myInt;//目标int类型
 CString myCString;//目标CString类型
 myInt= _ttoi(myCString);

  4. int向string类型转换 

//使用C++函数std::to_string可以实现转换,std::to_string不但可以将int转换成string,对于常用的基本数据类型都能进行转换,如float、double、long等。

int myInt;//目标int类型
string to_string (myInt);

  5. string向int类型转换

std::string str;  //目标string类型
int myInt = std::stoi(str); 

  6. char向CString类型转换

//产生两个个随机长度的key字符数组
char * key = test->genRandomString(128);
char * value = test->genRandomString(256);
//DO SOMETHING 对数据进行操作
………………
char temp[1024];
//将字符数组,key,value按照一定的格式要求,连接起来
sprintf(temp,"%s%s%s%s%s%s","Key:",key,"------","Value",value,"插入成功!");
//生成我们需要的CString对象
CString str(temp);
原文地址:https://www.cnblogs.com/wzqstudy/p/12061386.html