제 8 장컨트롤과리소스 II 8.1 탭컨트롤 8.2 슬라이더컨트롤실습 8-1 도형의종류와색상출력하기 8.3 스핀컨트롤 8.4 프로그레스바컨트롤 8.5 IP 주소컨트롤 8.6 네트워크주소컨트롤 8.7 날짜 / 시간컨트롤 8.8 애니메이트컨트롤실습 8.2 데이터전송시뮬레이터작성하기
컨트롤및리소스 리스트컨트롤 (List Control) 트리컨트롤 (Tree Control) 탭컨트롤 (Tab Control) 슬라이드컨트롤 (Slider Control) 스핀컨트롤 (Spin Control) 프로그레스바컨트롤 (Progress Bar Control) IP 주소컨트롤 (IP Address Control) 네트워크주소컨트롤 (Network Address Control) 날짜 / 시간컨트롤 (Date Time Picker) 애니메이트컨트롤 (Animate Control)
탭컨트롤 탭컨트롤은정보를분류하고자할때사용 주어진탭을선택함에따라해당하는정보를분류하여보여준다. 작은대화상자안에많은정보를표현하고자할때많이사용된다.
슬라이더컨트롤 슬라이드컨트롤은주어진범위의값이나비연속적인값을입력하고자할때사용 주어진범위안에서마우스를드래그함으로써값을증가, 감소할수있게하는컨트롤이다.
슬라이더컨트롤 슬라이더컨트롤의주요멤버함수 SetRange() 함수 슬라이더컨트롤의상, 하위범위를설정하는함수 SetRange(int nmin, int nmax, BOOL bredraw=false); GetPos() 함수 슬라이더컨트롤의현재위치를반환하는함수 SetPos(int npos) 함수 슬라이더컨트롤의위치를설정하는함수
스핀컨트롤 스핀컨트롤 스핀컨트롤은두개의작은화살표버튼으로구성되어일정한범위의값을입력할때사용 화살표방향은스타일설정에따라변할수있다. 버디컨트롤 일반적으로에디트박스에붙여서사용하는경우가많다. 이런경우를버디컨트롤이라한다.
실습 8-1 도형의종류와색상을대화상자에출력하기 Tab Control 을이용해도형선택항목과색상선택항목을분류하며, Slider Control 을이용해빨강, 청록, 파랑각각의색상을선택하는인터페이스를제작한다. 버디컨트롤을이용하여도형의크기를조절한다. 선택된도형을각각의색상을조합하여대화상자에도형을출력해보는프로그램을작성해보자.
실습 8-1 도형의종류와색상을대화상자에출력하기
TC_ITEM 구조체 탭컨트롤의아이템을삽입하거나얻어올때사용하는구조체 구조체의원형 Typedef struct tagtcitem { Unit mask; // 얻거나설정하기위한유효한마스크 DWORD dwstate; // 탭컨트롤아이템의현재상태표시 DWORD dwstatemask; // dwstate 멤버인비트를명시 LPTSTR psztext; // 텝아이템에나타나는문자열 Int cchtextmax; // psztext의버퍼의크기 Int iimage; // 탭컨트롤이미지리스트의인텍스 LPARAM lparam // 데이터애플리케이션 } TCITEM, FAR *LPTCTIEM;
실습 8-1 프로그램작성순서 프로그램작성순서 1) 대화상자기반의프로젝트를생성한다 2) 대화상자에컨트롤을배치하고속성을설정한다. Picture 컨트롤, Tab 컨트롤, 라디오버튼, 슬라이더컨트롤, 에디트컨트롤, 스핀컨트롤등 3) 각컨트롤들을멤버변수에연결한다. 클래스마법사사용 ( 멤버변수 Tab) Tab 컨트롤, 슬라이더컨트롤, 에디트박스
실습 8-1 프로그램작성순서 4) 대화상자클래스에멤버변수를추가한다. 도형의종류를저장하기위한변수 도형의색상을저장하기위한변수 5) 각컨트롤들을초기화한다. OnInitDialog() 함수에서처음보여질탭과컨트롤들을초기화한다. 6) 탭컨트롤에대한메시지핸들러함수를만든다. 탭선택에따라적당한컨트롤들을보여지게한다. 7) 도형선택을위해라디오버튼에대한메시지핸들러함수를만든다.
실습 8-1 프로그램작성순서 8) 도형을그린다. OnPaint() 함수에도형을그리는코딩을한다. 9) 색상선택을위한슬라이더컨트롤에대한메시지핸들러함수를만든다. 10) 크기조정을위한버디컨트롤을대한핸들러함수를만든다. 11) 각컨트롤들을재배치한다. 12) 프로그램을실행시킨다.
실습 8-1 실행결과
프로그레스바컨트롤 프로그레스바컨트롤은어떤작업의진행상황을표현하는데유용하게사용된다. 다른컨트롤같이임의의데이터입력에는사용될수없다. 이컨트롤은작업의진행상황을시각적으로표현해줌으로써사용자에게다른작업을할시간을준다.
IP 주소컨트롤 IP 주소컨트롤 인터넷프로토콜 (IP) 형식의주소만입력가능 세자릿수의네개의필드로구성 0 ~ 255 까지만입력가능 각필드입력시세자리가채워지면자동으로우측필드로이동
네트워크주소컨트롤 윈도우비스타이상의운영체제에서만사용되는컨트롤 IPv4, IPv6, URL 숫자주소를입력할수있게형식을고정하지않았음 사용자가주소가잘못입력되면검사하여문제가있으면사용자에게알려줌
날짜 / 시간선택컨트롤 날짜 / 시간선택컨트롤은직관적으로특정날짜를선택하는컨트롤 인터페이스는콤보박스와유사하나컨트롤을확장하면특정날짜를지정할수있는 Month Calendar 컨트롤이표시된다. Short Date 형식 Long Date 형식 Time 형식
애니메이트컨트롤 애니메이트컨트롤은 AVI 동영상파일을재생하고제어하는데사용된다. AVI 파일이란 RLE(Run-Length Encoding) 을사용해압축한파일과압축하지않은파일두가지이다. 애니메이트컨트롤은사운드를지원하지않는다.
실습 8-2 데이터전송시뮬레이터작성하기 이번실습에서는 IP 주소를입력하기위해 IP Address Control 을사용하고전송날짜를제어하기위해 Date Time Picker Control 을이용하게된다. 또한데이터전송값을입력하기위해 Buddy control 을사용하고, Progress Bar Control 을이용하여전송진행률을표현하는프로그램을작성하는것이다.
실습 8-2 프로그램작성순서 1) 대화상자기반의프로젝트를생성한다. 2) 대화상자에컨트롤을배치하고속성을설정한다. IP Address 컨트롤, Progress Bar 컨트롤, Date Time Picker 컨트롤, Buddy 컨트롤, Edit Control 3) 각컨트롤을멤버변수와연결한다. 클래스마법사사용 ( 멤버변수 Tab) IP Address, Progress Bar, Date Time Picker, Edit Control
실습 8-2 프로그램작성순서 4) 대화상자클래스에멤버변수를선언한다. 데이터전송율을저장하기위한변수 5) 컨트롤을초기화한다. OnInitDialog() 함수에서프로그레스바를초기화한다. 6) 데이터전송에관한함수를만든다. 데이터전송시작버튼에대한메시지핸들러함수를만든다. 데이터전송상황을업데이트할수있도록타이머함수를작성한다.
실습 8-2 프로그램작성순서 전송할데이터크기를증가또는감소하기위한스핀컨트롤에대한함수를작성한다. 7) 프로그램을실행시킨다.
실습 8-2 실행결과
연습문제 8-1 여러가지컨트롤을이용하여, 사용자로부터원의확대 / 축소비율을입력받아, 그비율에따른애니메이션을수행하는프로그램을작성하도록한다.
연습문제 8-1 실행예
BOOL CExercise8_1Dlg::OnInitDialog() m_bsameratio = TRUE; m_nhorizontal = 50; m_nvertical = 50; m_ncurhscale = 50; m_ncurvscale = 50; m_sliderhorizontal.setrange(0, 100); m_slidervertical.setrange(0, 100); m_sliderhorizontal.setpos(50); m_slidervertical.setpos(50); m_prgsscale.setrange(0, 100); m_sliderscale.setrange(0, 100); m_prgsscale.setpos(0); m_sliderscale.setpos(0); UpdateData(FALSE); ((CButton*) GetDlgItem(IDC_CHECK_SAME_RATIO))->SetCheck(TRUE); return TRUE; // 포커스를컨트롤에설정하지않으면 TRUE 를반환합니다. } { { } { } void CExercise8_1Dlg::OnSysCommand(UINT nid, LPARAM lparam) if ((nid & 0xFFF0) == IDM_ABOUTBOX) CAboutDlg dlgabout; dlgabout.domodal(); else CDialogEx::OnSysCommand(nID, lparam);
void CExercise8_1Dlg::OnPaint() CRect rectview, rectfigure; GetDlgItem(IDC_STATIC_VIEW)->GetWindowRect(&rectView); CPoint ptcenter = rectview.centerpoint(); ScreenToClient(&ptCenter); rectfigure.left = ptcenter.x - (int)(rectview.width()/2.0 * m_ncurhscale/100.0); rectfigure.right = ptcenter.x + (int)(rectview.width()/2.0 * m_ncurhscale/100.0); rectfigure.top = ptcenter.y - (int)(rectview.height()/2.0 * m_ncurvscale/100.0); rectfigure.bottom = ptcenter.y + (int)(rectview.height()/2.0 * m_ncurvscale/100.0); CClientDC dc(this); CBrush NewBrush, *oldbrush; NewBrush.CreateSolidBrush(RGB(255,0,0)); oldbrush = dc.selectobject(&newbrush); dc.ellipse(&rectfigure); dc.selectobject(oldbrush); NewBrush.DeleteObject();
void CExercise8_1Dlg::OnClickedCheckSameRatio() UpdateData(TRUE); { { m_bsameratio =!m_bsameratio; if (m_bsameratio) if (m_ncurhscale > m_ncurvscale) m_nhorizontal = m_sliderhorizontal.getpos(); m_nvertical = m_nhorizontal; } { else m_nvertical = m_slidervertical.getpos(); m_nhorizontal = m_nvertical; } m_ncurhscale = m_nhorizontal; m_ncurvscale = m_nvertical; m_slidervertical.setpos(m_nvertical); m_sliderhorizontal.setpos(m_nvertical); UpdateData(FALSE); } m_prgsscale.setpos(0); m_sliderscale.setpos(0); Invalidate();
void CExercise8_1Dlg::OnClickedButtonScale() UpdateData(TRUE); m_nanihscale = 0; m_nanivscale = 0; { if (m_nhorizontal >= m_nvertical) m_prgsscale.setrange(0, m_nhorizontal); m_sliderscale.setrange(0, m_nhorizontal); } { else m_prgsscale.setrange(0, m_nvertical); m_sliderscale.setrange(0, m_nvertical); } SetTimer(1, 30, NULL); GetDlgItem(IDC_BUTTON_SCALE)->EnableWindow(FALSE); UpdateData(FALSE); Invalidate();
void CExercise8_1Dlg::OnTimer(UINT_PTR nidevent) UpdateData(TRUE); CRect rectview, rectfigure; GetDlgItem(IDC_STATIC_VIEW)->GetWindowRect(&rectView); ScreenToClient(&rectView); { { if (m_nhorizontal >= m_nvertical) if (m_nanihscale!= m_nhorizontal) m_nanihscale++; m_nanivscale=(int)((float)m_nanihscale * ((float)m_nvertical/ (float)m_nhorizontal)); m_ncurhscale = m_nanihscale; m_ncurvscale = m_nanivscale; } m_prgsscale.setpos(m_ncurhscale); m_sliderscale.setpos(m_ncurhscale);
void CExercise8_1Dlg::OnTimer(UINT_PTR nidevent) { } } { { else KillTimer(1); GetDlgItem(IDC_BUTTON_SCALE)->EnableWindow(TRUE); else if (m_nanivscale!= m_nvertical) m_nanivscale++; m_nanihscale++; m_nanihscale=(int)((float)m_nanivscale * ((float)m_nhorizontal/ (float)m_nvertical)); m_ncurhscale = m_nanihscale; m_ncurvscale = m_nanivscale; } { m_prgsscale.setpos(m_ncurvscale); m_sliderscale.setpos(m_ncurvscale); else KillTimer(1); GetDlgItem(IDC_BUTTON_SCALE)->EnableWindow(TRUE); } } UpdateData(FALSE); InvalidateRect(&rectView);
void CExercise8_1Dlg::OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar) CRect rectview; GetDlgItem(IDC_STATIC_VIEW)->GetWindowRect(&rectView); ScreenToClient(&rectView); if( pscrollbar->getsafehwnd() == m_sliderhorizontal.m_hwnd ) { { } { } if(m_bsameratio == TRUE) m_ncurhscale = m_sliderhorizontal.getpos(); m_ncurvscale = m_sliderhorizontal.getpos(); m_slidervertical.setpos(m_ncurhscale); else m_ncurhscale = m_sliderhorizontal.getpos(); m_ncurvscale = m_slidervertical.getpos(); m_nhorizontal = m_ncurhscale; m_nvertical = m_ncurvscale; m_prgsscale.setpos(0); m_sliderscale.setpos(0); } UpdateData(FALSE); InvalidateRect(&rectView);
void CExercise8_1Dlg::OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar) else if( pscrollbar->getsafehwnd() == m_slidervertical.m_hwnd ) { { } { } if(m_bsameratio == TRUE) m_ncurhscale = m_slidervertical.getpos(); m_ncurvscale = m_slidervertical.getpos(); m_sliderhorizontal.setpos(m_ncurhscale); else m_ncurhscale = m_sliderhorizontal.getpos(); m_ncurvscale = m_slidervertical.getpos(); m_nhorizontal = m_ncurhscale; m_nvertical = m_ncurvscale; m_prgsscale.setpos(0); m_sliderscale.setpos(0); } UpdateData(FALSE); InvalidateRect(&rectView); else if( pscrollbar->getsafehwnd() == m_sliderscale.m_hwnd ) { if (m_nhorizontal >= m_nvertical)
void CExercise8_1Dlg::OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar) { m_prgsscale.setrange(0, m_nhorizontal); m_sliderscale.setrange(0, m_nhorizontal); m_ncurhscale = m_sliderscale.getpos(); m_ncurvscale = (int)((float)m_ncurhscale * ((float)m_nvertical/ (float)m_nhorizontal)); m_prgsscale.setpos(m_ncurhscale); } { else m_prgsscale.setrange(0, m_nvertical); m_sliderscale.setrange(0, m_nvertical); m_ncurvscale = m_sliderscale.getpos(); m_ncurhscale = (int)((float)m_ncurvscale * ((float)m_nhorizontal/ (float)m_nvertical)); m_prgsscale.setpos(m_ncurvscale); } } UpdateData(FALSE); InvalidateRect(&rectView); else return;