我现在点击ListCtrl表中某一位置只能选中一行(项目),但我现在是想选择一个项目中的某一列并对它进行值更改!!各位大虾帮我出点主意啊!我在网站查了一个代码好象是要另写控件,我把它移植过来但还是行不通!真的很郁闷哪!!

解决方案 »

  1.   

    是的,给你两个类
    第一个类:
    // ListCtrlEx.cpp : implementation file
    //
    #include "stdafx.h"
    #include "ListCtrlEx.h"
    #include "ListCellEdit.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CListCtrlEx
    struct ItemData
    {
    public:
    ItemData() : arrpsz( NULL ), dwData( NULL ),crText ( NULL ),crBak (NULL) {} LPTSTR* arrpsz;
    DWORD dwData;
    //color
    COLORREF * crText;
    COLORREF * crBak;
    private:
    // ban copying.
    ItemData( const ItemData& );
    ItemData& operator=( const ItemData& );
    };
    CListCtrlEx::CListCtrlEx()
    {
    }CListCtrlEx::~CListCtrlEx()
    {
    }
    BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
    //{{AFX_MSG_MAP(CListCtrlEx)
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
    ON_WM_LBUTTONDOWN()
    ON_WM_VSCROLL()
    ON_WM_HSCROLL()
    ON_WM_SIZE()
    ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // CListCtrlEx message handlers
    void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
    *pResult = CDRF_DODEFAULT; if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
    {
    *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    { *pResult = CDRF_NOTIFYSUBITEMDRAW;
    }
    else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
    {
    int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
    int nSubItem = pLVCD->iSubItem;
    /* if(nSubItem == 2) //颜色框
    {
    COLORREF clr = GetItemData(nItem);
    CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
    CRect rect;
    GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
    rect.bottom -= 1;
    rect.left += 1;
    pDC->Rectangle(rect);
    rect.DeflateRect(1,1);
    pDC->FillSolidRect(&rect, clr);

    *pResult = CDRF_SKIPDEFAULT; // We've painted everything.
    }*/
    }}void CListCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    CListCtrl::OnLButtonDown(nFlags, point);
    // TODO: Add your message handler code here and/or call default
        int nItem;
        int nSubItem;
        if ((nItem = HitTestEx (point, nSubItem)) != -1)
        {
    if(nSubItem == 1) 
    {
    EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 2) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 3) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 4) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 5) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 6) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 7) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 8) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 9) 
    {
        EditSubItem(nItem, nSubItem);
    }
    else if(nSubItem == 10) 
    {
        EditSubItem(nItem, nSubItem);
    }
        }
    }int CListCtrlEx::HitTestEx (CPoint& Point, int& nSubItem)
    {
    nSubItem = 0;
    int ColumnNum = 0;
        int Row = HitTest (Point, NULL);

        // 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 (ColumnNum = 0; ColumnNum < nColumnCount; ColumnNum++)
    {
    int ColWidth = GetColumnWidth (ColumnNum);
    if (Point.x >= Rect.left && Point.x <= (Rect.left + ColWidth))
    {
    nSubItem = ColumnNum;
    return Row;
    }
    Rect.left += ColWidth;
    }
    }
        }    return -1;
    }CEdit* CListCtrlEx::EditSubItem(int nItem, int nSubItem)
    {
        // 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 (nSubItem >= nColumnCount || GetColumnWidth (nSubItem) < 5)
    return NULL;    // Get the column offset
        int Offset = 0;
        for (int iColumn = 0; iColumn < nSubItem; iColumn++)
    Offset += GetColumnWidth (iColumn);    CRect Rect;
        GetItemRect (nItem, &Rect, LVIR_BOUNDS);    // Now scroll if we need to expose the column
        CRect ClientRect;
        GetClientRect (&ClientRect);
        if (Offset + Rect.left < 0 || Offset + Rect.left > ClientRect.right)
        {
    CSize Size;
    if (Offset + Rect.left > 0)
    Size.cx = -(Offset - Rect.left);
    else
    Size.cx = Offset - Rect.left;
    Size.cy = 0;
    Scroll (Size);
    Rect.left -= Size.cx;
        }    // Get nSubItem alignment
        LV_COLUMN lvCol;
        lvCol.mask = LVCF_FMT;
        GetColumn (nSubItem, &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 (nSubItem) - 3;
        if (Rect.right > ClientRect.right)
    Rect.right = ClientRect.right;    dwStyle |= WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
        CEdit *pEdit = new CListCellEdit (nItem, nSubItem, GetItemText (nItem, nSubItem));
        pEdit->Create (dwStyle, Rect, this, IDC_EDITCELL);    return pEdit;
    }void CListCtrlEx::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    // TODO: Add your message handler code here and/or call default
        if (GetFocus() != this) SetFocus();

    CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
    }void CListCtrlEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    // TODO: Add your message handler code here and/or call default
        if (GetFocus() != this) SetFocus(); CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
    }void CListCtrlEx::OnSize(UINT nType, int cx, int cy) 
    {
    CListCtrl::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here

    }void CListCtrlEx::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;
    }
      

  2.   

    接上面:
    头文件:
    #if !defined(AFX_LISTCTRLEX_H__E29BCEF5_3FCB_4A2E_8EFF_4C6DCCD6485C__INCLUDED_)
    #define AFX_LISTCTRLEX_H__E29BCEF5_3FCB_4A2E_8EFF_4C6DCCD6485C__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ListCtrlEx.h : header file
    //
    /////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // CListCtrlEx windowclass CListCtrlEx : public CListCtrl
    {
    // Construction
    public:
    CListCtrlEx();// Attributes
    public:// Operations
    public:
        int     HitTestEx (CPoint& Point, int& nSubItem);
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CListCtrlEx)
    //}}AFX_VIRTUAL// Implementation
    public:
    CEdit* EditSubItem(int nItem, int nSubItem);
    virtual ~CListCtrlEx();
    // Generated message map functions
    protected:
    //{{AFX_MSG(CListCtrlEx)
    afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LISTCTRLEX_H__E29BCEF5_3FCB_4A2E_8EFF_4C6DCCD6485C__INCLUDED_)第二个类:#include "stdafx.h"
    #include "ListCellEdit.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CListCellEditCListCellEdit:: CListCellEdit(int nItem, int nSubItem, CString strInitText)
    :m_bEscape (FALSE)
    {
        m_nItem = nItem;
        m_nSubItem = nSubItem;
        m_strInitText = strInitText;
    }CListCellEdit::~CListCellEdit()
    {
    }
    BEGIN_MESSAGE_MAP(CListCellEdit, CEdit)
    //{{AFX_MSG_MAP(CListCellEdit)
    ON_WM_KILLFOCUS()
    ON_WM_NCDESTROY()
    ON_WM_CHAR()
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CListCellEdit message handlersvoid CListCellEdit::OnKillFocus(CWnd* pNewWnd) 
    {
    CEdit::OnKillFocus(pNewWnd);

    // TODO: Add your message handler code here
    SetListItemText();    DestroyWindow();
    }void CListCellEdit::OnNcDestroy() 
    {
    CEdit::OnNcDestroy();

    // TODO: Add your message handler code here
        delete this;
    }BOOL CListCellEdit::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class
    if( pMsg->message == WM_KEYDOWN )
    {
    if(pMsg->wParam == VK_RETURN
    || pMsg->wParam == VK_DELETE
    || pMsg->wParam == VK_ESCAPE
    || GetKeyState( VK_CONTROL)
    )
    {
    ::TranslateMessage(pMsg);
    ::DispatchMessage(pMsg);
    return TRUE;      // DO NOT process further
    }
    }

    return CEdit::PreTranslateMessage(pMsg);
    }void CListCellEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    // TODO: Add your message handler code here and/or call default
    if( nChar == VK_ESCAPE || nChar == VK_RETURN)
    {
    if( nChar == VK_ESCAPE )
    m_bEscape = TRUE;
    GetParent()->SetFocus(); return;
    } // Resize edit control if needed
    // Get text extent
    CString str; GetWindowText( str );
    CWindowDC dc(this);
    CFont *pFont = GetParent()->GetFont();
    CFont *pFontDC = dc.SelectObject( pFont );
    CSize size = dc.GetTextExtent( str );
    dc.SelectObject( pFontDC );
    size.cx += 5;     // add some extra buffer // Get client rect
    CRect rect, parentrect;
    GetClientRect( &rect );
    GetParent()->GetClientRect( &parentrect ); // Transform rect to parent coordinates
    ClientToScreen( &rect );
    GetParent()->ScreenToClient( &rect ); // Check whether control needs to be resized
    // and whether there is space to grow
    if( size.cx > rect.Width() )
    {
    if( size.cx + rect.left < parentrect.right )
    rect.right = rect.left + size.cx;
    else
    rect.right = parentrect.right;
    MoveWindow( &rect );
    }

    CEdit::OnChar(nChar, nRepCnt, nFlags);
    }int CListCellEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CEdit::OnCreate(lpCreateStruct) == -1)
    return -1;

    // Set the proper font
    CFont* font = GetParent()->GetFont();
    SetFont(font); SetWindowText( m_strInitText );
    SetFocus();
    SetSel( 0, -1 );

    return 0;
    }void CListCellEdit::SetListItemText()
    {
        CString Text;
        GetWindowText (Text);    // Send Notification to parent of ListView ctrl
        LV_DISPINFO dispinfo;
        dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
        dispinfo.hdr.idFrom = GetDlgCtrlID();
        dispinfo.hdr.code = LVN_ENDLABELEDIT;    dispinfo.item.mask = LVIF_TEXT;
        dispinfo.item.iItem = m_nItem;
        dispinfo.item.iSubItem = m_nSubItem;
        dispinfo.item.pszText = m_bEscape ? NULL : LPTSTR ((LPCTSTR) Text);
        dispinfo.item.cchTextMax = Text.GetLength();    GetParent()->GetParent()->SendMessage (WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM) &dispinfo);
    }#if !defined(AFX_LISTCELLEDIT_H__3C59ACB3_1141_4A7F_8F72_37A4D9782868__INCLUDED_)
    #define AFX_LISTCELLEDIT_H__3C59ACB3_1141_4A7F_8F72_37A4D9782868__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ListCellEdit.h : header file
    //
    /////////////////////////////////////////
    /////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    // CListCellEdit windowclass CListCellEdit : public CEdit
    {
    // Construction
    public:
    CListCellEdit(int nItem, int nSubItem, CString strInitTex);
    void SetListItemText();// Attributes
    public:// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CListCellEdit)
    public:
    virtual BOOL PreTranslateMessage(MSG* pMsg);
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CListCellEdit();
     
    protected:
    int m_nItem;
        int m_nSubItem;
        CString m_strInitText;
        BOOL m_bEscape; // Generated message map functions
    //{{AFX_MSG(CListCellEdit)
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg void OnNcDestroy();
    afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LISTCELLEDIT_H__3C59ACB3_1141_4A7F_8F72_37A4D9782868__INCLUDED_)