MFC ListControl Column Check

C++/팁 2018. 10. 8. 13:47 |

이 문서는 Visual Studio 2013 환경에서 제작 되었습니다.

 

ListControl를 가공해서 사용할 경우 기존 코드와는 조금 다른 방식으로 사용해야 한다.

 

 

 

기본 방식

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void CTest::Init()
{
    CListCtrl m_ctrList_MESStatus; //리소스 뷰에서 리스트 컨트롤 변수 생성하면 생성 됨. 

 

    //ListControl 스타일 설정

    m_ctrList_MESStatus.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES 

   | LVS_EX_DOUBLEBUFFER);  

    

    //Column 생성    

    m_ctrList_MESStatus.InsertColumn(0, _T("CELL ID"), LVCFMT_CENTER, 230-1);

    m_ctrList_MESStatus.InsertColumn(1, _T("MES SEND"), LVCFMT_CENTER, 100-1);
    m_ctrList_MESStatus.InsertColumn(2, _T("MES RECIVE"), LVCFMT_CENTER, 100-1);
 
 
    int nCnt = 0;
    CString strIdx;
    nCnt = m_ctrList_MESStatus.GetItemCount();
    strIdx.Format(_T("%d"), nCnt + 1);
    
 
    //Row 생성 (실제 데이터)
    m_ctrList_MESStatus.InsertItem(nCnt, strIdx);
    m_ctrList_MESStatus.SetItem(nCnt, 1, LVIF_TEXT, _T("MES Send OK"), NULLNULLNULLNULL);
    m_ctrList_MESStatus.SetItem(nCnt++, 2, LVIF_TEXT, _T("MES Recive OK"), NULLNULLNULLNULL);
 
    m_ctrList_MESStatus.InsertItem(nCnt, strIdx);
    m_ctrList_MESStatus.SetItem(nCnt, 1, LVIF_TEXT, _T("MES Send zz"), NULLNULLNULLNULL);
    m_ctrList_MESStatus.SetItem(nCnt, 2, LVIF_TEXT, _T("MES Recive zx"), NULLNULLNULLNULL);
}
 
cs

 

 

위의 방식으로 스타일에서 체크박스를 적용할 경우 체크박스는 각 항목의 맨 오른쪽에 나타나게 된다.

 

이 체크박스를 하나하나 누르기 힘들기 때문에 컬럼 부분에 체크박스를 추가해서 전체 체크를 하려면 

 

아래와 같이 사용하면 된다.

 

가공 방식

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void CTest::Init()
{

    CWnd *m_CwndList; //변수 구분을 위해 여기에 표기. (헤더에 두고 사용 추천)

    m_CwndList = GetDlgItem(IDC_LIST_MES_NG_STATUS);
    ListView_SetExtendedListViewStyle(m_CwndList->m_hWnd, LVS_EX_DOUBLEBUFFER | 

    LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);

 
    // Add some columns to the list view control
    LVCOLUMN lvc = { 0 };
    ListView_InsertColumn(m_CwndList->m_hWnd, 0&lvc);
    lvc.mask = LVCF_TEXT;
    lvc.iSubItem++;
    lvc.pszText = _T("Cell ID");
    ListView_InsertColumn(m_CwndList->m_hWnd, 1&lvc);
    lvc.iSubItem++;
    lvc.pszText = _T("MES Send");
    ListView_InsertColumn(m_CwndList->m_hWnd, 2&lvc);
    lvc.iSubItem++;
    lvc.pszText = _T("MES Receive");
    ListView_InsertColumn(m_CwndList->m_hWnd, 3&lvc);
 
    // Set column widths
    ListView_SetColumnWidth(m_CwndList->m_hWnd, 0, LVSCW_AUTOSIZE_USEHEADER);
    ListView_SetColumnWidth(m_CwndList->m_hWnd, 1, LVSCW_AUTOSIZE_USEHEADER); //Cell ID
    ListView_SetColumnWidth(m_CwndList->m_hWnd, 2, LVSCW_AUTOSIZE_USEHEADER); //MES Send
    ListView_SetColumnWidth(m_CwndList->m_hWnd, 3, LVSCW_AUTOSIZE_USEHEADER); //MES Receive
    
    
    HWND header = ListView_GetHeader(m_ctrList_MESStatus);
    DWORD dwHeaderStyle = ::GetWindowLong(header, GWL_STYLE);
    dwHeaderStyle |= HDS_CHECKBOXES;
    ::SetWindowLong(header, GWL_STYLE, dwHeaderStyle);
 
    m_nListSelectIdx = ::GetDlgCtrlID(header);
 
    HDITEM hdi = { 0 };
    hdi.mask = HDI_FORMAT;
    Header_GetItem(header, 0&hdi);
    hdi.fmt |= HDF_CHECKBOX/* | HDF_FIXEDWIDTH*/;
    Header_SetItem(header, 0&hdi);}
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
BEGIN_MESSAGE_MAP(CTest, CDialogEx)
    ON_NOTIFY(HDN_ITEMSTATEICONCLICK, 0&CTest::OnHdnItemStateIconClickListMesNgStatus)
END_MESSAGE_MAP()
 
void CTest::OnHdnItemStateIconClickListMesNgStatus(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    
    LPNMHEADER pnmHeader = (LPNMHEADER)pNMHDR;
 
    if (pnmHeader->pitem->mask & HDI_FORMAT && pnmHeader->pitem->fmt & HDF_CHECKBOX) 
    {
        CheckAllItems(!(pnmHeader->pitem->fmt & HDF_CHECKED));
    }
    
    *pResult = 0;    
}
 
void CTest::CheckAllItems(BOOL bChecked)
{
    for (int nItem = 0; nItem < ListView_GetItemCount(m_CwndList->m_hWnd); nItem++
    {
        ListView_SetCheckState(m_CwndList->m_hWnd, nItem, bChecked);
    }
}
cs

 

HDN_ITEMSTATEICONCLICK 이벤트를 추가한 후 위와 같이 작성하면 컬럼 헤더에서 체크박스 클릭 시 전체 항목 선택

 

및 선택해제가 가능하다.

 

 

그리고 아이템 항목 추가는 아래와 같이 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void CTest::AddItem(CString strCellID, CString strSend, CString strReceive)
{
    CWnd *m_CwndList; //변수 구분을 위해 여기에 표기. (헤더에 두고 사용 추천)
    m_CwndList = GetDlgItem(IDC_LIST_MES_NG_STATUS);
 
    LVITEM lvi = { 0 };    lvi.iItem = ListView_GetItemCount(m_CwndList->m_hWnd);
    ListView_InsertItem(m_CwndList->m_hWnd, &lvi);
 
    lvi.mask = LVIF_TEXT;
    lvi.iSubItem = 1;
    lvi.pszText = (LPWSTR)(LPCWSTR)strCellID;
    ListView_SetItem(m_CwndList->m_hWnd, &lvi);
 
    lvi.iSubItem++;
    lvi.pszText = (LPWSTR)(LPCWSTR)strSend;
    ListView_SetItem(m_CwndList->m_hWnd, &lvi);
 
    lvi.iSubItem++;
    lvi.pszText = (LPWSTR)(LPCWSTR)strReceive;
    ListView_SetItem(m_CwndList->m_hWnd, &lvi);
}
 
cs

 

항목 삭제는 다음과 같이 한다.

 

1
2
3
4
5
6
7
8
void CTest::DeleteItem()
{
    CWnd *m_CwndList; //변수 구분을 위해 여기에 표기. (헤더에 두고 사용 추천)
    m_CwndList = GetDlgItem(IDC_LIST_MES_NG_STATUS);
    
    ListView_DeleteItem(m_CwndList->m_hWnd, ListView_GetItemCount(m_CwndList->m_hWnd) - 1);
}
 
cs

 

이 체크박스 전체 선택은 속성창에서 자체 해결 불가능하기 때문에 조금 불편하더라도 위와 같은 방식으로 ListControl을

 

가공하여 사용해야 한다.

Posted by 람뫼
: