리스트 박스를 사용하면서 주로 쓰이는 기능이 대표적으로 아이템의 추가, 삽입, 삭제 및 선택 기능이다. 기능은 단순하지만, 리스트 박스의 속성에 따라 동작 특성이나 메서드의 응답이 달라진다.

아래의 함수는 리스트박스에 긴 문자열이 들어갔을 경우, 수평 스크롤바를 생성시키는 코드이다.
이전 장에서 다룬것을 조금 확장한 것이고, 앞으로 리스트박스에서 항상 쓰일 함수이다.

static int GetTextLenEx(CListBox& box, LPCTSTR lpszText)
{
    CSize size;
    CDC *pDC = box.GetDC();
   
    CFont* pOld = pDC->SelectObject(box.GetFont());
    if ((box.GetStyle() & LBS_USETABSTOPS) == 0)
    {
        size = pDC->GetTextExtent(lpszText, _tcslen(lpszText));
        size.cx += 3;
    }
    else
    {
        size = pDC->GetTabbedTextExtent(lpszText, _tcslen(lpszText), 0, NULL);
        size.cx += 2;
    }
    pDC->SelectObject(pOld);
    box.ReleaseDC(pDC);
   
    return size.cx;
}
static void AddStringEx(CListBox& box, CString str, int ndx = -1)
{
    if(ndx == -1)
        box.AddString(str);
    else
        box.InsertString(ndx+1, str);
    int iExt = GetTextLenEx(box, str);
    if (iExt > box.GetHorizontalExtent())
        box.SetHorizontalExtent(iExt);
}

우선 리스트 박스 하나를 single 선택 모드로 예제를 하나 작성하였다.
리스트 박스를 선택할  속성에 따라 동작이 다름에 주의하여야 한다.


각각의 기능을 구현한 함수는 다음과 같다.

void CSssDlg::OnButton1()
{
    
AddStringEx(m_list"하나");  AddStringEx(m_list"");
    
AddStringEx(m_list"");     AddStringEx(m_list"");
    
AddStringEx(m_list"다섯");  AddStringEx(m_list"여섯");
    
AddStringEx(m_list"일곱");  AddStringEx(m_list"여덟");
    
AddStringEx(m_list"아홉");  AddStringEx(m_list"임의의 아이템을 10개를 리스트 박스에 삽입함.");
}

void CSssDlg::OnButton2()
{
    
UpdateData(TRUE);
    
AddStringEx(m_listm_str_insertm_list.GetCurSel());
}

void CSssDlg::OnButton3()
{
    
UpdateData(TRUE);

    
m_list.SetCurSel(m_sel_program);
}

void CSssDlg::OnButton4()
{
    
m_list.DeleteString(m_list.GetCurSel());
}

void CSssDlg::OnButton5()
{
    
m_list.ResetContent();
}
single 
선택 모드일 경우는 아이템을 하나씩만 선택할  있기 때문에선택이나 삭제가
위처럼 수월하게 이루어진다.

하지만 multiple extended  다중 선택할 경우.. GetCurSel 응답이 약간 달라진다.
single
   
아이템이 선택되었을 경우 : 선택된 아이템의 인덱스
   
아이템이 선택되어지지 않았을 경우 : -1
multiple or extended
   
아이템이 선택되었을 경우 : 최종 선택된 아이템의 인덱스
   
아이템이 선택되어지지 않았을 경우 : 0

일단 다중 선택이 가능한 상태에서 그럼 어떻게 여러개의 아이템이 선택되어 졌는지를
인식하고 항목들을 가져   있는지 살펴보자.

void DoSomething(CListBoxbox)
{
    
// 몇개의 아이템이 선택되어졌는지 카운트
    
int nCount = box.GetSelCount();

    
// 선택되어진 아이템이 하나도 없으면 리턴.
    
if(nCount <= 0)
        
return;

    
// 배열을 하나 만들고크기를 설정한다.
    
CArray<int,intaryListBoxSel;
    
aryListBoxSel.SetSize(nCount);

    
// 아이템중에서 선택되어진 인덱스를 배열에 읽어온다.
    
box.GetSelItems(nCountaryListBoxSel.GetData());

    
for(int i=0i<nCounti++)
    {
         
// 선택된걸 하나씩 뽑아서 먼가 처리를 하겠지...
         
int sel = aryListBoxSel[i];

        
// do something...
    }
}

위의 함수에서 보았듯이 여러개의 아이템이 선택되어져 있을 경우먼저 선택 아이템 카운트를
읽어온다음 인덱스를 배열에 읽어오는 과정을 거친다.

그럼 다중 선택일 경우에 선택아이템을 지우는 버튼의 코드를 수정해보자.

싱글 선택일 경우는 아래와 같았다.
void CSssDlg::OnButton4()
{
    
m_list.DeleteString(m_list.GetCurSel());
}

멀티 선택일 경우는 다음과 같다.
void CSssDlg::OnButton4()
{
    
int nCount = box.GetSelCount();
    
if(nCount <= 0)
        
return;

    
CArray<int,intaryListBoxSel;
    
aryListBoxSel.SetSize(nCount);
    
box.GetSelItems(nCountaryListBoxSel.GetData());

    
// 앞에꺼 부터 지우게 되면 뒤쪽의 저장해 놓은 인덱스 정보가 틀어지게 되므로
    
// 뒤에꺼 부터 앞으로 하나씩 지우면 된다.
    
for(int i=nCount-1i>=0i--)
          
m_list.DeleteString(aryListBoxSel[i]);
}

86.zip
0.03MB

+ Recent posts