Visual C++/CListCtrl with CView

CListCtrl with CView in MFC

Soul-Learner 2013. 6. 24. 21:02

프로젝트를 생성할 때 CView 기반으로 뷰클래스를 설정하고 프로젝트가 생성된 후에 뷰 클래스에 멤버변수로 CListCtrl 을 선언한다


//CMyView.h

#pragma once


class CMyView : public CView

{

protected: // serialization에서만 만들어집니다.

CMyView();

DECLARE_DYNCREATE(CMyView)


// 특성입니다.

public:

CMyDoc* GetDocument() const;

CListCtrl m_ListCtrl;



CMyView.cpp 파일을 열고  함수에 다음과 같이 입력한다

void CMyView ::OnInitialUpdate()

{

CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class


m_ListCtrl.Create(

        WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS,

        CRect(0,0,800,500), this, NULL);

m_ListCtrl.SetExtendedStyle( LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

m_ListCtrl.DeleteAllItems();

m_ListCtrl.InsertColumn(0, _T("순번"), LVCFMT_LEFT, 40, -1); 

m_ListCtrl.InsertColumn(1, _T("환자이름"), LVCFMT_LEFT, 70, -1); 

m_ListCtrl.InsertColumn(2, _T("환자번호"), LVCFMT_LEFT, 70, -1); 

m_ListCtrl.InsertColumn(3, _T("환자성별"), LVCFMT_LEFT, 70, -1);

m_ListCtrl.InsertColumn(4, _T("진료날짜"), LVCFMT_LEFT, 70, -1); 

m_ListCtrl.InsertColumn(5, _T("사진파일"), LVCFMT_LEFT, 600, -1); 

//칼럼 추가 인덱스, 칼람명, 정렬방향, 칼럼길이, 서브아이템 갯수

int seq = 0; 

CString seq_string; 

seq_string.Format(_T("%d"),seq); 

CString patientName =_T("홍길동"); 

CString patientID =_T("365412");

CString patientSex =_T("M"); 

CString studyDate =_T("20120321"); 

CString dcmFullPath =_T("D:\\DCM ROOT\\365412\\20123021\\홍길동.dcm");


m_ListCtrl.InsertItem(seq,seq_string); 

m_ListCtrl.SetItem(seq,1,LVIF_TEXT,patientName,0,0,0,NULL);

m_ListCtrl.SetItem(seq,2,LVIF_TEXT,patientID,0,0,0,NULL);

m_ListCtrl.SetItem(seq,3,LVIF_TEXT,patientSex,0,0,0,NULL); 

m_ListCtrl.SetItem(seq,4,LVIF_TEXT,studyDate,0,0,0,NULL); 

m_ListCtrl.SetItem(seq,5,LVIF_TEXT,dcmFullPath,0,0,0,NULL); 


seq = 1; 

seq_string.Format(_T("%d"),seq); 

patientName =_T("박환자"); 

patientID =_T("145632");

patientSex =_T("F"); 

studyDate =_T("20130215"); 

dcmFullPath =_T("D:\\DCM ROOT\\145632\\20130215\\박환자.dcm");


m_ListCtrl.InsertItem(seq,seq_string);

m_ListCtrl.SetItem(seq,1,LVIF_TEXT,patientName,0,0,0,NULL); 

m_ListCtrl.SetItem(seq,2,LVIF_TEXT,patientID,0,0,0,NULL);

m_ListCtrl.SetItem(seq,3,LVIF_TEXT,patientSex,0,0,0,NULL);

m_ListCtrl.SetItem(seq,4,LVIF_TEXT,studyDate,0,0,0,NULL); 

m_ListCtrl.SetItem(seq,5,LVIF_TEXT,dcmFullPath,0,0,0,NULL); 

}



위의 코드를 빌드하고 실행하면 다음과 같이 CListCtrl 이 제대로 작동하는 것을 볼 수 있다.


위의 코드만으로도 데이터를 정렬하여 출력하는데는 문제가 없지만 리스트에서 클릭하거나 더블클릭하더라도 아무런 반응이 없으므로 리스트를 사용하기 위해서는 메시지 핸들러가 필요함을 알 수 있다.


메시지 핸들러 함수는 CListCtrl 클래스를 상속하여 하위 클래스를 정의하고 그 안에 메시지 핸들러 함수를 정의할 수 있기 때문에 CListCtrl 클래스를 상속하여 새로운 하위 콘트롤을 새로 생성해야 함을 의미한다. CListCtrl 클래스를 상속한 하위 클래스가 DCMListCtrl 이라고 할 때, Class View 에서 DCMListCtrl 클래스에 마우스 우측을 눌러 Class Wizard를 열고 Messages 탭을 선택하여 NM_DBLCLK 메시지를 더블클릭하여 OnNMDblclk() 핸들러를 코드에 추가하고 다음과 같이 입력하면 리스트 항목에서 더블클릭할 경우 해당 행의 정보를 가져와서 보여줄 수 있게 된다. 뷰 클래스를 새로 생성하는 것이 아니라 뷰 클래스는 위의 것을 그대로 사옹하고 콘트롤 클래스를 새로 생성하여 뷰 클래스에서 사용함을 의미한다 단지 뷰 클래스에서는 멤버변수의 자료형만 변경해주면 된다.


헤더파일을 열고 아래처럼 변경한다

//CMyView.h

#include "DCMListCtrl.h"

#pragma once


class CMyView : public CView

{

protected: // serialization에서만 만들어집니다.

CMyView();

DECLARE_DYNCREATE(CMyView)


// 특성입니다.

public:

CMyDoc* GetDocument() const;

//CListCtrl m_ListCtrl;

        DCMListCtrl m_ListCtrl; // CListCtrl 대신에 CListCtrl 클래스의 하위 클래스로 생성한 DCMListCtrl 클래스를 사용한다



DCMListCtrl.cpp ( CListCtrl 의 하위 클래스로 생성한 DCMListCtrl 클래스에 NM_DBLCLK 메시지 핸들러를 추가한다 )

// ON_NMDBLCLK 메시지 핸들러를 추가한다

void DCMListCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)

{

LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

*pResult = 0;

// TODO: Add your control notification handler code here

//AfxMessageBox(_T("더블클릭"));

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

int itemindex = pNMListView->iItem;

 

if( itemindex != -1 )

{

CString strNum = GetItemText( itemindex, 0 );

    CString strValue = GetItemText( itemindex, 1 );

    CString strFileName = GetItemText( itemindex, 5 );

    AfxMessageBox(strNum+", "+strValue+", "+strFileName);

}

*pResult = 0;

}



위의 코드를 빌드하고 실행하여 출력된 리스트에서 두번째 행을 더블클릭했을 경우에 아래처럼 보이게 된다