zoukankan      html  css  js  c++  java
  • MFC List Control 控件添加单元格编辑,实现可编辑重写

      在实现随机生成四则运算的个人项目中,目前已经完成基本功能,想要把程序变成一个Windows界面的程序。原本以为学习过MFC,应该很快就能完成。但是由于以前用的都是VC6.0,这次用了VS2010,稍微有点不适应,而且也有一段时间没用,悲催地发现自己已经很不熟练了(╮(╯▽╰)╭基本上自己以前写的MFC应用程序都是看网上傻瓜教程,扯远了~~~)。经过分析发现,用MFC实现显示四则运算表达式然后接受用户输入答案,单纯地用List Control好像不能实现,所以又在网上搜索了实现可编辑List-Control的教程,自己跟着实现了一遍。

      首先,创建的是基于对话框的MFC应用程序,对话框为FourArithOperDlg,在FourArithOperDlg.h中添加如下变量和函数:

    1     int e_Item;//刚编辑的行
    2     int e_SubItem;//刚编辑的列
    3     CEdit m_Edit;//生成单元编辑框
    4     bool haveeditcreate;//标志编辑框已经被创建
    5     void createEdit(NM_LISTVIEW  *pEditCtrl, CEdit *createdit, int &Item, int &SubItem, bool &havecreat);//创建单元格编辑框函数  
    6     void distroyEdit(CListCtrl *list, CEdit* distroyedit, int &Item, int &SubItem);//销毁单元格编辑框对象 

      在对话框的初始函数中添加初始化代码如下:这里的列表框第一行显示表达式,第二行显示答案。

    1      CRect rect;
    2      m_expression.GetClientRect(&rect);
    3      m_expression.SetExtendedStyle(m_expression.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    4      m_expression.InsertColumn(0,_T("运算表达式"), LVCFMT_CENTER, rect.Width()/2,0);
    5      m_expression.InsertColumn(1,_T("结果"), LVCFMT_CENTER, rect.Width()/2,1);
    6      m_expression.InsertItem(0,_T("1+1"));
    7      m_expression.SetItemText(0,1,_T("2"));
    8      haveeditcreate = false;    

      为列表框添加单击响应函数,NM_CLICK,这里只是让第二列,也就是显示答案的那一列单击产生编辑框。

     1   NM_LISTVIEW  * pEditCtrl = (NM_LISTVIEW *)pNMHDR;
     2     printf("行:%d,列:%d
    ",pEditCtrl->iItem,pEditCtrl->iSubItem);
     3     if (pEditCtrl->iItem == -1)//点击到非工作区
     4     {
     5         if (haveeditcreate == true)//如果之前创建了编辑框就销毁掉
     6         {
     7             distroyEdit(&m_expression,&m_Edit,e_Item,e_SubItem);//销毁单元格编辑对象
     8             haveeditcreate = false;
     9         }
    10     } 
    11     else if(pEditCtrl->iSubItem == 1)//如果选择第二列
    12     {
    13         if (haveeditcreate == true)
    14         {
    15             if (!(e_Item == pEditCtrl->iItem && e_SubItem == pEditCtrl->iSubItem))//如果点中的单元格不是之前创建的
    16             {
    17                 distroyEdit(&m_expression,&m_Edit,e_Item,e_SubItem);
    18                 haveeditcreate = false;
    19                 createEdit(pEditCtrl,&m_Edit,e_Item,e_SubItem,haveeditcreate);
    20             } 
    21             else //点中的单元格是之前创建的
    22             {
    23                 m_Edit.SetFocus();//设置为焦点
    24             }
    25         } 
    26         else
    27         {
    28             e_Item = pEditCtrl->iItem;
    29             e_SubItem = pEditCtrl->iSubItem;
    30             createEdit(pEditCtrl,&m_Edit,e_Item,e_SubItem,haveeditcreate);//创建编辑框
    31         }
    32     }

       接下来就是创建与销毁单元格编辑框的实现了。

    1 void CFourArithOperDlg::distroyEdit(CListCtrl *list,CEdit* distroyedit, int &Item, int &SubItem)  
    2 {  
    3     CString meditdata;  
    4     distroyedit->GetWindowTextW(meditdata);  
    5     list->SetItemText(Item, SubItem, meditdata);//获得相应单元格字符  
    6     distroyedit->DestroyWindow();//销毁对象,有创建就要有销毁,不然会报错  
    7 }  
     1 void CFourArithOperDlg::createEdit(NM_LISTVIEW *pEditCtrl, CEdit *createdit, int &Item, int &SubItem, bool &havecreat)
     2 {
     3     Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理  
     4     SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理  
     5     createdit->Create(ES_AUTOHSCROLL | WS_CHILD | ES_LEFT | ES_WANTRETURN,  
     6         CRect(0, 0, 0, 0), this, IDC_EDIT_CREATEID);//创建编辑框对象,IDC_EDIT_CREATEID为控件ID号3000,在Resource.h中定义
     7     havecreat = true;  
     8     createdit->SetFont(this->GetFont(), FALSE);//设置字体,不设置这里的话上面的字会很突兀的感觉  
     9     createdit->SetParent(&m_expression);//将list control设置为父窗口,生成的Edit才能正确定位,这个也很重要  
    10     CRect  EditRect;  
    11     m_expression.GetSubItemRect(e_Item, e_SubItem, LVIR_LABEL, EditRect);//获取单元格的空间位置信息  
    12     EditRect.SetRect(EditRect.left+1, EditRect.top+1, EditRect.left + m_expression.GetColumnWidth(e_SubItem)-1, EditRect.bottom-1);//+1和-1可以让编辑框不至于挡住列表框中的网格线  
    13     CString strItem = m_expression.GetItemText(e_Item, e_SubItem);//获得相应单元格字符  
    14     createdit->SetWindowText(strItem);//将单元格字符显示在编辑框上  
    15     createdit->MoveWindow(&EditRect);//将编辑框位置放在相应单元格上  
    16     createdit->ShowWindow(SW_SHOW);//显示编辑框在单元格上面  
    17     createdit->SetFocus();//设置为焦点   
    18     createdit->SetSel(-1);//设置光标在文本框文字的最后  
    19 }

       然后,解决单元格编辑框中回车键的处理,在教程中说可以重载对话框类的OnOK函数来避免。所以在对话框类中添加声明

     1 afx_msg void OnOk(); 

      在对话框cpp文件中函数内为空。

    1 void CFourArithOperDlg::OnOk()
    2 {}

      但是此时,在编辑框中修改数据,然后点击其他的单元格,编辑框还停留在上一个单元格中,所以在对话框类声明中添加动态生成编辑框失去焦点响应函数

     1 afx_msg void OnKillFocusEdit(); 

      然后在对话框类实现地消息映射描述中添加

     1 ON_EN_KILLFOCUS(IDC_EDIT_CREATEID,&CFourArithOperDlg::OnKillFocusEdit) 

      处理函数:

    1 void CFourArithOperDlg::OnKillFocusEdit()
    2 {
    3     if (haveeditcreate == true)
    4     {
    5         distroyEdit(&m_expression,&m_Edit,e_Item,e_SubItem);
    6         haveeditcreate = false;
    7     }
    8 }

       现在,基本完成了对话框的第二列可以编辑的功能了,效果图:

      通过这个可编辑列表框的实现教程,熟悉了在VS中创建简单的MFC应用程序的过程。

  • 相关阅读:
    20200209 ZooKeeper 3. Zookeeper内部原理
    20200209 ZooKeeper 2. Zookeeper本地模式安装
    20200209 Zookeeper 1. Zookeeper入门
    20200206 尚硅谷Docker【归档】
    20200206 Docker 8. 本地镜像发布到阿里云
    20200206 Docker 7. Docker常用安装
    20200206 Docker 6. DockerFile解析
    20200206 Docker 5. Docker容器数据卷
    20200206 Docker 4. Docker 镜像
    Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition
  • 原文地址:https://www.cnblogs.com/13062225wmx/p/5245151.html
Copyright © 2011-2022 走看看