rt

解决方案 »

  1.   

    我从CListView派生出一个类,并没有提供额外的代码设置它的只读属性。设置它的只读属性应用LVS_???给style置位?谢谢!
      

  2.   

    好像其它的Item是不能编辑的,我是在单击Item时获得它的位置,然后在这个位置上创建一个EDIT,在EDIT失去焦点时将EDIT内的内容交给ITEM,然后删除EDIT。
      

  3.   

    问题解决。
    是VC产生的OnLBtnDblClick的默认处理代码没有注册掉。
    谢谢二位。
      

  4.   

    to lzmailcn:
       subitem 也是可以编辑的。post 一篇codeguru上的文章,希望对你有帮助。
    --------------------------------------------------------------------------------
    The default implementation of the ListView control allows editing of the first column label only. You have to create your own edit control to allow editing of subitems. 
    Step 1: Derive a class from CListCtrl
    In the code below, CMyListCtrl is the name used for the derived class. You can also derive a class from CListView if you need this functionality in a CView rather than in a control. If you are already working with a sub-class of CListCtrl, you can make the modifications to that class. 
    Step 2: Define HitTestEx()
    Define an extended HitTest function for the CMyListCtrl class. This function will determine the row index that the point falls over and also determine the column. The HitTestEx() has already been listed and explained in an earlier section and is listed here again for completeness. We need this function if the user interface to initiate the edit is a mouse click or a double click. See the section "Detecting column index of the item clicked". 
    // HitTestEx - Determine the row index and column index for a point
    // Returns - the row index or -1 if point is not over a row
    // point - point to be tested.
    // col - to hold the column index
    int CMyListCtrl::HitTestEx(CPoint &point, int *col) const
    {
    int colnum = 0;
    int row = HitTest( point, NULL );

    if( col ) *col = 0; // Make sure that the ListView is in LVS_REPORT
    if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
    return row; // Get the top and bottom row visible
    row = GetTopIndex();
    int bottom = row + GetCountPerPage();
    if( bottom > GetItemCount() )
    bottom = GetItemCount();

    // Get the number of columns
    CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
    int nColumnCount = pHeader->GetItemCount(); // Loop through the visible rows
    for( ;row <=bottom;row++)
    {
    // Get bounding rect of item and check whether point falls in it.
    CRect rect;
    GetItemRect( row, &rect, LVIR_BOUNDS );
    if( rect.PtInRect(point) )
    {
    // Now find the column
    for( colnum = 0; colnum < nColumnCount; colnum++ )
    {
    int colwidth = GetColumnWidth(colnum);
    if( point.x >= rect.left 
    && point.x <= (rect.left + colwidth ) )
    {
    if( col ) *col = colnum;
    return row;
    }
    rect.left += colwidth;
    }
    }
    }
    return -1;
    }
      

  5.   

    Step 3: Add function to initiate the edit
    The user interface to initiate an edit for a sub item may be click on an already selected row, a double click or even a push button. We define a helper function to set up the edit control. The helper function takes only the row and column index of the subitem. EditSubLabel() ensures that the row as well as the column is visible before it creates the edit control. It then creates the edit control of the right size and with the proper text justification. The edit control created is of the class CInPlaceEdit which we will define later. 
    // EditSubLabel - Start edit of a sub item label
    // Returns - Temporary pointer to the new edit control
    // nItem - The row index of the item to edit
    // nCol - The column of the sub item.
    CEdit* CMyListCtrl::EditSubLabel( int nItem, int nCol )
    {
    // The returned pointer should not be saved // Make sure that the item is visible
    if( !EnsureVisible( nItem, TRUE ) ) return NULL; // Make sure that nCol is valid
    CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
    int nColumnCount = pHeader->GetItemCount();
    if( nCol >= nColumnCount || GetColumnWidth(nCol) < 5 )
    return NULL; // Get the column offset
    int offset = 0;
    for( int i = 0; i < nCol; i++ )
    offset += GetColumnWidth( i ); CRect rect;
    GetItemRect( nItem, &rect, LVIR_BOUNDS ); // Now scroll if we need to expose the column
    CRect rcClient;
    GetClientRect( &rcClient );
    if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
    {
    CSize size;
    size.cx = offset + rect.left;
    size.cy = 0;
    Scroll( size );
    rect.left -= size.cx;
    } // Get Column alignment
    LV_COLUMN lvcol;
    lvcol.mask = LVCF_FMT;
    GetColumn( nCol, &lvcol );
    DWORD dwStyle ;
    if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
    dwStyle = ES_LEFT;
    else if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
    dwStyle = ES_RIGHT;
    else dwStyle = ES_CENTER; rect.left += offset+4;
    rect.right = rect.left + GetColumnWidth( nCol ) - 3 ;
    if( rect.right > rcClient.right) rect.right = rcClient.right; dwStyle |= WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
    CEdit *pEdit = new CInPlaceEdit(nItem, nCol, GetItemText( nItem, nCol ));
    pEdit->Create( dwStyle, rect, this, IDC_IPEDIT );
    return pEdit;
    }
    Step 4: Handle the scroll messages
    The CInPlaceEdit class is designed to destroy the edit control and delete the object when it loses focus. Clicking on the scrollbars of the ListView control does not take away the focus from the edit control. We therefore add handlers for the scrollbar messages which force focus away from the edit control by setting the focus to the list view control itself. void CMyListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    if( GetFocus() != this ) SetFocus();
    CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
    }void CMyListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    if( GetFocus() != this ) SetFocus();
    CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
    }
    Step 5: Handle EndLabelEdit
    Like the built in edit control for the first column, our edit control also sends the LVN_ENDLABELEDIT notification when the edit is completed. If this notification message isn’t already being handled, add a handler so that any changes made with the edit control can be accepted. void CMyListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
    {
    LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
    LV_ITEM *plvItem = &plvDispInfo->item; if (plvItem->pszText != NULL)
    {
    SetItemText(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
    }
    *pResult = FALSE;
    }