[MFC] 리스트 컨트롤(List Control) 사용 방법

[MFC] 리스트 컨트롤 (List Control) 사용 방법


 

이번 포스팅에서는 MFC 컨트롤 중에 하나인 리스트 컨트롤(List Control) 사용 방법에 대해서 알아보도록 하겠습니다.

 

실제 저도 실무 프로젝트를 경험하면서 어떠한 파일을 읽고 그 데이터를 UI로 불러와서 사용자에게 보여주기 용도나 혹은 Database안에 있는 데이터 값을 가져와 원하는 자료 정보로써 사용자에게 정보 제공용으로 많이 사용하는 컨트롤로써 사용방법을 알게 되시면 실무에서 매우 유용하게 사용하실 수 있을 거라고 생각합니다.

 

MFC에서 제공해주는 리스트 컨트롤 클래스로는 CListCtrl 클래스가 있으면서 해당 클래스의 멤버 함수는 아래와 같이 제공해줍니다.

 

CList Ctrl 클래스 멤버 함수 종류


멤버 함수

설명

InsertColumn

새로운 컬럼을 추가합니다.

InsertItem

새로운 항목을 추가합니다.

DeleteItem

지정한 항목을 삭제합니다.

GetItemText

지정한 항목에서 텍스트를 얻습니다.

SetItemText

지정한 항목에서 텍스트를 설정합니다.

GetImageList

항목에 표시할 아이콘은 이미지 리스트에 저장되는데, 사용할 이미지 리스트를 얻습니다.

SetImageList

항목에 표시할 아이콘은 이미지 리스트에 저장되는데, 사용할 이미지 리스트를 설정합니다..

GetItemCount

항목의 개수를 얻습니다.

 


 

그렇다면 실제 위와 같은 멤버 함수들을 이용하여 어떻게 리스트 컨트롤을 선언하고 사용하는지 예제를 통하여 알아보도록 하겠습니다.


 

제일 첫 번째로, MFC 대화상자 기반의 프로젝트를 아래와 같은 방법으로 생성해 주시기 바랍니다.




그리고 위에 불필요한 컨트롤은 모두 지워 주시고 List Control을 아래와 같이 배치해 주시기 바랍니다.



그리고 List Control 속성에 가셔서 View속성을 Report로 수정해 주시기 바랍니다.



그리고 아래와 같이 List Control 멤버 변수와 Edit Control의 멤버변수를 각각 m_List, m_strName, m_strAge 라고 선언을 해주시기 바랍니다.


 



여기까지 모두 완료 하셨다면 이제 List Control 사용법을 아래 코드 및 주석을 통하여 설명을 하겠습니다.

 

아래와 같은 헤더파일과 cpp 파일에 코드를 알맞게 작성을 해주시기 바랍니다.


 

[testDlg.h]


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

 

// testDlg.h : 헤더 파일

//

 

#pragma once

#include "afxcmn.h"

 

 

// CtestDlg 대화 상자

class CtestDlg : public CDialogEx

{

// 생성입니다.

public:

    CtestDlg(CWnd* pParent = NULL);    // 표준 생성자입니다.

 

// 대화 상자 데이터입니다.

    enum { IDD = IDD_TEST_DIALOG };

 

    protected:

    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.

 

 

// 구현입니다.

protected:

    HICON m_hIcon;

 

    // 생성된 메시지  함수

    virtual BOOL OnInitDialog();

    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

    afx_msg void OnPaint();

    afx_msg HCURSOR OnQueryDragIcon();

    DECLARE_MESSAGE_MAP()

public:

    CListCtrl m_List;

    afx_msg void OnBnClickedButtonAdd();

    afx_msg void OnBnClickedButtonDelete();

    CString m_strName;

    CString m_strAge;

};

 

Colored by Color Scripter

cs

 

[testDlg.cpp]


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

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

 

// testDlg.cpp : 구현 파일

//

 

#include "stdafx.h"

#include "test.h"

#include "testDlg.h"

#include "afxdialogex.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

 

// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.

 

class CAboutDlg : public CDialogEx

{

public:

    CAboutDlg();

 

// 대화 상자 데이터입니다.

    enum { IDD = IDD_ABOUTBOX };

 

    protected:

    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.

 

// 구현입니다.

protected:

    DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)

{

}

 

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialogEx::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)

END_MESSAGE_MAP()

 

 

// CtestDlg 대화 상자

 

 

 

CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)

    : CDialogEx(CtestDlg::IDD, pParent)

    , m_strName(_T(""))

    , m_strAge(_T(""))

{

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CtestDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialogEx::DoDataExchange(pDX);

    DDX_Control(pDX, IDC_LIST3, m_List);

    DDX_Text(pDX, IDC_EDIT1, m_strName);

    DDX_Text(pDX, IDC_EDIT_AGE, m_strAge);

}

 

BEGIN_MESSAGE_MAP(CtestDlg, CDialogEx)

    ON_WM_SYSCOMMAND()

    ON_WM_PAINT()

    ON_WM_QUERYDRAGICON()

    ON_BN_CLICKED(IDC_BUTTON_ADD, &CtestDlg::OnBnClickedButtonAdd)

    ON_BN_CLICKED(IDC_BUTTON_DELETE, &CtestDlg::OnBnClickedButtonDelete)

END_MESSAGE_MAP()

 

 

// CtestDlg 메시지 처리기

 

BOOL CtestDlg::OnInitDialog()

{

    CDialogEx::OnInitDialog();

 

    // 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.

 

    // IDM_ABOUTBOX 시스템 명령 범위에 있어야 합니다.

    ASSERT((IDM_ABOUTBOX & 0xFFF0== IDM_ABOUTBOX);

    ASSERT(IDM_ABOUTBOX < 0xF000);

 

    CMenu* pSysMenu = GetSystemMenu(FALSE);

    if (pSysMenu != NULL)

    {

        BOOL bNameValid;

        CString strAboutMenu;

        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);

        ASSERT(bNameValid);

        if (!strAboutMenu.IsEmpty())

        {

            pSysMenu->AppendMenu(MF_SEPARATOR);

            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

        }

    }

 

    //  대화 상자의 아이콘을 설정합니다응용 프로그램의  창이 대화 상자가 아닐 경우에는

    //  프레임워크가  작업을 자동으로 수행합니다.

    SetIcon(m_hIcon, TRUE);            //  아이콘을 설정합니다.

    SetIcon(m_hIcon, FALSE);        // 작은 아이콘을 설정합니다.

 

    // 리스트 컨트롤의 크기를 얻어온다.

    CRect rect;

    m_List.GetClientRect(&rect);

 

    //리스트 컨트롤 컬럼 추가

    m_List.InsertColumn(0, _T("이름"), LVCFMT_LEFT, 300);

 

    //마지막에 추가할 컬럼의 폭은 리스트 컨트롤의 너비에서 이미 추가한

    //컬럼들의 너비를  값으로 하면 2개의 컬럼이 리스트 컨트롤에  맞게 됩니다.

    m_List.InsertColumn(1, _T("나이"), LVCFMT_LEFT, rect.Width() - 300);

 

    //서브 항목으로 추가할 데이터를 배열에 저장

    CString sampleName[] = { _T("홍길동"), _T("범범조조") };

    CString sampleAge[] = { _T("12"), _T("26") };

 

    for(int i = 0; i < 2; i++)

    {

        //이름 추가하기

        m_List.InsertItem(i, sampleName[i],i % 5);

 

        //나이 추가하기

        m_List.SetItemText(i, 1, sampleAge[i]);

    }

 

    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE 반환합니다.

}

 

void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

    if ((nID & 0xFFF0== IDM_ABOUTBOX)

    {

        CAboutDlg dlgAbout;

        dlgAbout.DoModal();

    }

    else

    {

        CDialogEx::OnSysCommand(nID, lParam);

    }

}

 

// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면

//  아래 코드가 필요합니다문서/ 모델을 사용하는 MFC 응용 프로그램의 경우에는

//  프레임워크에서  작업을 자동으로 수행합니다.

 

void CtestDlg::OnPaint()

{

    if (IsIconic())

    {

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

 

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

        // 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.

        int cxIcon = GetSystemMetrics(SM_CXICON);

        int cyIcon = GetSystemMetrics(SM_CYICON);

        CRect rect;

        GetClientRect(&rect);

        int x = (rect.Width() - cxIcon + 1/ 2;

        int y = (rect.Height() - cyIcon + 1/ 2;

 

        // 아이콘을 그립니다.

        dc.DrawIcon(x, y, m_hIcon);

    }

    else

    {

        CDialogEx::OnPaint();

    }

}

 

// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서

//   함수를 호출합니다.

HCURSOR CtestDlg::OnQueryDragIcon()

{

    return static_cast<HCURSOR>(m_hIcon);

}

 

 

 

void CtestDlg::OnBnClickedButtonAdd()

{

    //추가할 행의 위치를 얻어오기 위해서 리스트 컨트롤에 항목의 개수를 얻어온다.

    UpdateData(TRUE);

 

    int nItemNum = m_List.GetItemCount();

 

    CString name = m_strName;

    CString age = m_strAge;

 

    //이름 추가하기

    m_List.InsertItem(nItemNum, name, rand() % 5);

 

    //나이 추가하기

    m_List.SetItemText(nItemNum, 1, age);

    

    //에디트 컨트롤에 입력한 값을 리스트 컨트롤에 추가하였다면

    //에디트 컨트롤을 초기화 합니다.

 

    m_strName = _T("");

    m_strAge = _T("");

 

    UpdateData(FALSE);

}

 

 

void CtestDlg::OnBnClickedButtonDelete()

{

    int count = m_List.GetItemCount(); //리스트 컨트롤의 현재 항목 수를 얻어옵니다.

 

    for(int i =  count; i >= 0; i--)   //모든 항목을 조사하여

    {

        if(m_List.GetItemState(i, LVIS_SELECTED) != 0//선택된 항목을 삭제

        {

            m_List.DeleteItem(i);

        }

    }

}

 

Colored by Color Scripter

cs


설명은 위 코드에 주석을 통하여 모두 하였기 때문에 따로 

하지 않아도 충분히 따라 하시고 이해를 하실거라고 생각합니다.^^

 


 

실행 결과 화면


[1. 첫 실행 화면]




[2. 이름, 나이 추가]




[3. 이름, 나이 추가 출력]





[4. 특정 데이터 삭제]





[5. 특정 데이터 삭제 결과]




 

위와 같이 초기 설정한 값이 List Control에 제대로 출력이 되는 것을 확인 하실 수 있습니다. 또한, 데이터 추가 및 특정 데이터 삭제까지 모두 정상적으로 동작하는 것을 확인 하실 수 있습니다

이제 이러한 기초를 토대로 실제 실무에서 다양한 방법으로 List Control을 사용하시면서 실력을 키우시면 될 것 같습니다.

 

감사합니다.^^


728x90

이 글을 공유하기

댓글(4)

  • ljs0652
    2018.11.20 18:38

    질문이 있는데요 리스트 컨트롤 헤더 부분이 좀 얇게 나왔는데 어떻게 하신건지 여쭈어 봐도 될까요? 저는 직각처럼 뭉툭하게 나오거든요

  • 2018.11.20 19:39 신고

    리스트컨트롤 속성에서 View를 Report로 설정한것 말고는 저도 컬럼 크기나 디자인은 따로 하지 않은거라서요..

    • JNAM
      2019.01.27 20:18

      안녕하세요?

      질문있습니다. 4종류의 자료릴 입력하려고 합니다. 어느 부분을 추가/변경 해야 할까요?
      감사합니다.

    • 2019.01.29 21:55 신고

      음...4종류의 자료를 입력하시고 싶으시다고 하셨는데, 그냥 입력은 문자열로 하되, 향후에 입력한 문자를 숫자 또는 다른 자료형으로 형변환 또는 Parsing만 해줘서 가져와도 되지 않을까요? 굳이 입력부터 예를들어 숫자, 실수, 문자, 이렇게 따로따로 입력할 필요가 있는가 생각되네요!

Designed by JB FACTORY