본문 바로가기
프로그래머의 길/C & C++

에디트 가능한 리스트컨트롤

by 제이콥케이 2012. 11. 12.
반응형

1. 리스트 컨트롤 변수, 위치기억 변수 생성
- CListCtrl m_editListCtrl;
- int iSavedItem, iSavedSubitem;

2. 에디트 컨트롤 생성
- ID : IDC_EDIT_MODIFY

3. OnInitDialog에서 샘플 데이터를 넣어놓고, 2번에서 만든 에디트 컨트롤을 숨신다

BOOL CxxxxDlg::OnInitDialog()
{
CDialog::OnInitDialog();

..........................
m_editListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

m_editListCtrl.InsertColumn(0, _T("FIELD1"), LVCFMT_LEFT, 100);
m_editListCtrl.InsertColumn(1, _T("FIELD2"), LVCFMT_LEFT, 100);
m_editListCtrl.InsertColumn(2, _T("FIELD3"), LVCFMT_LEFT, 100);

m_editListCtrl.InsertItem(0, _T("1111"));
m_editListCtrl.SetItem(0, 1, LVIF_TEXT, _T("2222"), 0, NULL, NULL, NULL);
m_editListCtrl.SetItem(0, 2, LVIF_TEXT, _T("3333"), 0, NULL, NULL, NULL);

}

4. 더블클릭시에
1) 클릭한 위치가 리스트컨트롤에서 유효한 행, 열이면 에디트 박스를 위치시킨다
2) subitem의 위치가 0번이면 따로 계산을 한다(전체행을 가리키는 위치가 나오므로)

void CxxxxDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMITEM = (LPNMITEMACTIVATE) pNMHDR;

iSavedItem = pNMITEM->iItem;
iSavedSubitem = pNMITEM->iSubItem;

if(pNMITEM->iItem != -1)
{
CRect rect;

if(pNMITEM->iSubItem == 0)
{
m_editListCtrl.GetItemRect(pNMITEM->iItem, rect, LVIR_BOUNDS);
rect.right = rect.left + m_editListCtrl.GetColumnWidth(0);
}
else
{
m_editListCtrl.GetSubItemRect(pNMITEM->iItem, pNMITEM->iSubItem, LVIR_BOUNDS, rect);
}

m_editListCtrl.ClientToScreen(rect);
this->ScreenToClient(rect);

GetDlgItem(IDC_EDIT_MOD)->SetWindowText(m_editListCtrl.GetItemText(pNMITEM->iItem, pNMITEM->iSubItem));
GetDlgItem(IDC_EDIT_MOD)->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW );
GetDlgItem(IDC_EDIT_MOD)->SetFocus();
}
*pResult = 0;
}

5. 클릭시에는 위치만 기억해놓는다

void CxxxxDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMITEM = (LPNMITEMACTIVATE) pNMHDR;

iSavedItem = iSavedSubitem = -1;
GetDlgItem(IDC_EDIT_MOD)->SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW );

if(pNMITEM->iItem != -1)
{
iSavedItem = pNMITEM->iItem;
iSavedSubitem = pNMITEM->iSubItem;
}
*pResult = 0;
}

6. F2키를 누르면, 마지막에 선택되었던 위치의 행, 열 값을 수정한다

void CxxxxDlg::OnLvnKeydownList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);

if(pLVKeyDow->wVKey == VK_F2)
{
if( iSavedItem != -1 )
{
CRect rect;

if(iSavedSubitem == 0)
{
m_editListCtrl.GetItemRect(iSavedItem, rect, LVIR_BOUNDS);
rect.right = rect.left + m_editListCtrl.GetColumnWidth(0);
}
else
{
m_editListCtrl.GetSubItemRect(iSavedItem, iSavedSubitem, LVIR_BOUNDS, rect);
}

m_editListCtrl.ClientToScreen(rect);
this->ScreenToClient(rect);

GetDlgItem(IDC_EDIT_MOD)->SetWindowText(m_editListCtrl.GetItemText(iSavedItem, iSavedSubitem));

GetDlgItem(IDC_EDIT_MOD)->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW );
GetDlgItem(IDC_EDIT_MOD)->SetFocus();
}
}
*pResult = 0;
}

7. 에디트박스에서 엔터키를 누르면, 리스트컨트롤에 값을 적용한다

BOOL CxxxxDlg::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){

if(pMsg->hwnd == GetDlgItem(IDC_EDIT_MOD)->GetSafeHwnd())
{
CString str;
GetDlgItemText(IDC_EDIT_MOD, str);
m_editListCtrl.SetItemText(iSavedItem, iSavedSubitem, str);

GetDlgItem(IDC_EDIT_MOD)->SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW );
}

return TRUE;
}

if(pMsg->wParam == VK_ESCAPE)
{
return TRUE;
}
}

return CDialog::PreTranslateMessage(pMsg);
}


 

반응형