Microsoft PowerPoint - CPP_chap6_interface(2)

Similar documents
<4D F736F F F696E74202D203039C0E520B4EBC8ADBBF3C0DA205BC8A3C8AF20B8F0B5E55D>

윈도우시스템프로그래밍

<4D F736F F F696E74202D203036C0E520BBE7BFEBC0DA20C0CEC5CDC6E4C0CCBDBA205BC8A3C8AF20B8F0B5E55D>

윈도우시스템프로그래밍

Microsoft PowerPoint - hci2-lecture9.ppt

Microsoft PowerPoint - hci2-lecture5-messagemap.ppt

Microsoft PowerPoint - hci2-lecture6.ppt

5장 MFC기반 다지기

Microsoft PowerPoint - hci2-lecture6.ppt

Microsoft PowerPoint _대화상자.ppt

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

Microsoft PowerPoint - CPP_chap7_dialogbox(2)

untitled

Microsoft Word - hci08-final-answer.doc

<4D F736F F F696E74202D20C1A C0E520B5B5C5A5B8D5C6AE20C6C4C0CF20C0D4C3E2B7C220B9D720B4D9BEE7C7D120BAE420C5ACB7A1BDBA2E BC8A3C8AF20B8F0B5E55D>

윈도우시스템프로그래밍

Programming hwp

그래픽 프로그래밍

윈도우 프로그래밍의 개념

오버라이딩 (Overriding)

PowerPoint Presentation

슬라이드 1

4S 1차년도 평가 발표자료

Programming hwp

PowerPoint Template

윈도우 프로그래밍의 개념

윈도우시스템프로그래밍

Microsoft PowerPoint - CPP_chap3

Visual C++의 개요

<B0EDB1DEC7C1B7CEB1D7B7A1B9D6284D DBFE4BEE0C1A4B8AE28B9DAB1E2C8AB292E687770>

Microsoft Word - hci07-final-answer.doc

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

어댑터뷰

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

윈도우시스템프로그래밍

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )

Microsoft PowerPoint - 09-CE-5-윈도우 핸들

Microsoft PowerPoint - 04windows.ppt

<B9CCB5F0BEEE20C1A4BAB8C3B3B8AE2E687770>

<4D F736F F F696E74202D203031C0E520C0A9B5B5BFEC20C7C1B7CEB1D7B7A1B9D620B1E2C3CA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

MFC 프로그래밍

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

윈도우 프로그래밍의 개념

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

[제1강] 텍스트를 입력하세요

Microsoft PowerPoint - chap06-2pointer.ppt

gnu-lee-oop-kor-lec06-3-chap7

DLL(Dynamic Linked Library)

Microsoft PowerPoint - 09-CE-14-리스트콤보박스

Dialog Box 실행파일을 Web에 포함시키는 방법

PowerPoint Presentation

歯Lecture2.PDF

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

Programming hwp

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

Microsoft PowerPoint - hci2-lecture10.ppt

. 스레드 (Thread) 란? 스레드를설명하기전에이글에서언급되는용어들에대하여알아보도록하겠습니다. - 응용프로그램 ( Application ) 사용자에게특정서비스를제공할목적으로구현된응용프로그램을말합니다. - 컴포넌트 ( component ) 어플리케이션을구성하는기능별요

윈도우 프로그래밍의 개념

JAVA PROGRAMMING 실습 08.다형성

슬라이드 1

슬라이드 1

MVVM 패턴의 이해

Programming hwp

04장 메시지 처리 유형

Visual Basic 반복문

Lab 3. 실습문제 (Single linked list)_해답.hwp

PowerPoint Presentation

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

슬라이드 1

게임 기획서 표준양식 연구보고서

소프트웨어공학 Tutorial #2: StarUML Eun Man Choi

쉽게 풀어쓴 C 프로그래밍

C++ Programming

Microsoft PowerPoint - 07-Data Manipulation.pptx

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

UI TASK & KEY EVENT

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

슬라이드 1

PowerPoint 프레젠테이션

제8장 자바 GUI 프로그래밍 II

PowerPoint 프레젠테이션

쉽게 풀어쓴 C 프로그래밍

C# Programming Guide - Types

Microsoft PowerPoint UI-Event.Notification(1.5h).pptx

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

UI TASK & KEY EVENT

Microsoft PowerPoint - hci2-lecture7.ppt

슬라이드 1

Microsoft PowerPoint - hci2-lecture3.ppt

윈도우즈 프로그래밍

설계란 무엇인가?

Microsoft PowerPoint - hci2-lecture3.ppt

VISLAB 박제강 1. 시작하기전에영상관련알고리즘을개발하는과정에서작성한프로그램을테스트하고피드백하는작업은빈번하게발생한다. 이때기존콘솔 (Console) 형태로작성된프로그램의경우테스트작업을유동적으로조절할수없기때문에작업의효율이떨어진다. 반면 GUI(Graphical Use

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

학습목표 메뉴를추가하는방법을이해하고실습할수있다. 프로그램의기본설정 (settings) 을정의하는방법을알고실습할수있다. 대화상자를여는방법을알고실습할수있다. 로그메시지로디버깅하는방법을이해한다. 디버거로디버깅하는방법을이해한다.

JVM 메모리구조

PowerPoint 프레젠테이션

Transcription:

사용자인터페이스 (2) 1

1. 대화상자 (Dialog) 2 학습목표 Graphs 예제에서여러가지굵기의선을그릴수있도록수정해본다 선의굵기를지정할대화상자를만들고대화상자클래스를만든다 대화상자구현과정 1 리소스에디터를사용하여대화상자리소스 (Resource) 를만든다. 대화상자리소스는대화상자의형태를정의한다. 2 ClassWizard를사용하여 CDialog 클래스를상속받아새대화상자클래스를만든다. 대화상자클래스는대화상자의기능을구현한다. 3 대화상자가메뉴명령에의해실행되려면, 메뉴리소스에메뉴항목을추가하고 ClassWizard를사용하여메뉴메시지핸들러를구현한다. 메뉴메시지핸들러에서대화상자를표시하는코드를구현한다. 4 필요에따라, 대화상자컨트롤이보내는메시지를처리하는메시지핸들러를구현한다. 5 ClassWizard를사용하여대화상자의컨트롤에해당하는데이터멤버를추가하고 Dialog Data Exchange와 Dialog Data Validation 설정

3 대화상자리소스 (Resource) 와대화상자클래스의연결 대화상자리소스는대화상자의형태를정의하고, 대화상자클래스는대화상자의기능을구현한다. 대화상자클래스는대화상자리소스에연결되어야한다. 대화상자클래스를정의할때대화상자리소스를지정해주어야한다. 대화상자의컨트롤들은대화상자클래스의멤버변수에연결되어야한다. ClassWizard 의 Member Variables 페이지에서대화상자컨트롤에해당하는멤버변수가대화상자클래스에정의된다.

4 프레임웍에서대화상자는두개의구성요소를갖는다 다이얼로그템플릿리소스 (dialog template resource) 대화상자의모양과컨트롤의배치를리소스에디터로비주얼하게디자인한리소스템플릿이다. 대화상자의크기위치스타일, 컨트롤의종류위치등을지정한다 다이얼로그클래스 (dialog class) CDialog 클래스를상속받아구현한 C++ 클래스 두종류의대화상자 Modal dialog box 프로그램의다른부분으로이동하기전에먼저대화상자를종료하여햐하는대화상자 Modaless dialog box 보통윈도우와같이다른윈도우로전환가능한대화상자를말한다.

5 소스 : "06-1 Graphs.zip" 대화상자리소스만들기 1 메뉴에서 Insert Resource Dialog 선택 2 메뉴에서 Edit Property 선택 3 Dialog Property 대화상자에서 ID: IDD_LINE_WIDTH Caption: Line Width Dialog 4 Controls 툴바에서 Edit Box와 Static Text 버튼을눌러컨트롤을추가한다. 5 EditBox를오른쪽버튼으로누르고 Properties선택 6 EditBox의 ID는 IDC_LINE_WIDTH 7 메뉴에서 Layout Tab Order 선택 Edit Box를클릭하여 Tab Order를 1번으로설정

6 대화상자클래스만들기 1 ClassWizard를시동하면새대화상자에대한클래스생성을묻는대화상자가디스플레이된다. 2 Create New Class 를선택 3 Create New Class 대화상자에서다음과같이입력 Name: CLineWidthDlg Base Class: CDialog Dialog ID: IDD_LINE_WIDTH

7

8 컨트롤과멤버변수연결하기 1 ClassWizard의 Member Variables 페이지에서 Class Name: CLineWidthDlg Control IDs: IDC_LINE_WIDTH Add Variable 버튼선택 2 Add member variable 대화상자에서 member variable name:m_width Category: Value Variable Type: int OK 3 ClassWizard 의 Member Variables 페이지에서 Minimum Value: 0 Maximum Value: 30

9

2. 메뉴 10 학습목표 메뉴를눌렀을때대화상자가화면에나올수있도록구현한다. 메뉴리소스에 Line Width 설정 항목을추가하고 메뉴를눌렀을때실행될메뉴메시지핸들러 (message handler function) 를구현한다. 소스 : "06-1 Graphs.zip" 메뉴리소스에메뉴항목추가 1 ResourceView에서메뉴리소스 IDR_LINES1TYPE 편집 2 메뉴바의오른쪽빈영역을더블클릭하면 Menu Item Properties 대화상자가표시된다

11 3 " 선 (L)" 메뉴바아래의메뉴항목더블클릭 ID: ID_LINE_WIDTH Caption: 선굵기 (&W) Prompt: 선굵기설정 n선굵기

4 " 선 (L)" 메뉴바아이템을마우스로드래그하여 " 편집 (E)" 과 " 보기 (V)" 사이로옮김 12

13 메뉴메시지핸들러함수구현 1 ClassWizard의 Message Map 페이지에서 Class name: CLines1Doc Object IDs: ID_LINE_WIDTH Messages: COMMAND Add Function 버튼선택 2 OnLineWidth 멤버함수추가된것확인 3 Edit Code 버튼을눌러내용입력 #include "linewidthdlg.h" void CGraphsDoc::OnLineWidth() { CLineWidthDlg dlg; dlg.m_width = m_width; if (dlg.domodal() == IDOK) { m_width = dlg.m_width; } }

14

15 CDialog::DoModal() 모달 (modal) 대화상자를디스플레이하는멤버함수이다. 모달대화상자는사용자가 OK 버튼을누르거나 Cancel 버튼을누르면종료된다. 모달대화상자가종료되면 DoModal() 멤버함수는 IDOK나 IDCANCEL 을리턴한다. CGraphsDoc::OnLineWidth 에서는 IDOK가리턴되었을경우에만라인굵기를새로설정한다.

16 버그수정 선굵기까지고려하여더넓게무효화하여야한다 InflateRectRect() 메소드로무효화할사각형을확장한다 CRect CRectangle::BoundRect() { CRect r = m_rect; r.inflaterect(m_width, m_width, m_width, m_width); return r; };

void CGraphsView::OnMouseMove(UINT nflags, CPoint point) { CGraphsDoc* pdoc = (CGraphsDoc*)GetDocument(); if (GetCapture() == this) { int w = pdoc->m_width; CRect r = MakeRect(m_point1,m_point2); r.inflaterect(w,w,w,w); InvalidateRect(r); m_point2 = point; r = MakeRect(m_point1,m_point2); r.inflaterect(w,w,w,w); InvalidateRect(r); } for (int i = pdoc->m_rects.getsize()-1; i>=0; --i) { CRectangle* r = &pdoc->m_rects[i]; if (r->ptinobject(point)) { if (r!= m_ptinrect) { if (m_ptinrect!= NULL) InvalidateRect(m_ptInRect->BoundRect()); m_ptinrect = r; InvalidateRect(m_ptInRect->BoundRect()); } return; } } if (m_ptinrect!= NULL) { InvalidateRect(m_ptInRect->BoundRect()); m_ptinrect = NULL; } 17

18 커멘드메시지 WM_COMMAND 메뉴나툴바에의해서발생하는메시지 커맨드메시지의전달순서 대부분의메시지는해당윈도우에직접전달되지만메뉴나툴바에의한커멘드메시지는 CCmdTarget 클래스로부터유도된여러클래스를두루거친다그중하나의클래스에서처리된다. 메뉴항목이선택되었을때, 다음과같은순서로전달된다. 1 Main Frame Window 2 활성화된 Child Frame Window 3 활성화된 Child Frame window에연결된활성화된뷰 4 활성화된뷰에연결되어있는도큐먼트 5 도큐먼트에연결되어있는도큐먼트템플릿 6 CWinApp

19 메시지핸들러와메시지의연결 툴바와메뉴는커맨드메시지를발생시킨다 이메시지를처리할메시지핸들러함수가호출되어야한다. 메시지가발생했을때연결된해당메시지핸들러함수를호출하는기능은 MFC에이미구현되어있다. ClassWizard에서메시지를처리할메시지핸들러를만들어주면된다. 커멘드메시지핸들러를어떤클래스에두어야하는가? " 선굵기 " 메뉴의메시지핸들러를어떤클래스의멤버함수로작성하여야할까? 도큐먼트클래스의멤버함수? 뷰클래스의? 고려할사항 여러뷰에공통적인기능은도큐먼트에구현한다 한뷰에한정된기능은그뷰에구현한다 커멘드메시지를제외한대부분의메시지핸들러는보통뷰클래스에구현한다.

20 대화상자의배경색설정 어플리케이션의 InitInstance 멤버함수에서 CWinApp의 SetDialogBkColor 멤버함수를호출하여설정 어플리케이션에서만들어지는모든대화상자와메시지박스의배경색이바뀜 대화상자의초기화 CDialog::OnInitDialog() 멤버함수를재정의하여구현한다. 이멤버함수는대화상자객체가생성된후, 대화상자윈도우가화면에나타나기전에호출된다. 오버라이드한 OnInitDialog() 멤버함수는에서는부모클래스 (CDialog) 의 OnInitDialog() 멤버함수를반드시호출하여야한다.

21 모달대화상자 모달대화상자를사용하는코드는다음과같은형태이다. CLineWidthDlg dlg; dlg.m_width = m_curwidth; if (dlg.domodal() == IDOK) { m_curwidth = dlg.m_width; } CDialog::DoModal() 멤버함수는대화상자를화면에출력시키고 OK 버튼이나 Cancel이눌려지면각각 IDOK나 IDCANCEL을리턴하면서빠져나온다. 즉대화상자는 DoModal() 내부에서만들어지고없어진다. 사용자가 Ok나 Cancel 버튼을누르면 CDialog클래스의 OnOK, OnCancel 메시지핸들러가호출된다. 이들메시지핸들러에서 EndDialog() 를호출하여대화상자를닫는다. 모달대화상자객체는보통함수의로컬변수로스택에생성되어함수가리턴되면서소멸한다

22 모달리스대화상자닫기 모달리스대화상자는메모리를할당받아생성해야한다 OnClose 멤버함수와 OnCancel멤버함수는 DestroyWindow를호출하고 DestroyWindow는대화상자윈도우를닫는다 모달리스대화상자의경우할당받은메모리해제는 PostNcDestroy 멤버함수에서 delete this 하여해제되는기능이이미구현되어있다

3. 공통대화상자 (Common Dialog) 23 학습목표 여러가지색의선을그릴수있도록 Graphs 예제를수정한다 색을지정할때윈도우즈에서지원하는색지정 Common Dialog Box를사용한다. 할일 먼저메뉴리소스에 선의색 (&L) 을추가한다. 메뉴메시지핸들러함수를도큐먼트클래스에구현한다. 메뉴메시지핸들러함수에서는색을선택대화상자를표시하고선택된색을멤버변수 m_pencolor에저장한다.

24 공통대화상자클래스 윈도우즈의 COMMDLG.DLL에정의된대화상자에대한클래스 자주사용되는대화상자들은이미만들어져있어서리소스나대화상자클래스만드는작업이필요없이바로사용할수있다 다음과같은공통대화상자클래스들이제공된다 CColorDialog 색을선택할때 CFileDialog 파일을열거나닫을때 CFindReplaceDialog 문자열을찾거나바꿀때 CFontDialog 폰트를선택할때 CPrintDialog 인쇄할때

25 소스 : "06-2 Graphs.zip" 메뉴항목추가 1 메뉴의 도형 (&G) 아래에메뉴항목추가 ID: ID_LINE_COLOR Caption: 선의색 (&L) Prompt: 선의색설정 n선의색 메뉴항목메시지핸들러추가 1 ClassWizard의 Message Map 페이지에서 Class name: CLines1Doc Object IDs: ID_LINE_COLOR Messages: COMMAND Add Function 버튼선택

26 2 Edit Code 버튼을눌러내용입력 void CGraphsDoc::OnLineColor() { CColorDialog dlg; if (dlg.domodal() == IDOK) m_pencolor = dlg.getcolor(); }

27 void CGraphsDoc::AddRect(CRect rect) { CRectangle r(rect, m_width, m_pencolor, m_brushcolor); m_rects.add(r); UpdateAllViews(NULL); SetModifiedFlag(TRUE); } CDocument::SetModifiedFlag() 도큐먼트의데이터가수정되었다고표시하는멤버함수이다. 이렇게하면문서를닫기전에저장할것인지묻는대화상자가나타난다. CDocument::UpdateAllViews() 도큐먼트의데이터가변경되었을경우, 도큐먼트에연결된모든뷰가화면을다시그릴수있도록변경사실을모든뷰에게통보하기위한메소드 통보받은뷰객체는전체를다시그린다. 파라미터는변경이발생한뷰객체의포인터이다. 그뷰는통보받지않는다. NULL 이면모든뷰에게통보한다.

문제 : 28 Graphs 에도형내부를칠할브러쉬의색을설정할수있는기능을구현하라

4. 툴바 (Toolbar) 29 학습목표 툴바버튼을추가한다 메뉴의 Edit 아래에 모두삭제 (&A) 메뉴항목을추가한다. 소스 : "06-3 Graphs.zip"

30 툴바버튼만들기 1 ResourceView에서 Toolbar 리소스를열고 2 다음과같이툴바버튼을그린다. 3 View 메뉴에서 Properties ID 는 ID_LINE_WIDTH 를선택.

31 4 다음과같이툴바버튼을그린다. 5 View 메뉴에서 Properties ID 는 ID_LINE_COLOR 를선택 툴바버튼은위와같이리소스를추가하고, ID를해당메뉴의 ID로선택해준다. 툴바버튼을누르면, 해당메뉴를누른것과같은메시지가전달되어, 메뉴의경우와같은메시지핸들러가실행되므로, 따로메시지핸들러를구현해줄필요가없다. 컴파일하고툴바버튼을눌러보라.

32 " 모두삭제 (&A)" 메뉴항목추가 1 메뉴의 Edit 아래에메뉴항목을추가하고 Menu Item Propties 대화상자에서 Seperator 항목을체크하여 Sperator 추가 2 메뉴의 Edit 아래에메뉴항목추가 ID: ID_EDIT_CLEAR_ALL Caption: 모두삭제 (&A) 메뉴항목메시지핸들러등록 1 ClassWizard의 Message Map 페이지에서 Class name: CLines1Doc Object IDs: ID_EDIT_CLEAR_ALL Messages: COMMAND Add Function 버튼선택 2OnEditClearAll멤버변수확인

33 3 Edit Code 버튼을눌러내용입력 void CGraphsDoc::OnEditClearAll() { m_rects.removeall(); SetModifiedFlag(); UpdateAllViews(NULL); } 툴바버튼만들기 툴바버튼의 ID: ID_EDIT_CLEAR_ALL 로지정

5. 메뉴항목상태갱신 (update) 34 소스 : "06-3 Graphs.zip" 메뉴항목객체상태갱신 MFC 프레임웍은메뉴항목을디스플레이하기전에메뉴항목을어떻게표시해야하는지결정하기위하여 UPDATE_COMMAND_UI 메시지를보낸다 UPDATE_COMMAND_UI 메시지핸들러에서는해당메뉴항목의 enable/disable 상태와 checked 상태를결정한다. " 모두삭제 " 메뉴항목은도큐먼트가비어있을때는 disable 되어있어야한다. 이렇게하기위해서 ID_EDIT_CLEAR_ALL의 UPDATE_COMMAND_UI 메시지핸들러는 m_rects가비어있으면 disable 상태로설정한다. 툴바아이템에대해서도 UPDATE_COMMAND_UI 메시지가발생하므로메뉴와처럼 enable/disable 상태와 checked 상태가결정된다

35 메뉴항목갱신과정 프레임웍은메뉴항목을갱신하기위해메뉴항목을그리기전에하나하나마다 UPDATE_COMMAND_UI 메시지를커맨드메시지전달과정을통해전달한다. 커맨드타겟 ( 메뉴나툴바버튼 ) 중 UPDATE_COMMAND_UI 메시지핸들러가있으면호출된다. 이 UPDATE_COMMAND_UI 메시지핸들러에서활성화상태를결정하여설정한다. UPDATE_COMMAND_UI 메시지핸들러가없을경우프레임웍은그메뉴항목의커맨드메시지핸들러가있는지조사한다. 커맨드메시지핸들러가없으면그메뉴항목을비활성화한다.

36 CCmdUI 클래스 UPDATE_COMMAND_UI 메시지핸들러는 CCmdUI* 타입의포인터를전달받는다. 이포인터를메뉴항목이나툴바버튼같은커멘트메시지를발생시키는사용자인터페이스객체에대한포인터이다. 이포인터를사용하여상태를설정한다. 상태바 (status bar) 에정보표시 상태바기능은 AppWizard가코드를생성한다 마우스가메뉴항목위를지나갈때그메뉴에대한설명이상태바에표시되는기능은이미구현되어있다. 리소스에디터로메뉴를정의할때 Prompt String에입력하는문자열이상태바에표시된다. Prompt String은 n 문자를중심으로앞과뒤로나뉘는데, 앞부분은상태바에표시되는내용이고뒷부분은툴팁 (tool tip) 이다.

37 메뉴항목의갱신메시지핸들러등록 1 ClassWizard의 Message Map 페이지에서 Class name: CGraphsDoc Object IDs: ID_EDIT_CLEAR_ALL Messages: UPDATE_COMMAND_UI 선택 2 OnUpdateEditClearAll 멤버변수확인 3 Edit Code 버튼을눌러내용입력 void CGraphsDoc::OnUpdateEditClearAll(CCmdUI* pcmdui) { pcmdui->enable(m_rects.getsize() > 0); }

38 OnUpdateEditClearAll() 은파라미터한개를갖는다. CCmdUI객체에대한포인터이며 Clear All 메뉴항목을가르킨다 m_rects가비어있으면메뉴항목을 disable시키고비어있지않으면 enable 시킨다 메뉴나툴바버튼이모두같이상태가갱신된다.

6. 메시지의종류 39 일반윈도우메시지 일반윈도우메시지는윈도우에직접전달된다 WM_PAINT와같은메시지는윈도우의일정영역을다시그려야할필요성이발생했을때그윈도우에직접전달된다 마우스메시지역시그마우스가위치한윈도우에직접전달된다 커맨드메시지 커맨드메시지는사용자의명령 ( 메뉴, 툴바, 액셀러레이터키 ) 에의해서발생한다. WM_COMMAND 메시지형태로어플리케이션에전달된다. 커맨드메시지를처리할클래스는정해져있지않고프로그래머가결정한다

40 Update Command UI 커맨드메시지 Update Command UI 커맨드메시지는어플리케이션프레임웍내부에서발생된다 메뉴아이템이나툴바버튼과같은사용자인터페이스객체의상태를갱신하려할때발생한다. 예를들면 현재어플리케이션의상태에서메뉴의어떤명령을수행할수없다면그메뉴를회색으로비활성화시켜야한다 사용자가메뉴바를클릭하여서브메뉴아이템들이디스플레이되어야할때 어플리케이션프레임웍은각메뉴아이템마다 Update Command UI 커멘드메시지를발생시킨다 이메시지핸들러에서메뉴아이템의상태를설정한다.

41 Control Notification 메시지 차일드컨트롤 (child control) 윈도우는자신의상태변경을부모윈도우인대화상자에게메시지를보내서알린다 예를들면 edit box에서키보드를눌러문자를입력하면 EN_UPDATE 란메시지가부모윈도우에전달된다.

7. 컨텍스트메뉴 42 학습목표 Graphs 의뷰에서마우스오른쪽버튼을클릭할때간단한컨테스트메뉴가표시되게해본다. 소스 : "06-4 Graphs.zip" 메뉴리소스만들기 1 메뉴에서 Insert Resource 선택 2 Insert Resource 대화상자에서 Menu 선택 3 메뉴바의맨윗단계에아이템하나추가캡션은아무거나상관없음 4 그메뉴아래에아래와같은메뉴항목추가 메뉴 ID 캡션 ID_LINE_WIDTH 선굵기 (&W) ID_LINE_COLOR 선의색 (&L) <sperator> ID_EDIT_CLEAR_ALL 전체삭제 (&A)

43 5 새로추가된메뉴리소스의 ID 를 IDR_POPUP_MENU 로설정 6 ClassWizard의 Message Map 페이지에서 Object ID CGraphsView Message WM_RBUTTONDOWN Member function OnRButtonDown 7 다음입력 void CLines1View::OnRButtonDown(UINT nflags, CPoint point) { CMenu menu; ClientToScreen(&point); menu.loadmenu(idr_popup_menu); CMenu* pmenu = menu.getsubmenu(0); pmenu->trackpopupmenu(tpm_leftalign TPM_RIGHTBUTTON, point.x, point.y, AfxGetApp()->m_pMainWnd); }

44 CMenu::LoadMenu() 는리소스에서메뉴를읽어오고 CMenu::GetSubMenu(n) 는메뉴의 n 번째서브메뉴에대한포인터를리턴한다. CMenu::TrackPopupMenu() 는스크린좌표로주어진위치에부동팝업메뉴를출력한다. 첫번째파라미터는메뉴항목을선택할마우스버튼을지정하는상수와, 마우스포인터에대한팝업메뉴의위치를지정하는상수이다 그다음파라미터는메뉴가표시될 x, y 좌표 마지막파라미터는메뉴를소유하는윈도우를지정한다. AfxGetApp()->m_pMainWnd 는어플리케이션메인프래임윈도우이다.

8. DDX 와 DDV 45 대화상자에서데이터읽어오기 CWnd클래스의 SetDlgItemText, GetDlgItemText 멤버함수를이용하여대화상자컨트롤에값을설정하거나입력된값을가져올수있다. 그런데 MFC가제공하는 DDX 방법을이용하면훨씬간편하다. DDX와 DDV를구현하기위해서는 ClassWizard를이용하여다이얼로그클래스의멤버변수를정의하고데이터타입과 validation rule을정의해주면된다 ClassWizard는대화상자클래스의생성자에멤버변수의초기화코드를첨가하고, 컨트롤과멤버변수간데이터교환을위해대화상자클래스의 DoDataExchange 멤버함수에 DDV, DDX 루틴첨가한다.

46 DDX (Dynamic Data Exchange) 대화상자의컨트롤과다이얼로그클래스의멤버변수간데이터교환을자동화한다. DDX를이용하면언제든지컨트롤의값을다이얼로그클래스의멤버변수에가져올수있고역도가능하다. 데이터를멤버변수에가져오려면 UpdateData(TRUE) 를호출하고반대로보내려면 UpdateData(FALSE) 를호출한다. 모달리스대화상자에서 Cancel버튼이선택된경우 DDX는발생하지않는다. 즉대화상자에입력한값을멤버변수에가져오지않는다 DDV (Dynamic Data Validation) 다어얼로그박스에입력되는데이터의유효화검증기능이다. 예를들면정수값의경우최대값최소값을검사하여이범위를벗어날경우경고메시지가저절로출력된다.

9. 메시지박스 47 소스 : "06-5 Msgbox.zip" 메시지박스를만들어본다 1 Dialog based 프로젝트를 Msgbox란이름으로생성한다. 2 다음과같이대화상자리소스편집

48 "Text" Edit Box의 ID: IDC_EDIT_TEXT "Caption" Edit Box의 ID: IDC_EDIT_CAPTION "Display" Push Button의 ID: IDC_BUTTON_DISPLAY "MB_ABORTRETRYIGNORE" 의 ID: ID_RADIO1 "MB_ICONEXCLAMATION" 의 ID: ID_RADIO7 각라디오버튼컨트롤그룹의첫라디오버튼컨트롤은 group 프러퍼티를체크해야한다.

3 다음과같이탭설정 49

50 4 ClassWizard를이용하여컨트롤과멤버변수연결 IDC_EDIT_TEXT CString m_text IDC_EDIT_CAPTION CString m_caption IDC_RADIO1 int m_type IDC_RADIO7 int m_icon 5 ClassWizard 를이용하여메시지핸들러작성 IDC_BUTTON_DISPLAY BN_CLICKED OnButtonDisplay()

6 다음입력 void CMsgboxDlg::OnButtonDisplay() { UpdateData(TRUE); int type, icon; switch (m_type) { case 0: type = MB_ABORTRETRYIGNORE; break; case 1: type = MB_OK; break; case 2: type = MB_OKCANCEL; break; case 3: type = MB_RETRYCANCEL; break; case 4: type = MB_YESNO; break; case 5: type = MB_YESNOCANCEL; break; 51

52 default: type = 0; }; } switch (m_icon) { case 0: icon = MB_ICONEXCLAMATION; break; case 1: icon = MB_ICONINFORMATION; break; case 2: icon = MB_ICONQUESTION; break; case 3: icon = MB_ICONSTOP; break; default: icon = 0; }; MessageBox(m_text, m_caption, type icon );

53 메시지박스에사용되는아이콘 아이콘모양 의미 메시지박스스타일 감탄부호 경고 MB_ICONEXCLAMATION 원안에 i 정보 MB_ICONINFORMATION 물음표 질문 MB_ICONQUESTION X 표시 에러 MB_ICONSTOP 메시지박스버튼 버튼스타일 버튼 MB_ABORTRETRYIGNORE Abort, Retry, Ignore MB_OK OK MB_OKCANCEL OK, Cancel MB_RETRYCANCEL Retry, Cancel MB_YESNO Yes, No MB_YESNOCANCEL Yes, No, Cancel

54 메시지박스리턴값 리턴값 눌려진버튼 IDABORT Abort IDCANCEL Cancel IDIGNORE Ignore IDNO No IDOK Ok IDRETRY Retry IDYES Yes

10. 다이얼로그바 55 다이얼로그바란? 컨트롤바는상태바, 툴바, 다이얼로그바세타입이있다. 다이얼로그바는툴바와유사하지만툴바와는달리버튼, 콤보박스, 리스트박스, 프로그래스컨트롤과같은컨트롤들을포함할수있다. 프로젝트생성 1 DlgBar 란이름의 MDI 유형프로젝트를생성한다. 2 새다이얼로그리소스 IDD_DIALOG1 작성 컨트롤 ID 컨트롤유형 캡션 IDC_EDIT1 Edit box IDC_BUTTON1 Pushbutton Button1

56 3 다이얼로그의리소스속성 Style: Child Border: None 4 MainFrm.h 에다음과같이입력 protected: // control bar embedded members CStatusBar m_wndstatusbar; CToolBar m_wndtoolbar; CDialogBar m_dlgbar; // Generated message map functions protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpcreatestruct); // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG afx_msg void OnButton1(); DECLARE_MESSAGE_MAP() };

57 5 MainFrm.cpp BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! ON_WM_CREATE() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BUTTON1, OnButton1) END_MESSAGE_MAP() int CMainFrame::OnCreate(LPCREATESTRUCT lpcreatestruct) { // 중간생략 m_dlgbar.create( this, IDD_DIALOG1, CBRS_TOP, IDD_DIALOG1); m_dlgbar.setwindowtext( "Dialog Bar" ); m_dlgbar.enabledocking( CBRS_ALIGN_ANY ); DockControlBar( &m_dlgbar ); return 0; }

58 void CMainFrame::OnButton1() { CString s; m_dlgbar.getdlgitem(idc_edit1)->getwindowtext(s); AfxMessageBox( s ); } 다이얼로그바는모달리스 (modeless) 대화상자와유사한윈도우형태이며툴바처럼메인프레임에부착될수있다. 툴바와는달리대화상자처럼모든컨트롤들을포함할수있다. 다이얼로그바에있는컨트롤에서발생하는메시지는다이얼로그바의부모에게전달된다. 그러나이메시지핸들러를등록하는데 ClassWizard를사용할수없다. 따라서직접메시지맵에연결항목을추가해주어야한다.

11. 상태바 59 상태바에현재시각표시하기 indicators 배열에새로운 ID 추가 문자열테이블에새로운디폴트텍스트아이템을첨가 상태바 pane을위한갱신명령핸들러를정의 타이머메시지처리핸들러작성 소스 : "06-6 SBar.zip" 프로젝트생성 1 SBar 란이름의 SDI 유형프로젝트를생성한다. 2 메뉴에서 View, Resource Symbols을선택하여다음과같이새로운리소스심볼을정의한다. 3 Resource Symbols 대화상자에서 New 버튼을누르고새리소스심볼명으로 ID_INDICATOR_CURRENT_TIME을입력한다. 4 MainFrm.cpp화일의선두에서 indicators 배열을다음과같이편집한다.

60 static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, ID_INDICATOR_CURRENT_TIME }; 5 CMainFrame::OnCreate() 함수의마지막에다음을추가한다. } m_wndstatusbar.setpaneinfo(4, ID_INDICATOR_CURRENT_TIME, SBPS_POPOUT, 80 ); return 0;

61 6 스트링테이블에 ID_INDICATOR_CURRENT_TIME란 ID의 "00:00:00 AM" 스트링리소스를추가한다. 7 ClassWizard를이용하여 CMainFrame클래스에 WM_TIMER 메시지핸들러를작성한다. void CMainFrame::OnTimer(UINT nidevent) { m_wndstatusbar.invalidaterect(null); } 8 CMainFrame 클래스에다음과같이 OnUpdateTimer() 멤버함수의정의를추가한다. // Generated message map functions protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpcreatestruct); afx_msg void OnTimer(UINT nidevent); //}}AFX_MSG afx_msg void OnUpdateTimer(CCmdUI* pcmdui); DECLARE_MESSAGE_MAP() };

62 9 다음과같이메시지멥에 OnUpdateTimer 항목을추가한다. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_TIMER() //}}AFX_MSG_MAP ON_UPDATE_COMMAND_UI(ID_INDICATOR_CURRENT_TIME, OnUpdateTimer) END_MESSAGE_MAP() 10 OnUpdateTimer() 멤버함수를정의한다. void CMainFrame::OnUpdateTimer(CCmdUI* pcmdui) { pcmdui->enable(); CTime thetime = CTime::GetCurrentTime(); CString sztime = thetime.format("%i:%m:%s %P"); pcmdui->settext(sztime); }

63 CMainFrame::OnCreate() 에서 CWnd::SetTimer() 메소드를호출하여 1000 밀리초단위로타이머를설정하였다. 1000 밀리초마다 WM_TIMER 이벤트가발생하여 CMainFrame::OnTimer() 이벤트핸들러가실행된다. CMainFrame::OnTimer() 이벤트핸들러에서는 CWnd::InvalidateRect() 를호출하여상태바를무효화시켜서다시그리게만든다. 상태바가무효화될때, MFC 프레임웍은 UPDATE_COMMAND_UI 이벤트핸들러를사용해서각 pane을갱신한다. 대부분의사용자인터페이스객체들을위한 UPDATE_COMMAND_UI 이벤트핸들러는 ClassWizard를이용하여만들수있지만, 상태바 pane 핸들러는직접작성해야한다. 8번 9번 10번절차는이렇게상태바의 UPDATE_COMMAND_UI 핸들러를만드는절차이다.