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\n",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應用程序的過程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM