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应用程序的过程。

  • 相关阅读:
    用Bootstrap框架弹出iframe页面 在弹出的模态框中载人iframe页面,bootstrapiframe
    Jquery Ajax表单提交插件jquery form用法
    ASP.NET MVC 在控制器中接收视图表单POST过来的数据方法
    RabbitMQ用户管理+VirtualHost管理
    Linux 查看Oracle 信息
    页面元素的坐标位置
    Selenium之Action Chains类
    测试管理:用量化的思想管理工作
    Python selenium ---父子,兄弟,相邻节点定位方式详解
    webdriver 清空input元素的值
  • 原文地址:https://www.cnblogs.com/13062225wmx/p/5245151.html
Copyright © 2011-2022 走看看