List Control控件item的可编辑操作实现

比眉伴天荒 2022-09-26 12:00 295阅读 0赞

目录(?)[-]

  1. 简介
  2. 实施步骤
  3. 总结

" class="reference-link">scrshot.jpg

简介

几乎每一个使用vc++编程的人,都将会遇到的列表控件。我们会遇到很多需要代表数据在多个栏目的列表控件场合。默认情况下是不可能的修改列表数据。在这个很小的文章我把一个简单的方法来实现在报告风格的列表控件编辑任意项目的值。这是简单的逻辑,每当用户点击一个他所要修改的子项目,我就在那个地方显示一个编辑框,允许修改其内容。修改后,并按回车键,最新值设置在列表控件。在这里我假设用户熟悉vc++和使用类的向导

实施步骤:

  1. 使用MFC向导,创建一个基于对话框的应用程序。程序命名为MultipleColumns。应用程序向导会默认生成OK和Cancel按钮,在这里,我们移除这两个按钮。
  2. 添加一个 List-Control控件,将view属性设置为Report,这是多列显示需要的风格。
  3. 添加两个按钮,命名为OK和Cancel。
  4. 添加一个Edit box控件,将Border属性设置为False。
  5. 用类向导为OK和Cancel按钮添加消息处理函数。为函数添加如下代码:
  1. void CMultipleColumnsDlg::OK()
  2. {
  3. CDialog::EndDialog (0); // Add this line
  4. }
  5. void CMultipleColumnsDlg::OnExit()
  6. {
  7. CDialog::EndDialog (0); // Add this line
  8. }
  1. 在CMulipleColumnsDlg类中添加InsertItems()函数
  1. void InsertItems();
  2. 在函数中添加如下代码:
  3. // This function inserts the default values
  4. // into the listControl
  5. void CMultipleColumnsDlg::InsertItems()
  6. {
  7. HWND hWnd = ::GetDlgItem(m_hWnd, IDC_LIST1);
  8. // Set the LVCOLUMN structure with the required
  9. // column information
  10. LVCOLUMN list;
  11. list.mask = LVCF_TEXT |LVCF_WIDTH|
  12. LVCF_FMT |LVCF_SUBITEM;
  13. list.fmt = LVCFMT_LEFT;
  14. list.cx = 50;
  15. list.pszText = "S.No";
  16. list.iSubItem = 0;
  17. //Inserts the column
  18. ::SendMessage(hWnd,LVM_INSERTCOLUMN,
  19. (WPARAM)0,(WPARAM)&list);
  20. list.cx = 100;
  21. list.pszText = "Name";
  22. list.iSubItem = 1;
  23. ::SendMessage(hWnd ,LVM_INSERTCOLUMN,
  24. (WPARAM)1,(WPARAM)&list);
  25. list.cx = 100;
  26. list.pszText = "Address";
  27. list.iSubItem = 2;
  28. ::SendMessage(hWnd ,LVM_INSERTCOLUMN,
  29. (WPARAM)1,(WPARAM)&list);
  30. list.cx = 100;
  31. list.pszText = "Country";
  32. list.iSubItem = 2;
  33. ::SendMessage(hWnd ,LVM_INSERTCOLUMN,
  34. (WPARAM)1,(WPARAM)&list);
  35. // Inserts first Row with four columns .
  36. SetCell(hWnd,"1",0,0);
  37. SetCell(hWnd,"Prabhakar",0,1);
  38. SetCell(hWnd,"Hyderabad",0,2);
  39. SetCell(hWnd,"India",0,3);
  40. // Inserts second Row with four columns .
  41. SetCell(hWnd,"2",1,0);
  42. SetCell(hWnd,"Uday",1,1);
  43. SetCell(hWnd,"Chennai",1,2);
  44. SetCell(hWnd,"India",1,3);
  45. // Inserts third Row with four columns .
  46. SetCell(hWnd,"3",2,0);
  47. SetCell(hWnd,"Saradhi",2,1);
  48. SetCell(hWnd,"Bangolore",2,2);
  49. SetCell(hWnd,"India",2,3);
  50. // Inserts fourth Row with four columns .
  51. SetCell(hWnd,"4",3,0);
  52. SetCell(hWnd,"Surya",3,1);
  53. SetCell(hWnd,"Calcutta",3,2);
  54. SetCell(hWnd,"India",3,3);
  55. }
  1. 在CMulipleColumnsDlg类中添加另外一个函数SetCell( )函数
  1. void SetCell(HWND hWnd1, CString value, int nRow, int nCol);
  2. 在函数中添加如下代码:
  3. // This function set the text in the specified
  4. // SubItem depending on the Row and Column values
  5. void CMultipleColumnsDlg::SetCell(HWND hWnd1,
  6. CString value, int nRow, int nCol)
  7. {
  8. TCHAR szString [256];
  9. wsprintf(szString,value ,0);
  10. //Fill the LVITEM structure with the
  11. //values given as parameters.
  12. LVITEM lvItem;
  13. lvItem.mask = LVIF_TEXT;
  14. lvItem.iItem = nRow;
  15. lvItem.pszText = szString;
  16. lvItem.iSubItem = nCol;
  17. if(nCol >0)
  18. //set the value of listItem
  19. ::SendMessage(hWnd1,LVM_SETITEM,
  20. (WPARAM)0,(WPARAM)&lvItem);
  21. else
  22. //Insert the value into List
  23. ListView_InsertItem(hWnd1,&lvItem);
  24. }
  1. 再在CMulipleColumnsDlg类中添加函数GetItemText()函数
  1. CString GetItemText(HWND hWnd, int nItem, int nSubItem) const;
  2. 在函数中添加如下代码:
  3. //this function will returns the item
  4. //text depending on the item and SubItem Index
  5. CString CMultipleColumnsDlg::GetItemText(
  6. HWND hWnd, int nItem, int nSubItem) const
  7. {
  8. LVITEM lvi;
  9. memset(&lvi, 0, sizeof(LVITEM));
  10. lvi.iSubItem = nSubItem;
  11. CString str;
  12. int nLen = 128;
  13. int nRes;
  14. do
  15. {
  16. nLen *= 2;
  17. lvi.cchTextMax = nLen;
  18. lvi.pszText = str.GetBufferSetLength(nLen);
  19. nRes = (int)::SendMessage(hWnd,
  20. LVM_GETITEMTEXT, (WPARAM)nItem,
  21. (LPARAM)&lvi);
  22. } while (nRes == nLen-1);
  23. str.ReleaseBuffer();
  24. return str;
  25. }
  1. 在CMultipleColumnsDlg类中添加两个int型变量

    1. int nItem, nSubItem;
  2. 从类向导中为 List control控件添加NM_CLICK通知消息。在函数处理中添加如下代码
  3. //This function Displays an EditBox at the position
    //where user clicks on a particular SubItem with
    //Rectangle are equal to the SubItem, thus allows to
    //modify the value
    void CMultipleColumnsDlg::OnClickList(

    1. NMHDR* pNMHDR, LRESULT* pResult)

    {

    1. Invalidate();
    2. HWND hWnd1 = ::GetDlgItem (m_hWnd,IDC_LIST1);
    3. LPNMITEMACTIVATE temp = (LPNMITEMACTIVATE) pNMHDR;
    4. RECT rect;
    5. //get the row number
    6. nItem = temp->iItem;
    7. //get the column number
    8. nSubItem = temp->iSubItem;
    9. if(nSubItem == 0 || nSubItem == -1 || nItem == -1)
    10. return ;
    11. //Retrieve the text of the selected subItem
    12. //from the list
    13. CString str = GetItemText(hWnd1,nItem ,
    14. nSubItem);
    15. RECT rect1,rect2;
    16. // this macro is used to retrieve the Rectanle
    17. // of the selected SubItem
    18. ListView_GetSubItemRect(hWnd1,temp->iItem,
    19. temp->iSubItem,LVIR_BOUNDS,&rect);
    20. //Get the Rectange of the listControl
    21. ::GetWindowRect(temp->hdr.hwndFrom,&rect1);
    22. //Get the Rectange of the Dialog
    23. ::GetWindowRect(m_hWnd,&rect2);
    24. int x=rect1.left-rect2.left;
    25. int y=rect1.top-rect2.top;
    26. if(nItem != -1)
    27. ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_EDIT1),
    28. HWND_TOP,rect.left+x,rect.top+4,
    29. rect.right-rect.left - 3,
    30. rect.bottom-rect.top -1,NULL);
    31. ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),SW_SHOW);
    32. ::SetFocus(::GetDlgItem(m_hWnd,IDC_EDIT1));
    33. //Draw a Rectangle around the SubItem
    34. ::Rectangle(::GetDC(temp->hdr.hwndFrom),
    35. rect.left,rect.top-1,rect.right,rect.bottom);
    36. //Set the listItem text in the EditBox
    37. ::SetWindowText(::GetDlgItem(m_hWnd,IDC_EDIT1),str);
    38. *pResult = 0;

    }

  4. 为了处理 ENTER键消息,我们需要在MultipleColumnsDlg.h文件中实现虚函数 OnOk,所以添加如下的保护成员函数

    1. afx_msg void OnOK();

    MultipleColumnsDlg.cpp中添加如下代码:

  1. // This function handles the ENTER key
  2. void CMultipleColumnsDlg::OnOK()
  3. {
  4. CWnd* pwndCtrl = GetFocus();
  5. // get the control ID which is
  6. // presently having the focus
  7. int ctrl_ID = pwndCtrl->GetDlgCtrlID();
  8. CString str;
  9. switch (ctrl_ID)
  10. { //if the control is the EditBox
  11. case IDC_EDIT1:
  12. //get the text from the EditBox
  13. GetDlgItemText(IDC_EDIT1,str);
  14. //set the value in the listContorl with the
  15. //specified Item & SubItem values
  16. SetCell(::GetDlgItem (m_hWnd,IDC_LIST1),
  17. str,nItem,nSubItem);
  18. ::SendDlgItemMessage(m_hWnd,IDC_EDIT1,
  19. WM_KILLFOCUS,0,0);
  20. ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),
  21. SW_HIDE);
  22. break;
  23. default:
  24. break;
  25. }
  26. }
  1. 最后一步是在OnInitDialog函数中添加如下代码
  1. //Set the style to listControl
  2. ListView_SetExtendedListViewStyle(::GetDlgItem
  3. (m_hWnd,IDC_LIST1),LVS_EX_FULLROWSELECT |
  4. LVS_EX_GRIDLINES);
  5. InsertItems();
  6. ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),SW_HIDE);

发表评论

表情:
评论列表 (有 0 条评论,295人围观)

还没有评论,来说两句吧...

相关阅读

    相关 List Control

           学习MFC也有半年多的时间了,对于控件的使用,只是大概知道怎么用,但是记不住,为了日后的使用方便从今天开始将常用到的控件的使用方法记录下来,以方便日后的使用。