아주 오랜만에 컨트롤에 대하여 올려봅니다.
자주 않쓰다보니.. ^^;
리스트컨트롤을 사용하다 보면 서브아이템도 에디팅해야 할때가 있습니다.
요거 하나 쓸라구 클래스 만들기도 귀찬죠.. (이놈에 귀차니즘 -_-)
코드그루에 있는 자료를 좀 수정해서 사용해봅니다.
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;
}