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

来源:互联网 发布:知乎 真武七截阵 编辑:程序博客网 时间:2024/05/20 22:01

目录(?)[-]

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


简介

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

实施步骤:

  1. 使用MFC向导,创建一个基于对话框的应用程序。程序命名为MultipleColumns。应用程序向导会默认生成OK和Cancel按钮,在这里,我们移除这两个按钮。
  2. 添加一个 List-Control控件,将view属性设置为Report,这是多列显示需要的风格。
  3. 添加两个按钮,命名为OK和Cancel。
  4. 添加一个Edit box控件,将Border属性设置为False。
  5. 用类向导为OK和Cancel按钮添加消息处理函数。为函数添加如下代码:
    void CMultipleColumnsDlg::OK() {    CDialog::EndDialog (0); // Add this line}
    void CMultipleColumnsDlg::OnExit() {    CDialog::EndDialog (0); // Add this line}
  6. CMulipleColumnsDlg类中添加InsertItems()函数
    void InsertItems();

    在函数中添加如下代码:

    // This function inserts the default values // into the listControlvoid CMultipleColumnsDlg::InsertItems(){    HWND hWnd = ::GetDlgItem(m_hWnd, IDC_LIST1);    // Set the LVCOLUMN structure with the required     // column information    LVCOLUMN list;    list.mask =  LVCF_TEXT |LVCF_WIDTH|         LVCF_FMT |LVCF_SUBITEM;    list.fmt = LVCFMT_LEFT;    list.cx = 50;    list.pszText   = "S.No";    list.iSubItem = 0;    //Inserts the column    ::SendMessage(hWnd,LVM_INSERTCOLUMN,         (WPARAM)0,(WPARAM)&list);    list.cx = 100;    list.pszText   = "Name";    list.iSubItem = 1;    ::SendMessage(hWnd  ,LVM_INSERTCOLUMN,         (WPARAM)1,(WPARAM)&list);    list.cx = 100;    list.pszText   = "Address";    list.iSubItem = 2;    ::SendMessage(hWnd  ,LVM_INSERTCOLUMN,         (WPARAM)1,(WPARAM)&list);    list.cx = 100;    list.pszText   = "Country";    list.iSubItem = 2;    ::SendMessage(hWnd  ,LVM_INSERTCOLUMN,         (WPARAM)1,(WPARAM)&list);    // Inserts first Row with four columns .    SetCell(hWnd,"1",0,0);    SetCell(hWnd,"Prabhakar",0,1);    SetCell(hWnd,"Hyderabad",0,2);    SetCell(hWnd,"India",0,3);    // Inserts second Row with four columns .    SetCell(hWnd,"2",1,0);    SetCell(hWnd,"Uday",1,1);     SetCell(hWnd,"Chennai",1,2);    SetCell(hWnd,"India",1,3);    // Inserts third Row with four columns .    SetCell(hWnd,"3",2,0);    SetCell(hWnd,"Saradhi",2,1);     SetCell(hWnd,"Bangolore",2,2);    SetCell(hWnd,"India",2,3);    // Inserts fourth Row with four columns .    SetCell(hWnd,"4",3,0);    SetCell(hWnd,"Surya",3,1);     SetCell(hWnd,"Calcutta",3,2);    SetCell(hWnd,"India",3,3);}
  7. CMulipleColumnsDlg类中添加另外一个函数SetCell( )函数
    void SetCell(HWND hWnd1, CString value, int nRow, int nCol);

    在函数中添加如下代码:

    // This function set the text in the specified // SubItem depending on the Row and Column valuesvoid CMultipleColumnsDlg::SetCell(HWND hWnd1,         CString value, int nRow, int nCol){    TCHAR     szString [256];    wsprintf(szString,value ,0);    //Fill the LVITEM structure with the     //values given as parameters.    LVITEM lvItem;    lvItem.mask = LVIF_TEXT;    lvItem.iItem = nRow;    lvItem.pszText = szString;    lvItem.iSubItem = nCol;    if(nCol >0)        //set the value of listItem        ::SendMessage(hWnd1,LVM_SETITEM,             (WPARAM)0,(WPARAM)&lvItem);    else        //Insert the value into List        ListView_InsertItem(hWnd1,&lvItem);}
  8. 再在CMulipleColumnsDlg类中添加函数GetItemText()函数
    CString GetItemText(HWND hWnd, int nItem, int nSubItem) const;

    在函数中添加如下代码:

    //this function will returns the item //text depending on the item and SubItem IndexCString CMultipleColumnsDlg::GetItemText(    HWND hWnd, int nItem, int nSubItem) const{    LVITEM lvi;    memset(&lvi, 0, sizeof(LVITEM));    lvi.iSubItem = nSubItem;    CString str;    int nLen = 128;    int nRes;    do    {        nLen *= 2;        lvi.cchTextMax = nLen;        lvi.pszText = str.GetBufferSetLength(nLen);        nRes  = (int)::SendMessage(hWnd,             LVM_GETITEMTEXT, (WPARAM)nItem,            (LPARAM)&lvi);    } while (nRes == nLen-1);    str.ReleaseBuffer();    return str;}
  9. CMultipleColumnsDlg类中添加两个int型变量
    int nItem, nSubItem;
  10. 从类向导中为 List control控件添加NM_CLICK通知消息。在函数处理中添加如下代码
  11. //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 valuevoid CMultipleColumnsDlg::OnClickList(        NMHDR* pNMHDR, LRESULT* pResult) {    Invalidate();    HWND hWnd1 =  ::GetDlgItem (m_hWnd,IDC_LIST1);    LPNMITEMACTIVATE temp = (LPNMITEMACTIVATE) pNMHDR;    RECT rect;    //get the row number    nItem = temp->iItem;    //get the column number    nSubItem = temp->iSubItem;    if(nSubItem == 0 || nSubItem == -1 || nItem == -1)        return ;    //Retrieve the text of the selected subItem     //from the list    CString str = GetItemText(hWnd1,nItem ,        nSubItem);    RECT rect1,rect2;    // this macro is used to retrieve the Rectanle     // of the selected SubItem    ListView_GetSubItemRect(hWnd1,temp->iItem,        temp->iSubItem,LVIR_BOUNDS,&rect);    //Get the Rectange of the listControl    ::GetWindowRect(temp->hdr.hwndFrom,&rect1);    //Get the Rectange of the Dialog    ::GetWindowRect(m_hWnd,&rect2);    int x=rect1.left-rect2.left;    int y=rect1.top-rect2.top;        if(nItem != -1)     ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_EDIT1),        HWND_TOP,rect.left+x,rect.top+4,         rect.right-rect.left - 3,        rect.bottom-rect.top -1,NULL);    ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),SW_SHOW);    ::SetFocus(::GetDlgItem(m_hWnd,IDC_EDIT1));    //Draw a Rectangle around the SubItem    ::Rectangle(::GetDC(temp->hdr.hwndFrom),        rect.left,rect.top-1,rect.right,rect.bottom);    //Set the listItem text in the EditBox    ::SetWindowText(::GetDlgItem(m_hWnd,IDC_EDIT1),str);    *pResult = 0;}
  12. afx_msg void OnOK();

    MultipleColumnsDlg.cpp 中添加如下代码:

    // This function handles the ENTER key void CMultipleColumnsDlg::OnOK() {       CWnd* pwndCtrl = GetFocus();    // get the control ID which is     // presently having the focus    int ctrl_ID = pwndCtrl->GetDlgCtrlID();    CString str;    switch (ctrl_ID)    {   //if the control is the EditBox         case IDC_EDIT1:        //get the text from the EditBox        GetDlgItemText(IDC_EDIT1,str);        //set the value in the listContorl with the        //specified Item & SubItem values        SetCell(::GetDlgItem (m_hWnd,IDC_LIST1),            str,nItem,nSubItem);        ::SendDlgItemMessage(m_hWnd,IDC_EDIT1,            WM_KILLFOCUS,0,0);        ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),            SW_HIDE);            break;             default:            break;    }}
  13. 最后一步是在OnInitDialog函数中添加如下代码
    //Set the style to listControlListView_SetExtendedListViewStyle(::GetDlgItem         (m_hWnd,IDC_LIST1),LVS_EX_FULLROWSELECT |         LVS_EX_GRIDLINES); InsertItems();::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT1),SW_HIDE);
0 0