cpp chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/cpp_chap6_interface(2).pdf · 2019. 2....

63
1 1 7 8 ˜ 8 B d D 8 ¤ 3 ( 2 )

Upload: others

Post on 30-Mar-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

1

사용자 인터페이스(2)

Page 2: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

21. 대화상자 (Dialog)

• 학습목표

– Graphs 예제에서 여러가지 굵기의 선을 그릴 수 있도록 수정해본다

– 선의 굵기를 지정할 대화상자를 만들고 대화상자 클래스를 만든다

• 대화상자 구현 과정

① 리소스 에디터를 사용하여 대화상자 리소스(Resource)를 만든다. 대화상자 리소스는 대화상자의 형태를 정의한다.

② ClassWizard를 사용하여 CDialog 클래스를 상속받아 새 대화상자 클래스를 만든다. 대화상자 클래스는 대화상자의 기능을 구현한다.

③ 대화상자가 메뉴 명령에 의해 실행되려면, 메뉴 리소스에 메뉴 항목을추가하고 ClassWizard를 사용하여 메뉴 메시지 핸들러를 구현한다. 메뉴 메시지 핸들러에서 대화상자를 표시하는 코드를 구현한다.

④ 필요에따라, 대화상자 컨트롤이 보내는 메시지를 처리하는 메시지 핸들러를 구현한다.

⑤ ClassWizard를 사용하여 대화상자의 컨트롤에 해당하는 데이터 멤버를추가하고 Dialog Data Exchange와 Dialog Data Validation 설정

Page 3: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

3

• 대화상자 리소스(Resource)와 대화상자 클래스의 연결

– 대화상자 리소스는 대화상자의 형태를 정의하고, 대화상자 클래스는 대화상자의 기능을 구현한다.

– 대화상자 클래스는 대화상자 리소스에 연결되어야 한다.

– 대화상자 클래스를 정의할때 대화상자 리소스를 지정해주어야 한다.

– 대화상자의 컨트롤들은 대화상자 클래스의 멤버 변수에 연결되어야 한다.

– ClassWizard 의 Member Variables 페이지에서 대화상자 컨트롤에 해당하는 멤버 변수가 대화상자 클래스에 정의된다.

Page 4: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

4

• 프레임웍에서 대화상자는 두개의 구성 요소를 갖는다

– 다이얼로그 템플릿 리소스 (dialog template resource)

• 대화상자의 모양과 컨트롤의 배치를 리소스 에디터로 비주얼하게디자인한 리소스 템플릿이다.

• 대화상자의 크기 위치 스타일, 컨트롤의 종류 위치 등을 지정 한다

– 다이얼로그 클래스 (dialog class)

• CDialog 클래스를 상속받아 구현한 C++ 클래스

• 두 종류의 대화상자

– Modal dialog box

• 프로그램의 다른 부분으로 이동하기 전에 먼저 대화상자를 종료하여햐 하는 대화상자

– Modaless dialog box

• 보통 윈도우와 같이 다른 윈도우로 전환 가능한 대화상자를 말한다.

Page 5: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

5

• 소스: "06-1 Graphs.zip"

• 대화상자 리소스 만들기

① 메뉴에서 Insert Ą Resource Ą Dialog 선택

② 메뉴에서 Edit Ą Property 선택

③ Dialog Property 대화상자에서

• ID: IDD_LINE_WIDTH

• Caption: Line Width Dialog

④ Controls 툴바에서 Edit Box와 Static Text 버튼을 눌러 컨트롤을 추가한다.

⑤ EditBox를 오른쪽 버튼으로 누르고 Properties선택

⑥ EditBox의 ID는 IDC_LINE_WIDTH

⑦ 메뉴에서 Layout Ą Tab Order 선택Edit Box를 클릭하여 Tab Order를 1번으로 설정

Page 6: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

6

• 대화상자 클래스 만들기

① ClassWizard를 시동하면 새 대화상자에 대한 클래스 생성을 묻는 대화상자가 디스플레이 된다.

② Create New Class 를 선택

③ Create New Class 대화상자에서 다음과 같이 입력

• Name: CLineWidthDlg

• Base Class: CDialog

• Dialog ID: IDD_LINE_WIDTH

Page 7: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

7

Page 8: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

8

• 컨트롤과 멤버 변수 연결하기

① ClassWizard의 Member Variables 페이지에서

• Class Name: CLineWidthDlg

• Control IDs: IDC_LINE_WIDTH

• Add Variable 버튼 선택

② Add member variable 대화상자에서

• member variable name:m_width

• Category: Value

• Variable Type: int

• OK

③ ClassWizard 의 Member Variables 페이지에서

• Minimum Value: 0

• Maximum Value: 30

Page 9: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

9

Page 10: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

102. 메뉴

• 학습목표

– 메뉴를 눌렀을 때 대화상자가 화면에 나올 수 있도록 구현한다.

– 메뉴 리소스에 “Line Width 설정” 항목을 추가하고

– 메뉴를 눌렀을 때 실행될 메뉴 메시지 핸들러(message handler function)를 구현한다.

• 소스: "06-1 Graphs.zip"

• 메뉴 리소스에 메뉴 항목 추가

① ResourceView에서 메뉴 리소스 IDR_LINES1TYPE 편집

② 메뉴 바의 오른쪽 빈 영역을 더블 클릭하면Menu Item Properties 대화 상자가 표시된다

Page 11: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

11

③ "선(L)" 메뉴 바 아래의 메뉴 항목 더블클릭ID: ID_LINE_WIDTHCaption: 선 굵기(&W)Prompt: 선 굵기 설정₩n선 굵기

Page 12: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

12

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

Page 13: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

13

• 메뉴 메시지 핸들러 함수 구현

① ClassWizard의 Message Map 페이지에서

• Class name: CLines1Doc

• Object IDs: ID_LINE_WIDTH

• Messages: COMMAND

• Add Function 버튼 선택

② OnLineWidth 멤버 함수 추가된 것 확인

③ Edit Code 버튼을 눌러 내용 입력

#include "linewidthdlg.h"void CGraphsDoc::OnLineWidth() {

CLineWidthDlg dlg;dlg.m_width = m_width;if (dlg.DoModal() == IDOK) {m_width = dlg.m_width;

}}

Page 14: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

14

Page 15: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

15

• CDialog::DoModal()

– 모달(modal) 대화상자를 디스플레이하는 멤버 함수이다.

– 모달 대화상자는 사용자가 OK 버튼을 누르거나 Cancel 버튼을 누르면종료된다.

– 모달 대화상자가 종료되면 DoModal() 멤버 함수는 IDOK나 IDCANCEL을 리턴한다.

– CGraphsDoc::OnLineWidth 에서는 IDOK가 리턴되었을 경우에만 라인굵기를 새로 설정한다.

Page 16: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

16

• 버그 수정

– 선 굵기까지 고려하여 더 넓게 무효화하여야 한다

– InflateRectRect() 메소드로 무효화할 사각형을 확장한다

CRect CRectangle::BoundRect() {

CRect r = m_rect;r.InflateRect(m_width, m_width, m_width, m_width);return r;

};

Page 17: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

17void 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;

}

Page 18: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

18

• 커멘드 메시지

– WM_COMMAND

– 메뉴나 툴바에 의해서 발생하는 메시지

• 커맨드 메시지의 전달 순서

– 대부분의 메시지는 해당 윈도우에 직접 전달되지만 메뉴나 툴바에 의한커멘드 메시지는 CCmdTarget 클래스로부터 유도된 여러 클래스를 두루 거친다 그 중 하나의 클래스에서 처리된다. 메뉴 항목이 선택되었을때, 다음과 같은 순서로 전달된다.

① Main Frame Window

② 활성화된 Child Frame Window

③ 활성화된 Child Frame window에 연결된 활성화된 뷰

④ 활성화된 뷰에 연결되어있는 도큐먼트

⑤ 도큐먼트에 연결되어있는 도큐먼트 템플릿

⑥ CWinApp

Page 19: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

19

• 메시지 핸들러와 메시지의 연결

– 툴바와 메뉴는 커맨드 메시지를 발생시킨다

– 이 메시지를 처리할 메시지 핸들러 함수가 호출되어야 한다.

– 메시지가 발생했을 때 연결된 해당 메시지 핸들러 함수를 호출하는 기능은 MFC에 이미 구현되어 있다.

– ClassWizard에서 메시지를 처리할 메시지 핸들러를 만들어주면 된다.

• 커멘드 메시지 핸들러를 어떤 클래스에 두어야 하는가?

– "선 굵기" 메뉴의 메시지 핸들러를 어떤 클래스의 멤버 함수로 작성하여야 할까?

– 도큐먼트 클래스의 멤버 함수? 뷰 클래스의?

– 고려할 사항

• 여러 뷰에 공통적인 기능은 도큐먼트에 구현한다

• 한 뷰에 한정된 기능은 그 뷰에 구현한다

• 커멘드 메시지를 제외한 대부분의 메시지 핸들러는 보통 뷰 클래스에 구현한다.

Page 20: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

20

• 대화 상자의 배경 색 설정

– 어플리케이션의 InitInstance 멤버 함수에서 CWinApp의SetDialogBkColor 멤버 함수를 호출하여 설정

– 어플리케이션에서 만들어지는 모든 대화 상자와 메시지 박스의 배경색이 바뀜

• 대화 상자의 초기화

– CDialog::OnInitDialog() 멤버 함수를 재정의 하여 구현한다. 이 멤버 함수는 대화 상자 객체가 생성된 후, 대화 상자 윈도우가 화면에 나타나기전에 호출된다.

– 오버라이드한 OnInitDialog() 멤버 함수는에서는 부모 클래스 (CDialog)의 OnInitDialog() 멤버 함수를 반드시 호출하여야 한다.

Page 21: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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()를 호출하여 대화 상자를 닫는다.

– 모달 대화 상자 객체는 보통 함수의 로컬 변수로 스택에 생성되어 함수가 리턴되면서 소멸한다

Page 22: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

22

• 모달리스 대화 상자 닫기

– 모달리스 대화 상자는 메모리를 할당 받아 생성해야 한다

– OnClose 멤버 함수와 OnCancel멤버 함수는 DestroyWindow를 호출하고 DestroyWindow는 대화 상자 윈도우를 닫는다

– 모달리스 대화 상자의 경우 할당받은 메모리 해제는 PostNcDestroy 멤버 함수에서 delete this 하여 해제되는 기능이 이미 구현되어 있다

Page 23: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

233. 공통 대화 상자 (Common Dialog)

• 학습목표

– 여러가지 색의 선을 그릴 수 있도록 Graphs 예제를 수정한다

– 색을 지정할 때 윈도우즈에서 지원하는 색지정 Common Dialog Box를사용한다.

• 할일

– 먼저 메뉴 리소스에 “선의 색(&L)”을 추가한다.

– 메뉴 메시지 핸들러 함수를 도큐먼트 클래스에 구현한다.

– 메뉴 메시지 핸들러 함수에서는 색을 선택 대화상자를 표시하고 선택된색을 멤버 변수 m_penColor에 저장한다.

Page 24: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

24

• 공통 대화상자 클래스

– 윈도우즈의 COMMDLG.DLL에 정의된 대화상자에 대한 클래스

– 자주 사용되는 대화 상자들은 이미 만들어져 있어서 리소스나 대화 상자 클래스 만드는 작업이 필요 없이 바로 사용할 수 있다

– 다음과 같은 공통 대화상자 클래스들이 제공된다

• CColorDialog 색을 선택할 때

• CFileDialog 파일을 열거나 닫을 때

• CFindReplaceDialog 문자열을 찾거나 바꿀때

• CFontDialog 폰트를 선택할 때

• CPrintDialog 인쇄할 때

Page 25: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

25

• 소스: "06-2 Graphs.zip"

• 메뉴 항목 추가

① 메뉴의 “도형(&G)” 아래에 메뉴 항목 추가

• ID: ID_LINE_COLOR

• Caption: 선의 색 (&L)

• Prompt: 선의 색 설정₩n선의 색

• 메뉴 항목 메시지 핸들러 추가

① ClassWizard의 Message Map 페이지에서

• Class name: CLines1Doc

• Object IDs: ID_LINE_COLOR

• Messages: COMMAND

• Add Function 버튼 선택

Page 26: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

26

② Edit Code 버튼을 눌러 내용 입력

void CGraphsDoc::OnLineColor() {

CColorDialog dlg;if (dlg.DoModal() == IDOK)

m_penColor = dlg.GetColor();}

Page 27: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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 이면 모든 뷰에게 통보한다.

Page 28: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

28문제:

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

Page 29: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

294. 툴바 (Toolbar)

• 학습목표

– 툴바 버튼을 추가한다

– 메뉴의 Edit 아래에 “모두 삭제(&A)” 메뉴 항목을 추가한다.

• 소스: "06-3 Graphs.zip"

Page 30: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

30

• 툴바 버튼 만들기

① ResourceView에서 Toolbar 리소스를 열고

② 다음과 같이 툴바 버튼을 그린다.

③ View 메뉴에서 PropertiesID는 ID_LINE_WIDTH 를 선택.

Page 31: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

31

④ 다음과 같이 툴바 버튼을 그린다.

⑤ View 메뉴에서 PropertiesID는 ID_LINE_COLOR 를 선택

– 툴바 버튼은 위와 같이 리소스를 추가하고, ID를 해당 메뉴의 ID로 선택해 준다. 툴바 버튼을 누르면, 해당 메뉴를 누른 것과 같은 메시지가 전달되어, 메뉴의 경우와 같은 메시지 핸들러가 실행되므로, 따로 메시지핸들러를 구현해줄 필요가 없다.

– 컴파일하고 툴바 버튼을 눌러보라.

Page 32: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

32

• "모두 삭제(&A)" 메뉴 항목 추가

① 메뉴의 Edit 아래에 메뉴 항목을 추가하고Menu Item Propties 대화상자에서Seperator 항목을 체크하여 Sperator 추가

② 메뉴의 Edit 아래에 메뉴 항목 추가

• ID: ID_EDIT_CLEAR_ALL

• Caption: 모두 삭제(&A)

• 메뉴 항목 메시지 핸들러 등록

① ClassWizard의 Message Map 페이지에서

• Class name: CLines1Doc

• Object IDs: ID_EDIT_CLEAR_ALL

• Messages: COMMAND

• Add Function 버튼 선택

② OnEditClearAll 멤버 변수 확인

Page 33: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

33

③ Edit Code 버튼을 눌러 내용 입력

void CGraphsDoc::OnEditClearAll() {

m_rects.RemoveAll();SetModifiedFlag();UpdateAllViews(NULL);

}

• 툴바 버튼 만들기– 툴바 버튼의 ID: ID_EDIT_CLEAR_ALL 로 지정

Page 34: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

345. 메뉴 항목 상태 갱신(update)

• 소스: "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 상태가 결정된다

Page 35: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

35

• 메뉴 항목 갱신 과정

– 프레임웍은 메뉴 항목을 갱신하기 위해 메뉴 항목을 그리기 전에 하나하나 마다 UPDATE_COMMAND_UI 메시지를 커맨드 메시지 전달과정을 통해 전달한다.

– 커맨드 타겟(메뉴나 툴바 버튼) 중 UPDATE_COMMAND_UI 메시지 핸들러가 있으면 호출된다. 이 UPDATE_COMMAND_UI 메시지 핸들러에서 활성화 상태를 결정하여 설정한다.

– UPDATE_COMMAND_UI 메시지 핸들러가 없을 경우 프레임웍은 그 메뉴 항목의 커맨드 메시지 핸들러가 있는지 조사한다.

– 커맨드 메시지 핸들러가 없으면 그 메뉴 항목을 비활성화 한다.

Page 36: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

36

• CCmdUI 클래스

– UPDATE_COMMAND_UI 메시지 핸들러는 CCmdUI* 타입의 포인터를전달받는다.

– 이 포인터를 메뉴 항목이나 툴바 버튼 같은 커멘트 메시지를 발생시키는 사용자 인터페이스 객체에 대한 포인터이다.

– 이 포인터를 사용하여 상태를 설정한다.

• 상태 바(status bar)에 정보 표시

– 상태 바 기능은 AppWizard가 코드를 생성한다

– 마우스가 메뉴 항목 위를 지나갈 때 그 메뉴에 대한 설명이 상태 바에표시되는 기능은 이미 구현되어 있다.

– 리소스 에디터로 메뉴를 정의할 때 Prompt String에 입력하는 문자열이상태바에 표시된다. Prompt String은 ‘₩n’ 문자를 중심으로 앞과 뒤로

나뉘는데, 앞부분은 상태바에 표시되는 내용이고 뒷 부분은 툴 팁(tool tip)이다.

Page 37: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

37

• 메뉴 항목의 갱신 메시지 핸들러 등록

① ClassWizard의 Message Map 페이지에서

• Class name: CGraphsDoc

• Object IDs: ID_EDIT_CLEAR_ALL

• Messages: UPDATE_COMMAND_UI 선택

② OnUpdateEditClearAll 멤버 변수 확인

③ Edit Code 버튼을 눌러 내용 입력

void CGraphsDoc::OnUpdateEditClearAll(CCmdUI* pCmdUI) {

pCmdUI->Enable(m_rects.GetSize() > 0);}

Page 38: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

38

• OnUpdateEditClearAll()은 파라미터 한개를 갖는다. CCmdUI객체에 대한포인터이며 Clear All 메뉴 항목을 가르킨다

• m_rects가 비어있으면 메뉴 항목을 disable시키고 비어있지 않으면 enable 시킨다

• 메뉴나 툴바 버튼이 모두 같이 상태가 갱신된다.

Page 39: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

396. 메시지의 종류

• 일반 윈도우 메시지

– 일반 윈도우 메시지는 윈도우에 직접 전달된다

– WM_PAINT와 같은 메시지는 윈도우의 일정 영역을 다시 그려야 할 필요성이 발생 했을 때 그 윈도우에 직접 전달된다

– 마우스 메시지 역시 그 마우스가 위치한 윈도우에 직접 전달된다

• 커맨드 메시지

– 커맨드 메시지는 사용자의 명령(메뉴, 툴바, 액셀러레이터 키)에 의해서발생한다.

– WM_COMMAND 메시지 형태로 어플리케이션에 전달된다.

– 커맨드 메시지를 처리할 클래스는 정해져 있지 않고 프로그래머가 결정한다

Page 40: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

40

• Update Command UI 커맨드 메시지

– Update Command UI 커맨드 메시지는 어플리케이션 프레임웍 내부에서 발생된다

– 메뉴 아이템이나 툴바 버튼과 같은 사용자 인터페이스 객체의 상태를갱신하려 할 때 발생한다.

– 예를 들면

• 현재 어플리케이션의 상태에서 메뉴의 어떤 명령을 수행할 수 없다면 그 메뉴를 회색으로 비활성화 시켜야 한다

• 사용자가 메뉴 바를 클릭하여 서브 메뉴 아이템들이 디스플레이 되어야 할 때

• 어플리케이션 프레임웍은 각 메뉴 아이템 마다 Update Command UI 커멘드 메시지를 발생시킨다

• 이 메시지 핸들러에서 메뉴 아이템의 상태를 설정한다.

Page 41: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

41

• Control Notification 메시지

– 차일드 컨트롤(child control) 윈도우는 자신의 상태 변경을 부모 윈도우인 대화상자에게 메시지를 보내서 알린다

– 예를 들면 edit box에서 키보드를 눌러 문자를 입력하면 EN_UPDATE 란 메시지가 부모 윈도우에 전달된다.

Page 42: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

427. 컨텍스트 메뉴

• 학습목표Graphs의 뷰에서 마우스 오른쪽 버튼을 클릭할 때 간단한 컨테스트 메뉴가표시되게 해 본다.

• 소스: "06-4 Graphs.zip"

• 메뉴 리소스 만들기

① 메뉴에서 Insert Ą Resource 선택

② Insert Resource 대화 상자에서 Menu 선택

③ 메뉴바의 맨 윗 단계에 아이템 하나 추가캡션은 아무거나 상관 없음

④ 그 메뉴 아래에 아래와 같은 메뉴 항목 추가

• 메뉴 ID 캡션

• ID_LINE_WIDTH 선 굵기(&W)

• ID_LINE_COLOR 선의 색(&L)

• <sperator>

• ID_EDIT_CLEAR_ALL 전체 삭제(&A)

Page 43: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

43

⑤ 새로 추가된 메뉴 리소스의 ID를 IDR_POPUP_MENU로 설정

⑥ ClassWizard의 Message Map 페이지에서

• Object ID CGraphsView

• Message WM_RBUTTONDOWN

• Member function OnRButtonDown

⑦ 다음 입력

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);

}

Page 44: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

44

– CMenu::LoadMenu()는 리소스에서 메뉴를 읽어오고CMenu::GetSubMenu(n)는 메뉴의 n번째 서브 메뉴에 대한 포인터를리턴한다.

– CMenu::TrackPopupMenu()는 스크린 좌표로 주어진 위치에 부동 팝업메뉴를 출력한다.

• 첫 번째 파라미터는 메뉴 항목을 선택할 마우스 버튼을 지정하는 상수와, 마우스 포인터에 대한 팝업 메뉴의 위치를 지정하는 상수이다

• 그 다음 파라미터는 메뉴가 표시될 x, y 좌표

• 마지막 파라미터는 메뉴를 소유하는 윈도우를 지정한다. AfxGetApp()->m_pMainWnd 는 어플리케이션 메인 프래임 윈도우이다.

Page 45: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

458. DDX와 DDV

• 대화 상자에서 데이터 읽어오기

– CWnd클래스의 SetDlgItemText, GetDlgItemText 멤버 함수를 이용하여 대화상자 컨트롤에 값을 설정하거나 입력된 값을 가져올 수있다.

– 그런데 MFC가 제공하는 DDX 방법을 이용하면 훨씬 간편하다.

• DDX와 DDV를 구현하기 위해서는

– ClassWizard를 이용하여 다이얼로그 클래스의 멤버 변수를 정의하고데이터 타입과 validation rule을 정의해주면 된다

– ClassWizard는 대화 상자 클래스의 생성자에 멤버 변수의 초기화 코드를 첨가하고, 컨트롤과 멤버 변수 간 데이터 교환을 위해 대화 상자 클래스의 DoDataExchange 멤버 함수에 DDV, DDX 루틴 첨가한다.

Page 46: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

46

• DDX (Dynamic Data Exchange)

– 대화 상자의 컨트롤과 다이얼로그 클래스의 멤버 변수 간 데이터 교환을 자동화한다.

– DDX를 이용하면 언제든지 컨트롤의 값을 다이얼로그 클래스의 멤버 변수에 가져올 수 있고 역도 가능하다.

– 데이터를 멤버 변수에 가져오려면 UpdateData(TRUE)를 호출하고 반대로 보내려면 UpdateData(FALSE)를 호출한다.

– 모달리스 대화 상자에서 Cancel버튼이 선택된 경우 DDX는 발생하지않는다. 즉 대화상자에 입력한 값을 멤버 변수에 가져오지 않는다

• DDV (Dynamic Data Validation)

– 다어얼로그 박스에 입력되는 데이터의 유효화 검증 기능이다.

– 예를 들면 정수 값의 경우 최대값 최소값을 검사하여 이 범위를 벗어날경우 경고 메시지가 저절로 출력된다.

Page 47: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

479. 메시지 박스

• 소스: "06-5 Msgbox.zip"

• 메시지 박스를 만들어 본다

① Dialog based 프로젝트를 Msgbox란 이름으로 생성한다.

② 다음과 같이 대화상자 리소스 편집

Page 48: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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 프러퍼티를체크해야한다.

Page 49: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

49

③ 다음과 같이 탭 설정

Page 50: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

50

④ ClassWizard를 이용하여 컨트롤과 멤버 변수 연결

IDC_EDIT_TEXT CString m_textIDC_EDIT_CAPTION CString m_captionIDC_RADIO1 int m_typeIDC_RADIO7 int m_icon

⑤ ClassWizard를 이용하여 메시지 핸들러 작성IDC_BUTTON_DISPLAY BN_CLICKED OnButtonDisplay()

Page 51: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

51

⑥ 다음 입력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;

Page 52: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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 );

}

Page 53: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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

Page 54: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

54

• 메시지 박스 리턴 값

리턴값 눌려진 버튼

– IDABORT Abort

– IDCANCEL Cancel

– IDIGNORE Ignore

– IDNO No

– IDOK Ok

– IDRETRY Retry

– IDYES Yes

Page 55: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

5510. 다이얼로그 바

• 다이얼로그 바란?

– 컨트롤바는 상태바, 툴바, 다이얼로그 바 세 타입이 있다.

– 다이얼로그 바는 툴바와 유사하지만 툴바와는 달리 버튼, 콤보 박스, 리스트 박스, 프로그래스 컨트롤과 같은 컨트롤들을 포함할 수 있다.

• 프로젝트 생성

① DlgBar 란 이름의 MDI 유형 프로젝트를 생성한다.

② 새 다이얼로그 리소스 IDD_DIALOG1 작성

컨트롤 ID 컨트롤 유형 캡션

IDC_EDIT1 Edit box

IDC_BUTTON1 Pushbutton Button1

Page 56: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

56

③ 다이얼로그의 리소스 속성Style: ChildBorder: None

④ MainFrm.h에 다음과 같이 입력

protected: // control bar embedded membersCStatusBar m_wndStatusBar;CToolBar m_wndToolBar;CDialogBar m_dlgBar;

// Generated message map functionsprotected:

//{{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_MSGafx_msg void OnButton1();DECLARE_MESSAGE_MAP()

};

Page 57: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

57

⑤ 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_MAPON_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;

}

Page 58: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

58

void CMainFrame::OnButton1(){

CString s;m_dlgBar.GetDlgItem(IDC_EDIT1)->GetWindowText(s);AfxMessageBox( s );

}

– 다이얼로그바는 모달리스(modeless) 대화 상자와 유사한 윈도우 형태이며 툴바처럼 메인 프레임에 부착될 수 있다.

– 툴바와는 달리 대화상자처럼 모든 컨트롤들을 포함할 수 있다.

– 다이얼로그바에 있는 컨트롤에서 발생하는 메시지는 다이얼로그 바의부모에게 전달된다. 그러나 이 메시지 핸들러를 등록하는데ClassWizard를 사용할 수 없다. 따라서 직접 메시지 맵에 연결 항목을추가해 주어야 한다.

Page 59: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

5911. 상태바

• 상태바에 현재 시각 표시하기

– indicators 배열에 새로운 ID 추가

– 문자열 테이블에 새로운 디폴트 텍스트 아이템을 첨가

– 상태바 pane을 위한 갱신 명령 핸들러를 정의

– 타이머 메시지 처리 핸들러 작성

• 소스: "06-6 SBar.zip"

• 프로젝트 생성

① SBar 란 이름의 SDI 유형 프로젝트를 생성한다.

② 메뉴에서 View, Resource Symbols을 선택하여 다음과 같이 새로운 리소스 심볼을 정의한다.

③ Resource Symbols 대화상자에서 New 버튼을 누르고 새 리소스 심볼명으로 ID_INDICATOR_CURRENT_TIME을 입력한다.

④ MainFrm.cpp화일의 선두에서 indicators 배열을 다음과 같이 편집한다.

Page 60: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

60

static UINT indicators[] = {

ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, ID_INDICATOR_CURRENT_TIME

};

⑤ CMainFrame::OnCreate() 함수의 마지막에 다음을 추가한다.

m_wndStatusBar.SetPaneInfo(4, ID_INDICATOR_CURRENT_TIME,SBPS_POPOUT, 80 );

return 0;}

Page 61: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

61

⑥ 스트링 테이블에 ID_INDICATOR_CURRENT_TIME란 ID의"00:00:00 AM" 스트링 리소스를 추가한다.

⑦ ClassWizard를 이용하여 CMainFrame클래스에 WM_TIMER 메시지 핸들러를 작성한다.

void CMainFrame::OnTimer(UINT nIDEvent) {

m_wndStatusBar.InvalidateRect(NULL);}

⑧ CMainFrame 클래스에 다음과 같이 OnUpdateTimer() 멤버 함수의 정의를 추가한다.

// Generated message map functionsprotected:

//{{AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnTimer(UINT nIDEvent);//}}AFX_MSGafx_msg void OnUpdateTimer(CCmdUI* pCmdUI);DECLARE_MESSAGE_MAP()

};

Page 62: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

62

⑨ 다음과 같이 메시지 멥에 OnUpdateTimer 항목을 추가한다.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)//{{AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()ON_WM_TIMER()//}}AFX_MSG_MAPON_UPDATE_COMMAND_UI(ID_INDICATOR_CURRENT_TIME, OnUpdateTimer)

END_MESSAGE_MAP()

⑩ OnUpdateTimer() 멤버 함수를 정의한다.

void CMainFrame::OnUpdateTimer(CCmdUI* pCmdUI){

pCmdUI->Enable();CTime theTime = CTime::GetCurrentTime();CString szTime = theTime.Format("%I:%M:%S %P");pCmdUI->SetText(szTime);

}

Page 63: CPP chap6 interface(2)compiler.sangji.ac.kr/lecture/cpp/CPP_chap6_interface(2).pdf · 2019. 2. 14. · • Class Name: CLineWidthDlg • Control IDs: IDC_LINE_WIDTH • Add Variable

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 핸들러는 직접 작성해야 한다.

• ⑧번 ⑨번 ⑩번 절차는 이렇게 상태바의 UPDATE_COMMAND_UI 핸들러를만드는 절차이다.