08: 표준컨트롤 학습목표 컨트롤의동작원리를이해한다. 표준컨트롤의다양한속성과통지메시지를이해한다. MFC 컨트롤클래스를이용하여표준컨트롤을다루는방법을익힌다. 서브클래싱과메시지반사기법을이해한다.
개요 (1/4) 컨트롤 표준화된형태와특성을가진윈도우 사용자에게입력을받거나정보를보여줌 1
개요 (2/4) 컨트롤과부모윈도우 컨트롤 ( 자식윈도우 ) 1 통지메시지 2 컨트롤메시지 부모윈도우 통지메시지 컨트롤의상태가변화되었음을알림 메모리부족등으로인한오류를알림 컨트롤메시지 컨트롤의상태를알아내거나변경 2
개요 (3/4) MFC 컨트롤클래스 컨트롤 MFC 클래스컨트롤버튼 버튼컨트롤정적컨트롤편집컨트롤리스트박스컨트롤콤보박스컨트롤 CButton CStatic CEdit CListBox CComboBox 스크롤바컨트롤 CScrollBar 3
개요 (4/4) MFC 클래스계층도 컨트롤도윈도우다! 4
버튼컨트롤 (1/8) 버튼컨트롤종류 라디오버튼그룹 5
버튼컨트롤 (2/8) 컨트롤생성방법 1 일반윈도우에서만들기 2 대화상자에만들기 컨트롤생성 - 첫번째방법 CButton m_button; // C++ 객체생성 m_button.create(" 누르세요 ", WS_CHILD WS_VISIBLE BS_PUSHBUTTON, CRect(100, 100, 200, 130), this, 101); // 푸시버튼생성 6
버튼컨트롤 (3/8) CButton::Create() 함수 BOOL CButton::Create (LPCTSTR lpszcaption, p DWORD dwstyle, const RECT& rect, CWnd* pparentwnd, UINT nid) ; lpszcaption - 캡션문자열 dwstyle - 일반윈도우스타일 + 버튼컨트롤스타일 rect - 컨트롤크기와위치 pparentwnd - 부모윈도우 UINT nid - 컨트롤 ID 7
버튼컨트롤 (4/8) 버튼컨트롤스타일 - 일부 버튼컨트롤스타일 BS_PUSHBUTTON BS_DEFPUSHBUTTON BS_CHECKBOX BS_AUTOCHECKBOX BS_3STATE BS_AUTO3STATE BS_RADIOBUTTON BS_AUTORADIOBUTTON BS_GROUPBOX 의미 푸시버튼 기본푸시버튼 : 대화상자에서사용할때는 Enter 키를누르면이버튼이눌려짐 ( 일반윈도우에서는차이없음 ). 체크박스 자동체크박스 : 클릭하면자동으로체크표시가 On/Off 3 상태체크박스 자동 3상태체크박스 : 클릭하면자동으로체크표시가 On/Grayed/Of 라디오버튼 자동라디오버튼 : 클릭하면자동으로선택과선택해제가이뤄짐과선택해제가이루어짐 그룹박스 8
버튼컨트롤 (5/8) 통지메시지처리하기 메시지핸들러작성 ON_BN_CLICKED(101, OnButtonClicked) // 메시지맵... void CExButton1View::OnButtonClicked() // 메시지핸들러 { MessageBox(" 버튼을눌렀습니다."); } 컨트롤메시지보내기 멤버함수호출 m_button.setcheck(bst_checked); 9
버튼컨트롤 (6/8) 컨트롤생성 - 두번째방법 대화상자템플릿에컨트롤추가 대화상자가생성될때컨트롤도자동으로생성 컨트롤변수생성 컨트롤자체를나타내는변수 (= 컨트롤변수 ) 를생성하고이를이용하여컨트롤을조작 10
버튼컨트롤 (7/8) 컨트롤변수생성 11
버튼컨트롤 (8/8) 컨트롤변수생성 (cont'd) // 헤더파일 class CExButtonView : public CFormView { }... CButton m_button; // 구현파일 void CExButtonView::DoDataExchange(CDataExchange* pdx) { } CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CExButtonView) DDX_Control(pDX, IDC_BUTTON1, m_button); //}}AFX_DATA_MAP 12
정적컨트롤 (1/2) 정적컨트롤종류 텍스트 프레임 ( 색으로채워지지않은사각형 ), 사각형 ( 색으로채워진사각형 ), 아이콘, 비트맵, 향상된메타파일 (Enhanced Metafile) 13
정적컨트롤 (2/2) 통지메시지 SS_NOTIFY 스타일을설정하면통지메시지발생 STN_CLICKED( 클릭 ), STN_DBLCLK( 더블클릭 ), STN_DISABLE( 비활성화 ), STN_ENABLE( 활성화 ) 14
편집컨트롤 (1/6) 편집컨트롤종류 속성대화상자 15
편집컨트롤 (2/6) 편집컨트롤스타일 편집컨트롤 의미 속성대화상자의항목 스타일 ES_AUTOHSCROLL 줄끝에도달하면자동으로수평스크롤 Auto HScroll ES_AUTOVSCROLL 줄끝에도달하면자동으로수직스크롤 Auto VScroll ES_CENTER 텍스트를가운데정렬 Align text: Centered ES_LEFT 텍스트를왼쪽정렬 Align text: Left ES_LOWERCASE 입력된모든문자를소문자로변환 Lowercase ES_MULTILINE 다중라인편집컨트롤임을나타냄 Multiline ES_NOHIDESEL 컨트롤이키보드포커스를잃더라도선택된텍스트가계속반전된상태로남아있도록함 ES_NUMBER 숫자만입력할수있다. Number No hide selection 16
편집컨트롤 (2/6) 편집컨트롤스타일 17
편집컨트롤 (3/6) 편집컨트롤스타일 (cont'd) 편집컨트롤스타일 의미 속성대화상자의항목 ES_OEMCONVERT 입력된텍스트가 OEM 문자셋으로변환되어 OEM convert 편집컨트롤내부에저장 ES_PASSWORD 단일라인편집컨트롤에만사용할수있 Password 으며입력된문자를 * 로표시 ES_READONLY 텍스트를읽기만가능하다. Read-only ES_RIGHT 텍스트를오른쪽정렬한다. Align text: Right ES_UPPERCASE 입력된모든문자를대문자로변환한다. Uppercase ES_WANTRETURN 다중라인편집컨트롤에만사용할수있 Want return 으며이스타일을지정하지않으면대화상자에서 Enter 키를이용한줄바꿈이되지않는다. Ctrl+Enter 키를이용하면이스 타일과무관하게줄바꿈을할수있다. 18
편집컨트롤 (4/6) 편집컨트롤통지메시지 통지메시지 EN_CHANGE 의미 사용자가컨트롤의내용을변경하면화면에컨트롤을다시그리는데그후에이메시지가발생한다. EN_ERRSPACEERRSPACE 메모리가부족하다. EN_HSCROLL 사용자가편집컨트롤의수평스크롤바를클릭하였다. EN_KILLFOCUS 키보드포커스를잃었다. EN_MAXTEXT 더이상문자를입력할수없다. CEdit::SetLimitText 함수로문자개수를제한한경우나 ES_AUTOHSCROLL, ES_AUTOVSCROLL 등의스타일을지정하지않은상태에서줄끝까지입력한경우에발생한다. EN_SETFOCUS 키보드포커스를얻었다. EN_UPDATE 사용자가컨트롤의내용을변경하면화면에컨트롤을다시그리는데그직전에이메시지가발생한다. EN_VSCROLL 사용자가편집컨트롤의수직스크롤바를클릭하였다. 19
편집컨트롤 (5/6) 텍스트를변경하거나입력된텍스트를알아내기 m_edit.setwindowtext(" 초기값입니다."); CString str; m_edit.getwindowtext(str); 입력가능한문자열의길이를제한하기 m_edit.setlimittext(10); 각종편집작업 m_edit.clear(); m_edit.cut(); m_edit.copy(); m_edit.paste(); m_edit.undo(); 20
편집컨트롤 (6/6) 텍스트선택과치환하기 1 m_edit.selsel(5, 7); 2 m_edit.replacesel("abc"); 1 을실행하기전 1 을실행한후 2 를실행한후 21
리스트박스컨트롤 (1/8) 리스트박스컨트롤종류 단일선택리스트박스 다중선택리스트박스 속성대화상자 22
리스트박스컨트롤 (2/8) 리스트박스컨트롤스타일 리스트박스의미컨트롤스타일 속성대화상자항목 LBS_DISABLENOSCROLL LBS_EXTENDEDSEL LBS_HASSTRINGS 표시할항목의개수가적은경우에도수직스크롤바가사라지지않는다. SHIFT, CTRL 키와마우스클릭을이용한다중선택이가능하다. LBS_OWNERDRAW* 스타일을지정하지않을경우의디폴트스타일이며컨트롤이문자열을저장및관리한다. Disable no scroll Selection: Et Extended dd Has strings LBS_MULTICOLUMN 여러줄 (Column) 로구성된리스트박스를생성하며항목이많을경우수평스크롤이가능하다. Multi-column 23
리스트박스컨트롤 (3/8) 리스트박스컨트롤스타일 (cont'd) 리스트박스의미컨트롤스타일 LBS_MULTIPLESEL LBS_NODATA LBS_NOINTEGRALHE IGHT LBS_NOREDRAW 마우스클릭을이용한다중선택이가능하다. 항목데이터를컨트롤이아닌부모윈도우가유지하며필요할때마다부모윈도우가직접그린다. 항목의개수가 1000개이상일경우에사용한다. 이스타일을지정하지않으면항목의일부가잘려서보이지않는경우가발생할수있다. 항목에변화가생기더라도리스트박스컨트롤을다시그리지않는다. 속성대화상자항목 Selection: Multiple 없음 No integral hih height No redraw 24
리스트박스컨트롤 (4/8) 리스트박스컨트롤스타일 (cont'd) 리스트박스 의미 속성 대화상자의 컨트롤스타일 항목 LBS_NOSEL LBS_NOTIFY LBS_OWNERDRAWFIXED LBS_OWNERDRAWVARIA BLE 항목을선택할수없다. 사용자가항목을클릭하거나더블클릭하면부모윈도우에게통지메시지를보낸다. 부모윈도우가리스트박스항목을직접그리되항목의높이가일정한경우이다. 부모윈도우가리스트박스항목을직접그리되항목의높이가일정하지않은경우이다. Selection: None Notify Owner draw: Fixed Owner draw: Variable 25
리스트박스컨트롤 (5/8) 리스트박스컨트롤스타일 (cont'd) 리스트박스 의미 속성 대화상자의 컨트롤스타일 항목 LBS_SORT LBS_STANDARD LBS_USETABSTOPS LBS_WANTKEYBOAR DINPUT 항목이문자열인경우정렬하여표시한다. LBS_NOTIFY, LBS_SORT, WS_VSCROLL, WS_BORDER 네가지스타일의조합이다. 이스타일을지정하면항목문자열에포함된탭문자 (' t') 를제대로처리할수있다. 리스트박스컨트롤이키보드포커스를가진상태에서사용자가키를누르면부모윈도우가이를감지하여특별한처리를할수있다. Sort Notify, Sort, Border, Vertical scroll Use tabstops Want key input 26
리스트박스컨트롤 (6/8) 리스트박스컨트롤통지메시지 통지메시지 의미 LBN_DBLCLK 사용자가항목을더블클릭하였다. LBN_SELCHANGE 사용자가선택을변경하였다. LBN_SELCANCEL 사용자가선택을취소하였다. LBN_SETFOCUS 키보드포커스를얻었다. LBN_KILLFOCUS 키보드포커스를잃었다. LBN_ERRSPACE 메모리가부족하다. LBN_DBLCLK, LBN_SELCHANGE, LBN_SELCANCEL 통지메시지는 LBS_NOTIFY 스타일을설정해야발생 27
리스트박스컨트롤 (7/8) 항목추가와삭제 m_list.addstring( AddString(" 사과 "); m_list.deletestring(3); 항목선택 // 단일선택리스트박스컨트롤인경우 m_list.setcursel(2); // 다중선택리스트박스컨트롤인경우 m_list.setsel(2); m_list.setsel(3, FALSE); 28
리스트박스컨트롤 (8/8) 선택된항목알아내기 // 단일선택리스트박스컨트롤인경우 int nindex = m_list.getcursel(); if(nindex!= LB_ERR){ CString str; m_list.gettext(nindex, str); } // 다중선택리스트박스컨트롤인경우 int nindex = m_list.getcaretindex(); if(nindex!= LB_ERR){ CString str; m_list.gettext(nindex, str); } 29
콤보박스컨트롤 (1/6) 콤보박스컨트롤종류 편집컨트롤 정적컨트롤 리스트박스컨트롤 단순스타일 드랍다운스타일 드랍다운리스트스타일 30
콤보박스컨트롤 (2/6) 속성대화상자 31
콤보박스컨트롤 (3/6) 콤보박스컨트롤스타일 콤보박스컨트롤스타일의미속성대화상자의항목 CBS_AUTOHSCROLL CBS_DISABLENOSCROLL CBS_DROPDOWN CBS_DROPDOWNLIST CBS_HASSTRINGS CBS_LOWERCASE CBS_NOINTEGRALHEIGHT CBS_OEMCONVERT CBS_OWNERDRAWFIXED CBS_OWNERDRAWVARIABLE CBS_SIMPLESIMPLE CBS_SORT CBS_UPPERCASE = ES_AUTOHSCROLL = LBS_DISABLENOSCROLL 드랍다운스타일드랍다운리스트스타일 = LBS_HASSTRINGS = ES_LOWERCASE = LBS_NOINTEGRALHEIGHT = ES_OEMCONVERT = LBS_OWNERDRAWFIXED = LBS_OWNERDRAWVARIABLE 단순스타일 = LBS_SORT = ES_UPPERCASE Auto HScroll Disable no scroll Type: Dropdown Type: Drop List Has strings Lowercase No integral height OEM convert Owner draw: Fixed Owner draw: Variable Type: Simple Sort Uppercase 32
콤보박스컨트롤 (4/6) 콤보박스컨트롤통지메시지 통지메시지 의미 CBN_CLOSEUP 리스트박스가닫혔다. CBN_DBLCLK 사용자가항목을더블클릭하였다. CBN_DROPDOWN 리스트박스가열리기직전이다. CBN_EDITCHANGE =EN_EDITCHANGE CBN_EDITUPDATE = EN_EDITUPDATE CBN_ERRSPACE 메모리가부족하다. CBN_KILLFOCUS 키보드포커스를잃었다. CBN_SELCHANGE = LBN_SELCHANGE CBN_SELENDCANCE = LBN_SELENDCANCEL LCBN_SELENDOK 사용자가항목을선택하였다. CBN_SETFOCUS 키보드포커스를얻었다. 단순 스타일드랍드랍다운다운리스트 33
콤보박스컨트롤 (5/6) 항목추가와삭제 m_combo.addstring( AddString(" 사과 "); m_combo.deletestring(3); 선택된항목알아내기 int nindex = m_combo.getcursel(); if(nindex!= CB_ERR){ CString str; m_combo.getlbtext(nindex, str); } 34
콤보박스컨트롤 (6/6) 입력가능한문자열의길이제한하기 m_combo.limittext(10); 각종편집작업 m_combo.clear(); m_combo.cut(); m_combo.copy(); m_combo.paste(); 35
스크롤바컨트롤 (1/3) 스크롤바컨트롤 화면의일정영역을스크롤하거나정해진범위의값을변경시키는용도로사용 스크롤바코드 36
스크롤바컨트롤 (2/3) WM_HSCROLL/WM_VSCROLL 메시지핸들러 void OnHScroll (UINT nsbcode, UINT npos, CScrollBar* pscrollbar); void OnVScroll (UINT nsbcode, UINT npos, CScrollBar* pscrollbar); nsbcode 스크롤바코드 npos 스크롤박스의위치 스크롤바코드가 SB_THUMBPOSITION 또는 SB_THUMBTRACK인경우에만사용 pscrollbar 스크롤바컨트롤을가리키는포인터 37
스크롤바컨트롤 (3/3) 주요함수 멤버함수 SetScrollRange() 역할 스크롤박스위치값의최소값과최대값을설정한다. SetScrollPos() 스크롤박스의현재위치를설정한다. GetScrollPos() 스크롤박스의현재위치를얻는다. 38
고급컨트롤기법 서브클래싱 기존의윈도우나컨트롤의형태또는동작변경 메시지반사 스스로통지메시지를처리하는독립적인컨트롤클래스제작가능 39
서브클래싱 (1/2) 서브클래싱 윈도우 ( 정확하게는윈도우프로시저 ) 로가는메시지를중간에서붙잡아처리하는기법 메시지종류에따라, 처리한후원래의윈도우프로시저에게전달해주거나전달하지않을수있음 메시지 중간에서처리 윈도우프로시저 40
서브클래싱 (2/2) 서브클래싱구현순서 1 기존의클래스를기반으로새로운윈도우나컨트롤 클래스를생성 2 메시지핸들러를재정의하거나새로운메시지핸들러 를추가하여정의 3 CWnd::SubclassWindow() 또는 CWnd::SubclassDlgItem() 함수를호출 41
메시지반사 (1/2) 메시지반사 부모윈도우가처리하지않는통지메시지를컨트롤자신이처리 통지메시지 컨트롤 ( 자식윈도우 ) 부모윈도우 부모윈도우가통지메시지를처리하지않을경우에만컨트롤이자신의통지메시지를처리가능 42
메시지반사 (2/2) 메시지반사구현 기존의컨트롤클래스로부터새로운클래스를만들고자신의통지메시지를처리하도록함수를추가 새로만든클래스를이용하여컨트롤생성 43