티스토리 뷰


컨트롤에 대해서 더 알아보자.

이번에는 ListBox 라는 컨트롤에 대해서 알아볼 것이다. 기본 컨트롤 중 유일하게 자료구조를 가진다.

다른 컨트롤에 비해서 활용가치가 높기에 잘 알아두면 좋다. 문자열을 목록화 시켜 보여주고, 함수가 많고 다양한 사용방법이 있다. 


도구 상자에서 ListBox를 추가하고, Edit Control과 Button도 같이 추가해 보자.






리스트 박스를 쓰기 위해서 더블 클릭해 함수를 만드는 것보다 멤버 변수를 선언해주는 것이 좋기 때문에 멤버 변수를 선언해 준다. 선언 방법은 오른쪽 클릭해 변수 추가를 눌러주면 된다.






엑세스 부분은 public이 아닌 private 이나 protected로 변경해주는 변수 이름은 m_name_list로 해준다.

그리고 버튼 이름을 수정 후 더블 클릭해 함수를 추가해 준다.

추가한 함수에 아래의 소스를 추가 해준다.


void CExamListDlg::OnBnClickedAddBtn() {

CString str;

GetDlgItemText(IDC_EDIT1, str);


m_name_list.AddString(str);

}


CString으로 변수를 선언 뒤 Edit 창에서 가져온 문자열을 저장 후, 리스트 박스에 넣어 주는 소스이다.

AddString 함수는 위치와 상관없이 문자열을 추가하는 함수이다. 기본으로 오름차순으로 되어 있다.







Edit Control의 가나다를 제일 마지막에 적었지만 가나다 순으로 맨 앞에 들어간 것을 확인할 수 있다.


리스트 박스에 문자열을 추가하는 함수는 AddString말고 InsertString이라는 함수가 있다. 이 함수는 위치를 지정해 스트링을 추가하는 함수로, 위치 정보를 받기 때문에, 문자열이 저장된 변수 말고, 저장하고자는 위치의 인덱스 인자 총 2개가 필요하다. 


m_name_list.InserString(0, str);

맨 처음에 변수에 저장된 문자열을 추가하겠다는 의미로, 만약 0이 아닌 1로 했을때, 리스트 박스에 문자열이 추가되지 않는 빈 리스트인 경우에, .즉 0번째 값이 없는 상태에서 1번째에 값을 저장할 수 없다. 반면에 위치 지정 인덱스의 값을 -1로 할 때, 현재 추가한 위치에서 가장 마지막 위치에 넣겠다는 의미를 가진다.


void CExamListDlg::OnBnClickedAddBtn() {

CString str;

GetDlgItemText(IDC_EDIT1, str);

int index = m_name_list.AddString(str);

m_name_list.SetCurSel(index);


}


GetDlgItemText의 반환값은 추가된 인자의 인덱스이다. 그래서 이번에는 커서를 설정해주기 위해 SetCurSel이라는 함수를 사용할 것이다. 함수는 Set Current(현재) Select(선택)의 줄임말로 현재 위치를 설정한다는 것이다. 이 함수를 이용해 값이 들어갈 때마다 커서가 자동으로 현재 위치를 가리키게 된다. 






이번에는 추가된 내용을 삭제하도록 삭제 버튼을 추가해 보자. 삭제하려면 사용자가 어떤것을 선택하여 삭제하는지 알아야한다. 현재 위치를 즉 삭제하고자 하는 위치를 알아오기 위한 함수로 GetCurSel 함수를 사용한다.


void CExamListDlg::OnBnClickedDelBtn(){

int index = m_name_list.GetCurSel();


if(index != LB_ERR) {    //LB_ERR 은 -1로 define이 되어 있다. 

m_name_list.DeleteString(index);

}

}



삭제 전에 삭제할 것인지 묻는 대화상자를 띄어보자. 삭제 전에 내용물을 읽어와서 물어보고 Yes를 누르면 지우도록 하자. 그리고 삭제를 하게 되면 커서도 같이 삭제가 되기 때문에 커서는 삭제된 문자열의 아래 문자열을 가리키도록 구성을 해보자.


void CExamListDlg::OnBnClickedDelBtn(){

int index = m_name_list.GetCurSel();

if (LB_ERR != index) {    //커서가 설정된 경우에만 실행하겠다.

CString str;

m_name_list.GetText(index, str);

if (IDOK == MessageBox(str, L"아래의 이름을 삭제하시겠습니가?", MB_OKCANCEL | MB_ICONQUESTION))

//선택한 문자열에 대해 삭제할 것인지 확인하는 메시지를 띄운다. 확인을 누르면 IDOK 취소를 누르면 IDCANCLE이 반환된다.

{

m_name_list.DeleteString(index);    //문자열 삭제시 커서도 같이 삭제가 된다.

if (m_name_list.GetCount() > 0){

if( m_name_list.GetCount() == index) m_name_list.SetCurSel(index - 1);

else m_name_list.SetCurSel(index);

                            //m_name_list.SetCurSel(index - (m_name_list.GetCount() == index))

}

}

}

}







GetCount() 함수는 ListBox에 있는 문자열들이 몇개 있는지 알 수 있다. 


이제 커서를 이용해 선택한 내용이 Edit Control에 나오도록 하자.






LBN_SELCHANGE를 더블 클릭하여 추가해주면 된다. 아래와 같은 소스가 추가 해주면 된다.


void CExamListDlg::OnLbnSelchangeList1(){

int index = m_name_list.GetCurSel();

// 현재 선택한 상태의 인덱스를 얻어올 수 있다. 선택시 발생하는 함수이기에

// 에러체크를 따라 해줘도 의미가 없다.


CString str;


m_name_list.GetText(index, str);

// 사용자가 선택한 문자열을 가지고 온다.


SetDlgItemText(IDC_EDIT1, str);

//Edit Control에 사용자가 선택한 문자열을 표시해 준다.

}


위의 소스를 추가해주면 우리가 원하는 결과가 나오게 된다.




댓글