아주 오랜만에 컨트롤에 대하여 올려봅니다.
자주 않쓰다보니.. ^^;

리스트컨트롤을 사용하다 보면 서브아이템도 에디팅해야 할때가 있습니다.
요거 하나 쓸라구 클래스 만들기도 귀찬죠.. (이놈에 귀차니즘 -_-)

코드그루에 있는 자료를 좀 수정해서 사용해봅니다.
http://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/article.php/c1077/

위 자료인데요..
이것도 리스트를 서브클래싱해야되나서 좀 수정해서 걍 그런거 없이 써봅시다.

요건 에디트컨트롤 서브클래싱한 클래스인데요..
않한다면서도 필요하내요 -_-;;;

/////////////////////////////////////////////////
// 에디트컨트롤 헤더

class CLVEdit : public CEdit
{
// Construction
public:
   CLVEdit() { m_nEdit=-1; }
   void BeginEdit(CListCtrl* pList, int ndx);
   void EndEdit(CListCtrl* pList, NMHDR* pNMHDR);

// Attributes
public:
   CRect m_rc;
   BOOL  m_nEdit;

protected:
   //{{AFX_MSG(CLVEdit)
   afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////////////////////////////
// 에디트 컨트롤 소스

BEGIN_MESSAGE_MAP(CLVEdit, CEdit)
   //{{AFX_MSG_MAP(CLVEdit)
   ON_WM_WINDOWPOSCHANGING()
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CLVEdit::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
   lpwndpos->x=m_rc.left;
   lpwndpos->y=m_rc.top;

   if(m_rc.Width() > 0)
      lpwndpos->cx = m_rc.Width();
   if(m_rc.Height() > 0)
      lpwndpos->cy = m_rc.Height();

   CEdit::OnWindowPosChanging(lpwndpos);
}

void CLVEdit::BeginEdit(CListCtrl* pList, int ndx)
{
    CPoint posMouse;
    GetCursorPos(&posMouse);
    pList->ScreenToClient(&posMouse);

    LV_COLUMN lvc;
    lvc.mask=LVCF_WIDTH;

    CRect rcItem;
    pList->GetItemRect(ndx,rcItem,LVIR_LABEL);

    if(rcItem.PtInRect(posMouse))
        m_nEdit=0;

    int nCol=1;
    while(m_nEdit==-1 && pList->GetColumn(nCol,&lvc))
    {
        rcItem.left=rcItem.right;
        rcItem.right+=lvc.cx;

        if(rcItem.PtInRect(posMouse))
            m_nEdit=nCol;

        nCol++;
    }

    if(m_nEdit==-1)
       return;
   
    m_rc = rcItem;
    SetWindowText(pList->GetItemText(ndx, m_nEdit));
}

void CLVEdit::EndEdit(CListCtrl* pList, NMHDR* pNMHDR)
{
     LV_DISPINFO* pDispInfo=(LV_DISPINFO*)pNMHDR;
     CString sEdit=pDispInfo->item.pszText;
 
    if(!sEdit.IsEmpty())
       pList->SetItemText(pDispInfo->item.iItem,m_nEdit,sEdit);
 
    m_nEdit=-1;
    pList->SetItemState(pDispInfo->item.iItem,0,LVNI_FOCUSED|LVNI_SELECTED);
}



위의 헤더와 소스를 걍 Paste 하시거나 파일로 만들어서 첨부하시면 되구요..
다이알로그나 뷰등에서 리스트 컨트롤을 올려다가 사용하실 때..
다음과 같이 처리하시면 됩니다.

헤더에 아래를 하나 선언한다.
CLVEdit m_LVEdit;

소스에서 각 이벤트를 다음과 같이 핸들링한다.
void 마이다이알로그::OnBeginlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LV_DISPINFO* pDispInfo=(LV_DISPINFO*)pNMHDR;
    *pResult=1;

    // 리스트컨트롤에 내장된 에디트컨트롤을 내가 맹글걸로 연결한다.
    HWND hWnd=(HWND)m_list.SendMessage(LVM_GETEDITCONTROL);
    ASSERT(hWnd!=NULL);
    VERIFY(m_LVEdit.SubclassWindow(hWnd));

    // 내부에서 좌표찾아서 에디트를 적당한 곳에 위치시킨다.
    m_LVEdit.BeginEdit(&m_list, pDispInfo->item.iItem);
    *pResult=0;
}

void 마이다이알로그::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LV_DISPINFO* pDispInfo=(LV_DISPINFO*)pNMHDR;
 
    // 에디트가 끝나면 그 값을 읽어다가, 선택된 셀에다가 쓴다.
    m_LVEdit.EndEdit(&m_list, pNMHDR);

    // 연결시킨걸 해제한다.
    VERIFY(m_LVEdit.UnsubclassWindow()!=NULL);

    *pResult=0;
}

+ Recent posts