+ All Categories
Home > Documents > Windows Programming

Windows Programming

Date post: 30-Dec-2015
Category:
Upload: medge-moore
View: 183 times
Download: 0 times
Share this document with a friend
Description:
Windows Programming. 박 상 원 [email protected] 한국외국어대학교 정보통신공학과. 서론. 목차. 객체지향이란 ? MFC 의 역사 MFC 를 위한 C++ 의 기초. 객체지향 개념의 등장 배경. 프로그래밍 언어의 발전 기계어 -> 어셈블리어 -> 고급언어 함수 기반 프로그래밍 1970 년대 - 1980 년대 소프트웨어의 위기 생산성 향상의 한계 객체지향 개념의 등장 1980 년대. 객체지향이란 ?. 객체 메쏘드 호출. 메시지. 이벤트. - PowerPoint PPT Presentation
470
ISLab ICE HUFS ISLab ICE HUFS Windows Programming Windows Programming 박 상 원 [email protected] 한국외국어대학교 정보통신공학과
Transcript
Page 1: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

Windows ProgrammingWindows Programming

박 상 원[email protected]

한국외국어대학교 정보통신공학과

Page 2: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

서론서론

Page 3: Windows Programming

MFC Tutorial 3

ISLab ICE HUFSISLab ICE HUFS

목차목차

• 객체지향이란 ? • MFC 의 역사• MFC 를 위한 C++ 의 기초

Page 4: Windows Programming

MFC Tutorial 4

ISLab ICE HUFSISLab ICE HUFS

객체지향 개념의 등장 배경객체지향 개념의 등장 배경

• 프로그래밍 언어의 발전– 기계어 -> 어셈블리어 -> 고급언어

• 함수 기반 프로그래밍– 1970 년대 - 1980 년대

• 소프트웨어의 위기– 생산성 향상의 한계

• 객체지향 개념의 등장– 1980 년대

Page 5: Windows Programming

MFC Tutorial 5

ISLab ICE HUFSISLab ICE HUFS

객체지향이란객체지향이란 ??

객체메쏘드 호출메시지메시지

이벤트

Page 6: Windows Programming

MFC Tutorial 6

ISLab ICE HUFSISLab ICE HUFS

객체지향의 핵심 내용객체지향의 핵심 내용 (1)(1)• 객체란

– 데이타 ( 자료구조 ; 상태변수 ) 와 오퍼레이터 ( 함수 ) 가 하나로 묶여있는 형태

• 추상 데이타 타입 (ADT;abstract data type)– 클래스를 이용하여 표현

• 계승 (inheritance)– 동적 바인딩 (dynamic binding)– cf) Static binding

• 다형성 (polymorphism)– Overloading : 동일한 함수의 이름 사용 가능– Overriding : 상위 클래스에서 정의된 함수를 하위 클래스에서 재 정의– Template : 타입을 인자로 하여 새로운 타입을 생성

Page 7: Windows Programming

MFC Tutorial 7

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 를 위한 를 위한 C++C++ 의 기초의 기초

• 클래스• 계승• 생성자 및 소멸자• Virtual Function 을 이용한 동적 바인딩

Page 8: Windows Programming

MFC Tutorial 8

ISLab ICE HUFSISLab ICE HUFS

클래스란클래스란 ??

• 객체를 기술할 수 있는 수단을 제공– 자료 구조 (member data)– 오퍼레이션 (member function)

실세계 컴퓨터세계

모델링

Page 9: Windows Programming

MFC Tutorial 9

ISLab ICE HUFSISLab ICE HUFS

클래스의 계승클래스의 계승 (1)(1)

• 계승을 통한 코드의 재 사용 가능– 생산성 향상

• 이름 충돌 (name conflict) 발생• 다중 계승의 문제점

– virtual base class 로 계승

Page 10: Windows Programming

MFC Tutorial 10

ISLab ICE HUFSISLab ICE HUFS

클래스의 계승클래스의 계승 (2)(2)

class B : virtual public A{

...};

class C : virtual public A{

...};

Aint x;

Aint x;

Bint y;

Bint y;

Cint z;

Cint z;

Dint z;

Dint z;

Page 11: Windows Programming

MFC Tutorial 11

ISLab ICE HUFSISLab ICE HUFS

생성자생성자 (1)(1)

• 생성자 (constructor) 호출– 메모리 할당과 생성자는 별개– 메모리 할당

• new : 힙 (heap) 에 객체 생성• 지역변수 : 스택 (stack) 에 객체 생성• 전역변수 : 프로그램 코드 영역에 객체 생성

– 생성자는 메모리 할당이 끝난 객체의 각 데이타 부분을 초기화하는 역할

Page 12: Windows Programming

MFC Tutorial 12

ISLab ICE HUFSISLab ICE HUFS

생성자생성자 (2)(2)

A::A(int n) : m_nNo(n){}

B::B(int i) : A( i ){

ptr = new char[ i ];}

AA

int m_nNoint m_nNo

BB

char* ptrchar* ptr

A* pA = new B(3);

33

500500 500

힙 (heap) 영역

힙 / 스택 / 코드 영역

Page 13: Windows Programming

MFC Tutorial 13

ISLab ICE HUFSISLab ICE HUFS

소멸자소멸자 (1)(1)

• 소멸자 (destructor) 의 virtual 함수화– 소멸자는 객체 자체의 메모리 영역을 없애는 것이 아님– 그 객체가 new 등을 이용하여 실행중에 만든 객체를 메모리에서

없애는 역할을 한다 .

Page 14: Windows Programming

MFC Tutorial 14

ISLab ICE HUFSISLab ICE HUFS

소멸자소멸자 (2)(2)

A* ptr = new A;delete ptr;

ptr = new B(3);delete ptr; <- 문제 발생 . A 의 소멸자만 불린다 .

33

500500500

힙 (heap) 영역

힙 / 스택 / 코드 영역접근못하는 메모리(garbage)

Page 15: Windows Programming

MFC Tutorial 15

ISLab ICE HUFSISLab ICE HUFS

Virtual Function(1)Virtual Function(1)

• 동적 바인딩 (dynamic binding)– 프로그램의 수행 중에 실제 수행할 함수를 결정– vitual function table(hidden pointer)

• 정적 바인딩 (static binding)

Page 16: Windows Programming

MFC Tutorial 16

ISLab ICE HUFSISLab ICE HUFS

Virtual Function(2)Virtual Function(2)

DrawObj* p_obj;

p_obj = new Point;p_obj->Draw();

p_obj = new Line;p_obj->Draw();

p_obj = new PolyLine;p_obj->Draw();

int a

virtual Draw()

int x, y

virtual Draw()

Point start, end

virtual Draw()virtual Calc()

Point[5] pt

virtual Draw()

DrawObj

Point Line

PolyLine

Page 17: Windows Programming

MFC Tutorial 17

ISLab ICE HUFSISLab ICE HUFS

Virtual Function - Virtual Function - 메모리 구조메모리 구조p_obj = new DrawObj;

p_obj->Draw();

p_obj = new Line;p_obj->Draw();

p_obj = new PolyLine;p_obj->Draw();

vtbl 50vtbl 50

vtbl 100vtbl 100

int aint a

Point startPoint start

Point endPoint end

vtbl 180vtbl 180

int aint a

Point startPoint start

Point endPoint end

Point[0] ptPoint[0] pt

int aint a

250250

350430

350430

550430

550430

DrawObj::DrawDrawObj::Draw

Line::DrawLine::Draw

Line::CalcLine::Calc

PolyLine::DrawPolyLine::Draw

50

100

180

250

350

430

550

Code 영역

virtualfunctiontable

pointerofvirtualfunctiontable

Point[1] ptPoint[1] pt

Point[2] ptPoint[2] pt

Point[3] ptPoint[3] pt

Point[4] ptPoint[4] pt

Page 18: Windows Programming

MFC Tutorial 18

ISLab ICE HUFSISLab ICE HUFS

Virtual Function Virtual Function 사용 예사용 예CObList list;DrawObj* p_obj;p_obj = new Line;list.AddTail(p_obj);p_obj = new Point;list.AddTail(p_obj);. . . .POSITION pos = list.GetHeadPosition();while(pos != NULL){

p_obj = (DrawObj*)list.GetNext(pos);p_obj->Draw();

}

LineLine PointPoint LineLine PolyLinePolyLine PointPoint

List

Page 19: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

MFC MFC 기초기초

Page 20: Windows Programming

MFC Tutorial 20

ISLab ICE HUFSISLab ICE HUFS

목차목차

• SDK 와 MFC 의 비교• MFC 클래스 종류• AppWizard 를 이용한 프로젝트 생성• Develop Studio 사용법• Hungarian 표기법

Page 21: Windows Programming

MFC Tutorial 21

ISLab ICE HUFSISLab ICE HUFS

Windows APIWindows API

• Applicatoin Programming Interface• Windows System Calls• Windows 3.1

– Win16 API

• Windows 95/NT– Win32 API

• C 라이브러리

Page 22: Windows Programming

MFC Tutorial 22

ISLab ICE HUFSISLab ICE HUFS

SDK SDK 프로그래밍프로그래밍

• SDK(Software Development Kit)– 윈도우 프로그래밍을 위한 여러 가지 툴과 라이브러리로

구성되어 있는 마이크로소프트에 의해 발표된 소프트웨어 패키지

– 윈도우 프로그래밍시 호출하여 사용할 수 있는 함수들이 포함 ( 윈도우 API)

– C 라이브러리

Page 23: Windows Programming

MFC Tutorial 23

ISLab ICE HUFSISLab ICE HUFS

메시지와 메시지 큐메시지와 메시지 큐

• 메시지 (message)?– 윈도우에서 발생하는 사건들의 표현– 숫자 (winuser.h)

• 메시지 큐 (queue)– 하나의 프로그램에 하나씩 할당

윈도우에 사건이 발생하면운영체제는 이를 메시지로 만들어

발생 순서대로 메시지 큐에넣는다 .

Page 24: Windows Programming

MFC Tutorial 24

ISLab ICE HUFSISLab ICE HUFS

메시지 루프메시지 루프 , , 윈도우 프로시저윈도우 프로시저

• 메시지 루프– 메시지 큐에서 메시지를 하나씩 꺼내어 거기에 맞게 처리

• 윈도우 프로시저– 메시지의 실제 처리

운영체제 응용 프로그랭

메시지를 하나씩 읽어다가이를 처리할 윈도우의 윈도우프로시저를 호출한다 .

Page 25: Windows Programming

MFC Tutorial 25

ISLab ICE HUFSISLab ICE HUFS

메시지에 의한 동작메시지에 의한 동작

• Message-driven operationsint WinMain(HINSTANCE ......)

{

. . .

InitApplication(hInstance);

InitInstance(hInstance);

. . .

. . .

while(GetMessage(....))

{

. . .

DispatchMessage(. . .);

}

. . .

}

메시지 큐

윈도우에 사건이 발생하면운영체제는 이를 메시지로만들어 발생 순서대로메시지 큐에 넣는다 .

msg

함수

Page 26: Windows Programming

MFC Tutorial 26

ISLab ICE HUFSISLab ICE HUFS

SDK SDK 프로그램의 예프로그램의 예#include “windows.h” // SDK 의 API 와 각종 상수 , 구조체가 정의된 헤더 화일#include “generic.h” // 이 프로그램 내에서 사용할 상수가 정의되고 함수가 // 선언된 헤더 화일

HINSTANCE hInst; // 인스턴스 핸들을 기억해둔다 .HWND hMainWnd; // 메인 윈도우 핸들을 기억해 둔다 .

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ MSG msg;

if (!hPrevInstance) if (!InitApplication(hInstance)) // 윈도우 클래스를 등록한다 . return FALSE;

hInst = hInstance; // 인스턴스 핸들을 전역 변수에 기억해둔다 . if (!InitInstance(hInstance, nCmdShow)) // 메인 윈도우를 생성한다 . return FALSE;

Page 27: Windows Programming

MFC Tutorial 27

ISLab ICE HUFSISLab ICE HUFS

// 메시지 루프에 진입한다 .

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (msg.wParam);

}

Page 28: Windows Programming

MFC Tutorial 28

ISLab ICE HUFSISLab ICE HUFS

InitApplicationInitApplication

BOOL InitApplication(HINSTANCE hInstance)

{

WNDCLASS wc; // WNDCLASS 는 윈도우 클래스의 등록에 필요한 구조체이다 .

wc.style = NULL;

wc.lpfnWndProc=MainWndProc; // 윈도우의 윈도우 프로시저 이름을 지정한다 wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance; // 윈도우가 속한 인스턴스의 핸들을 지정한다 .

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);// 이 윈도우의 아이콘 지정 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 이 윈도우의 커서 지정 wc.hbrBackground = GetStockObject(WHITE_BRUSH); // 배경색 지정 wc.lpszMenuName = “EX_Menu”; // 이 윈도우의 메뉴를 지정한다 wc.lpszClassName = “EX_WClass”; // 이 윈도우의 클래스 이름을 지정한다 .

return RegisterClass(&wc); // 이 윈도우 클래스를 등록한다 .

}

Page 29: Windows Programming

MFC Tutorial 29

ISLab ICE HUFSISLab ICE HUFS

InitInstanceInitInstanceBOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

HWND hWnd;

hMainWnd = hWnd = CreateWindow(

“EX_WClass”, // 생성하려는 윈도우의 윈도우 클래스 이름 “EX Program”, // 윈도우의 타이틀을 지정한다 .

WS_OVERLAPPEDWINDOW, // 윈도우의 스타일을 지정한다 .

CW_USEDEFAULT, // 윈도우의 시작 X 좌표 CW_USEDEFAULT, // 윈도우의 시작 Y 좌표 CW_USEDEFAULT, // 윈도우의 폭 CW_USEDEFAULT, // 윈도우의 높이 NULL, // 부모 윈도우의 핸들 NULL,

hInstance, // 이 윈도우가 속한 인스턴스의 핸들 NULL

);

if (!hWnd) return FALSE; // 윈도우가 실패했으면 ShowWindow(hWnd, nCmdShow); // 메인 윈도우의 형태를 결정하고 WM_PAINT 발생

UpdateWindow(hWnd); // WM_PAINT 메시지를 바로 처리해버린다 .

return TRUE;

}

Page 30: Windows Programming

MFC Tutorial 30

ISLab ICE HUFSISLab ICE HUFS

윈도우 스타일윈도우 스타일 (1)(1)

WS_OVERLAPPED 겹쳐질 수 있는 윈도우를 생성한다 .

WS_SYSMENU 윈도우에 시스템 메뉴를 붙인다 .

WS_CAPTION 윈도우에 타이틀바를 사용한다 .

WS_THICKFRAME 윈도우의 테두리선을 굵은선으로 한다 .

WS_MINIMIZEBOX 축소 버튼을 윈도우 타이틀바 오른쪽에 붙인다 .

WS_MAXIMIZEBOX 확대 버튼을 윈도우 타이틀바 오른쪽에 붙인다 .

WS_CHILD 다른 윈도우의 자식 윈도우로 생성한다 .

WS_VISIBLE 윈도우의 생성과 동시에 윈도우를 보이게 한다 .

WS_BORDER 윈도우에 테두리를 긋는다 .

WS_MAXIMIZE 윈도우를 전체 화면 크기로 생성한다 .

WS_MINIMIZE 윈도우를 아이콘 모양으로 생성한다 .

WS_HSCROLL 윈도우에 수평 스크롤바를 붙여 생성한다 .

WS_VSCROLL 윈도우에 수직 스크롤바를 붙여 생성한다 .

Page 31: Windows Programming

MFC Tutorial 31

ISLab ICE HUFSISLab ICE HUFS

윈도우 스타일윈도우 스타일 (2)(2)

WS_POPUP 팝업 윈도우를 생성한다 . 이것은 WS_CHILD 와함께 사용될 수 없다 .

WS_CLIPSIBLINGS 같은 레벨의 자식 윈도우간에 겹치는 영역이 있을때 각각의 자식 윈도우가 다른 겹치는 자식 윈도우의 영역으로 넘어가지 못하도록 한다 . 이 스타일을주지 않았을 경우 자식 윈도우끼리 겹칠 때 이상하게 그려지는 상황이 발생할 수 있다 .

WS_CLIPCHILDREN 자식 윈도우가 차지하는 영역은 부모 윈도우의 영역에서 제외된다 . 부모 윈도우를 생성할 경우 주어야 한다 .

#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION \

| WS_SYSMENU | WS_THICKFRAME \

| WS_MINIMIZEBOX | WS_MAXIMIZEBOX)

Page 32: Windows Programming

MFC Tutorial 32

ISLab ICE HUFSISLab ICE HUFS

윈도우 프로시저 윈도우 프로시저 MainWndProcMainWndProc

long APIENTRY MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_COMMAND: // 사용자가 메뉴 항목을 선택하면 발생하는 메시지 { case ID_FILE_EXIT: SendMessage(hWnd, WM_CLOSE, 0, 0); break; } case WM_PAINT: // 윈도우의 사용자 영역이 복구되어야 할 때 발생하는 메시지 { HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hWnd, &ps); TextOut(hDC, 10, 10, “Hello, everybody”, 16); EndPaint(hWnd, &ps); break; }

Page 33: Windows Programming

MFC Tutorial 33

ISLab ICE HUFSISLab ICE HUFS

case WM_DESTROY: // 윈도우가 없어지기 직전에 발생하는 메시지 {

PostQuitMessage(0);

break;

}

default: // 처리하지 못한 메시지를 넘긴다 .

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

Page 34: Windows Programming

MFC Tutorial 34

ISLab ICE HUFSISLab ICE HUFS

generic.h & resource.hgeneric.h & resource.h

• generic.h#include “resource.h”

int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);

BOOL InitApplication(HANDLE);

BOOL InitInstance(HANDLE, int);

long APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);

• resource.h#define ID_FILE_EXIT 100

Page 35: Windows Programming

MFC Tutorial 35

ISLab ICE HUFSISLab ICE HUFS

generic.rcgeneric.rc

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS#include "afxres.h"

#undef APSTUDIO_READONLY_SYMBOLS// Korean resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)

#ifdef _WIN32

LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT

#pragma code_page(949)#endif //_WIN32

// Menu

EX_Menu MENU DISCARDABLE BEGIN POPUP "File" BEGIN MENUITEM "Exit",

ID_FILE_EXIT ENDEND

#ifdef APSTUDIO_INVOKED

#endif // Korean resources

#ifndef APSTUDIO_INVOKED// Generated from the TEXTINCLUDE 3

resource.

#endif // not APSTUDIO_INVOKED

Page 36: Windows Programming

MFC Tutorial 36

ISLab ICE HUFSISLab ICE HUFS

핸들핸들 (Handle)(Handle)

• 무엇인가를 구별하기 위해 붙인 번호– 예 ) 윈도우 핸들 (HWND)

• 윈도우가 여러 개 존재할 경우 이를 구별하기 위해 윈도우마다 번호를 하나씩 부여

• 핸들 타입 앞에는 H 가 붙는다 .

• UINT 로부터 재정의– #define UINT HANDLE– #define HANDLE HWND

Page 37: Windows Programming

MFC Tutorial 37

ISLab ICE HUFSISLab ICE HUFS

타입타입BOOL 참 , 거짓을 나타내는 타입으로 int 로부터 재정의 되었으며

TRUE, FALSE 값을 갖는다 .

LPSTR char 타입에 대한 포인터 , 즉 char * 와 같다 . Long Pointer to STRing 을 나타낸다 .

LPCTSTR는 const char * 와 같다 .

HWND 윈도우들을 구별하기 위해 윈도우에 붙여지는 핸들 타입

HINSTANCE 인스턴스의 구별을 위해 인스턴스마다 부여되는 핸들 타입

UINT unsigned int 에 해당 . Win32 에서는 4 바이트

HANDLE 모든 핸들 타입의 원조에 해당하는 타입 . UINT 로 부터 typedef 문을 이용해 재정의 . H로 시작되는 모든 핸들

타입은 모두 이것으로부터 typedef 문으로 재정의 됨 .

WPARAM UINT 로부터 재정의 . 메시지에 수반되는 부가 정보를 나타냄 .

LPARAM LONG으로부터 재정의 . 메시지에 수반되는 부가 정보 표시

Page 38: Windows Programming

MFC Tutorial 38

ISLab ICE HUFSISLab ICE HUFS

주요 메시지주요 메시지 (1)(1)

WM_CREATE 윈도우가 생성될 때 발생한다 . 정확히 말하면 CreateWindow API 가 호출되었을 때 발생한다 . 이 메시지 처리부에서 초기화 작업을 수행하는 것이 일반적이다 . 아직 윈도우가 보이지 않는다 .

WM_SIZE 윈도우의 크기가 변화하면 발생 . 이 메시지가 발생하면 그 뒤에 WM_PAINT 가 따라서 발생한다 .

WM_PAINT 윈도우의 사용자 영역이 가려졌다가 앞으로 나온다든가 해서 다시 그려질 일이 생기면 발생하는 메시지이다 . InvalidateRect 와 같은 API 로 발생시키는 것도 가능하다 .

WM_COMMAND 사용자가 메뉴에서 명령을 선택하면 발생

WM_CLOSE 사용자가 윈도우의 시스템 메뉴에서 닫기 (Close) 를 택하면 발생 . DefWindowProc 함수는 WM_CLOSE 메시지를 받으면 WM_DESTROY 메시지를 발생

Page 39: Windows Programming

MFC Tutorial 39

ISLab ICE HUFSISLab ICE HUFS

주요 메시지주요 메시지 (2)(2)

WM_DESTROY 윈도우가 없어지기 직전에 발생한다 . 여기서는 앞서 윈도우 프로시저의 실행중에 할당한 자원들이있다면 이를 운영체제에 반환하는 역할을 수행함 .메인 윈도우의 WM_DESTROY 메시지 처리부에서는 끝부분에서 PostQuitMessage 함수를 호출하는것이 일반적이다 .

WM_QUIT PostQuitMessage 함수를 호출하면 이 메시지가 만들어져 메시지 큐에 들어가게 된다 . 메시지 루프에서 이 메시지를 읽어가면 GetMessage 함수의 리턴값이 FALSE가 되기 때문에 메시지 루프가 끝나게되고 프로그램이 종료된다 .

Page 40: Windows Programming

MFC Tutorial 40

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 란란

• 클래스 라이브러리– 클래스의 집합 ( 함수의 집합이 아님 )

• 애플리케이션 프레임워크 (application framework)– AppWizard– ClassWizard– Project Workspace

Page 41: Windows Programming

MFC Tutorial 41

ISLab ICE HUFSISLab ICE HUFS

MFC MFC 구조구조

• MFC 는 SDK API 의 기능을 구분하여 클래스 계층구조를 입힌 것

• 응용 프로그램은 SDK API 를 직접 부를 수 있음

• “Handle” 은 분류의 기준이 됨

응용프로그램

MFC

SDK API

운영체제

Page 42: Windows Programming

MFC Tutorial 42

ISLab ICE HUFSISLab ICE HUFS

왜 왜 MFC MFC 인가인가 ??

• 이해가 쉬움 – 연관된 함수와 데이타를 “클래스”를 이용하여 그룹화하였음

• 코드의 재사용성 향상• 소프트웨어 개발의 용이성

– 애플리케이션 프레임워크 (application framework) 제공– 멤버 함수 나열– 코드 삽입의 용이성

Page 43: Windows Programming

MFC Tutorial 43

ISLab ICE HUFSISLab ICE HUFS

HandleHandle 을 이용한 분류 을 이용한 분류 - SDK(1)- SDK(1)

RECT rc;

GetClientRect(hWnd, &rc);

MoveWinodw(hWnd, x, y, x2, y2, TRUE);

Page 44: Windows Programming

MFC Tutorial 44

ISLab ICE HUFSISLab ICE HUFS

HandleHandle 을 이용한 분류 을 이용한 분류 - MFC(1)- MFC(1)

class CWnd : public CCmdTarget{

HWND m_hWnd;...BOOL GetClientRect(LPRECT lpRect);BOOL MoveWindow(int x,int y,int width,int height,BOOL bDraw=TRUE);...

}

BOOL CWnd::GetClientRect(LPRECT lpRect) --> inline 함수를 이용하여 성능 저하를 막는다 {

::GetClientRect(m_hWnd, lpRect);}BOOL CWnd::MoveWindow(int x, int y, int width, int height, BOOL bDraw){

::MoveWindow(m_hWnd, x, y, width, height);}

Page 45: Windows Programming

MFC Tutorial 45

ISLab ICE HUFSISLab ICE HUFS

HandleHandle 을 이용한 분류 을 이용한 분류 - SDK(2)- SDK(2)

HDC hDC = GetDC(hWnd);

Rectangle(hDC, 10, 10, 100, 100);

TextOut(hDC, 10, 10, “Sample”, 6);

ReleaseDC(hWnd, hDC);

Page 46: Windows Programming

MFC Tutorial 46

ISLab ICE HUFSISLab ICE HUFS

HandleHandle 을 이용한 분류 을 이용한 분류 - MFC(2)- MFC(2)

class CDC : public CObject{

HDC m_hDC;. . . .BOOL Rectangle(int x1, int y1, int x2, int y2);BOOL TextOut(int x, int y, LPSTR lpStr, int size);

}

BOOL CDC::Rectangle(int x1, int y1, int x2, int y2){

::Rectangle(m_hDC, x1, y1, x2, y2);}BOOL CDC:: TextOut(int x, int y, LPSTR lpStr, int size){

::TextOut(m_hDC, x, y, lpStr, size);}

Page 47: Windows Programming

MFC Tutorial 47

ISLab ICE HUFSISLab ICE HUFS

SDK - SDK - 자원 획득 및 반환자원 획득 및 반환

• SDK{

HDC hDC;

hDC = GetDC(hWnd); // 자원 획득

Rectangle(hDC,10,10,100,100);

TextOut(hDC,10,10,“Sample”,6);

ReleaseDC(hWnd, hDC); // 반드시 자원을 반환해야 한다 .

}

Page 48: Windows Programming

MFC Tutorial 48

ISLab ICE HUFSISLab ICE HUFS

C++C++ 의 장점의 장점 (( 생성자생성자 // 소멸자소멸자 ) - MFC) - MFC

{ CClientDC dc(this); dc.Rectangle(10, 10, 100, 100); dc.TextOut(10,10,“Sample”,6);} // 소멸자 불림

CClientDC::CClientDC(CWnd* pWnd){ m_hWnd = pWnd->GetSafeHwnd(); // 윈도우 핸들을 얻는다 . m_hDC = ::GetDC(m_hWnd); // 윈도우의 Device Context 를 얻음}

CClientDC::~CClientDC(){ ::ReleaseDC(m_hWnd, m_hDC); // Device Context 를 해제한다 .}

Page 49: Windows Programming

MFC Tutorial 49

ISLab ICE HUFSISLab ICE HUFS

C++C++ 의 장점 의 장점 - - 부재인자부재인자

• SDKint MessageBox(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle, UNIT flag);InvalidateRect(HWND hWnd, LPCRECT lpRect, BOOL bErase);

• MFCint AfxMessageBox(LPCSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0);void InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE);

Page 50: Windows Programming

MFC Tutorial 50

ISLab ICE HUFSISLab ICE HUFS

C++C++ 의 장점 의 장점 - - 중복 정의중복 정의

• 함수 중복 정의 (function overloading)BOOL Rectangle(int x1, int y1, int x2, int y2);BOOL Rectangle(LPCRECT lpRect);

• 연산자 중복 정의 (operator overloading)CRect a, b, c;c.left = a.left + b.left; c = a + b;c.right = a.right + b.right;c.top = a.top + b.top;c.bottom = a.bottom + b.bottom;

Page 51: Windows Programming

MFC Tutorial 51

ISLab ICE HUFSISLab ICE HUFS

MFC MFC 클래스 종류클래스 종류

• 일반 목적의 클래스• 윈도우 API 클래스• 애플리케이션 프레임워크 클래스• 고 수준 추상화 클래스• 운영체제 확장 클래스

Page 52: Windows Programming

MFC Tutorial 52

ISLab ICE HUFSISLab ICE HUFS

일반 목적의 클래스일반 목적의 클래스• CObject : 모든 클래스의 상위 클래스• 예외 처리 클래스

– CException, CArchiveException, CFileException, CMemoryException, CNotSupportedException, COleException, CDBException, CResourceException, CUserException

• 콜렉션 (collection) 클래스– CByteArray, CWordArray, CDWordArray, CPtrArray, CObArray, CStringArray, CUintArray– CObList, CPtrList, CStringList– CMapPtrToWord, CMapPtrToPtr, CMapStringToOb, CMapStringToPtr, CMapStringToString, CM

apWordToOb, CMapWordToPtr• 동적 문자열 클래스

– Cstring• 파일 클래스

– CFile, CStdioFile, CMemFile• 시간 및 시간 간격 (time span) 클래스

– CTime, CTimeSpan• 그외

– CPoint, CSize, CRect 등

Page 53: Windows Programming

MFC Tutorial 53

ISLab ICE HUFSISLab ICE HUFS

윈도우 윈도우 API API 클래스 클래스 (1)(1)

• 응용 프로그램에서 사용하는 클래스– CCmdTarget, CCmdUI, CWinThread, CWinApp

• 객체 동기화 관련 클래스– CSyncObject, CCriticalSection, CSemaphore, CMutex, CEvent, CSingleLock, CMulti

Lock

• 응용 프로그램 관련 클래스– CCommandLineInfo, CWaitCursor

• 메뉴 : Cmenu

• CWnd : 모든 윈도우 클래스의 상위 클래스– 프레임 윈도우 (frame window)

• CFrameWindow, CMDIFrameWindow, CMDIChildWnd– CWnd 계승 클래스

• CDialog, 콘트롤 클래스 (CButton, CListBox, CEdit 등 )

Page 54: Windows Programming

MFC Tutorial 54

ISLab ICE HUFSISLab ICE HUFS

윈도우 윈도우 API API 클래스 클래스 (2)(2)

• 다이얼로그– CFileDialog, CColorDialog, CFontDialog, CPrintDialog, CFindReplaceDialog

• 다이얼로그 DDX/DDV– CDataExchange

• 콘트롤 클래스– CButton, CBitmapButton, CComboBox, CEdit, CStatic, CScrollBar, CListBox, CCheckListBox, CVBControl

– CAnimateCtrl, CDragListBox, CHeaderCtrl, CHotKeyCtrl, CImageList, CListCtrl, CProgressCtrl, CRichEditCtrl, CSliderCtrl, CSpinButtonCtrl, CStatusBarCtrl, CTabCtrl, CToolBarCtrl, CToolTipCtrl, CTreeCtrl

• GDI 및 그림 관련 클래스– CPaintDC, CWindowDC, CClientDC, CMetaFileDC– CGdiObject, CFont, CPen, CBrush, CBitmap, CPalette, CRgn

Page 55: Windows Programming

MFC Tutorial 55

ISLab ICE HUFSISLab ICE HUFS

애플리케이션 프레임워크 클래스애플리케이션 프레임워크 클래스

• 문서 /뷰 관련 클래스– CDocTemplate, CSingleDocTemplate, CMultiDocTemplate– CDocument, Cview

• 문맥 지원 도움말 (context-sensitive help)

Page 56: Windows Programming

MFC Tutorial 56

ISLab ICE HUFSISLab ICE HUFS

고 수준 추상화 클래스고 수준 추상화 클래스

• 확장된 뷰 (enhanced view)– CScrollView, CFormView– 콘트롤 뷰 : CEditView, CListView, CRichEditView, CTreeView

• 분리 윈도우– CSplitterWnd

• 콘트롤 바– CControlBar– CToolBar, CStatusBar, CDialogBar

Page 57: Windows Programming

MFC Tutorial 57

ISLab ICE HUFSISLab ICE HUFS

운영체제 확장 클래스 운영체제 확장 클래스 (1)(1)

• OLE 지원– OLE Document

• CDocItem, COleServerItem, COleClientItem, COleDocument, COleLinkingDoc, COleServerDoc, COleIPFrameWnd

– 클래스 팩토리 (class factories)• COleObjectFactory, COleTemplateServer

– 오토메이션 (automation)

– 통일된 데이타 전송• COleDataSource, COleDataObject, COleDropSource, COleDropTarget

– OLE 콘트롤• COleControl, COlePropertyPage, COleControlModule, COleObjectFactoryEx, COleConnecti

onPoint, CPropExchange, CFontHolder, CPictureHolder

Page 58: Windows Programming

MFC Tutorial 58

ISLab ICE HUFSISLab ICE HUFS

운영체제 지원 클래스운영체제 지원 클래스 (2)(2)

• ODBC 지원– CDatabase, CRecordset, CFiledExchange, CLongBinary, CRecordView

• DAO 지원– CDaoWorkspace, CDaoDatabase, CDaoRecordset, CDaoRecordView, CDaoQueryD

ef, CDaoTableDef, CDaoException, CDaoFiledExchange

• MAPI 지원

• Winsock 지원– CAsyncSocket, Csocket

• 펜 윈도우 지원– CHEdit, CBEdit– 제한 : 16 비트 환경

Page 59: Windows Programming

MFC Tutorial 59

ISLab ICE HUFSISLab ICE HUFS

코드 재 사용 방법코드 재 사용 방법

Component Gallery

응용프로그램

MFCCustomAppWizard

MFC 확장AppWizard

Page 60: Windows Programming

MFC Tutorial 60

ISLab ICE HUFSISLab ICE HUFS

AppWizardAppWizard 를 통한 를 통한 Project Project 생성생성 (1)(1)

• Project 생성 (project 이름 : Obedit)– New 메뉴 (MFC AppWizard (.exe)

• Database, OLE 메뉴– None

• Multiple document 선택

Page 61: Windows Programming

MFC Tutorial 61

ISLab ICE HUFSISLab ICE HUFS

AppWizardAppWizard 를 통한 를 통한 Project Project 생성생성 (2)(2)

• Advanced Options– File extension : obe File type ID: Obedit.Docum

ent– Main frame caption: Obedit– Doc type name: Obedit Filter name: Obedit Files(*.obe)

– File new name: Obedit File type name: Obedit Document

• MFC library 사용 방법– As a shared DLL (MFC42.DLL 필요 )

• Base class 선택– CObeditView 클래스의 상위 클래스로 CScrollView 선택

Page 62: Windows Programming

MFC Tutorial 62

ISLab ICE HUFSISLab ICE HUFS

Developer StudioDeveloper Studio

• Project Workspace– 클래스 뷰 (class view)– 리소스 뷰 (resource view, AppStudio 대신 )– 파일 뷰 (file view)– 인포 뷰 (info view)

• 작업 영역– source code browser / wizard bar / resource editor– online help

Page 63: Windows Programming

MFC Tutorial 63

ISLab ICE HUFSISLab ICE HUFS

클래스 뷰클래스 뷰 // 파일 뷰파일 뷰 // 리소스 뷰리소스 뷰

Page 64: Windows Programming

MFC Tutorial 64

ISLab ICE HUFSISLab ICE HUFS

클래스 뷰클래스 뷰 (class view)(class view)

• 클래스에 함수 및 멤버 추가– 클래스 이름에 마우스 커서를

위치시킨 후 오른쪽 버튼을 클릭– 멤버 함수 추가– 멤버 변수 추가

• 특정 위치로 커서 이동

• 계승 관계 표시

Page 65: Windows Programming

MFC Tutorial 65

ISLab ICE HUFSISLab ICE HUFS

파일 뷰파일 뷰 (file view)(file view)

• 프로젝트에 있는 화일들을 열거• 프로젝트에서 화일 삭제

• (.net) 솔루션 탐색기

Page 66: Windows Programming

MFC Tutorial 66

ISLab ICE HUFSISLab ICE HUFS

Hungarian Hungarian 표기법표기법Type Prefix 예 비고char c cDirSeperatorBOOL b bIsSendingint n nVariableCountUINT n nMyUnsignedIntWORD w wListIDLONG l lAxisRatioDWORD dw dwPackedmessage* (pointer) p pWndFAR * lp lpWndLPSTR lpsz lpszFileName z는 NULL 로 끝남을 handle h hWnd 의미callback lpfn lpfnHookProc 함수 포인터

Page 67: Windows Programming

MFC Tutorial 67

ISLab ICE HUFSISLab ICE HUFS

Hungarian Hungarian 표기법 표기법 - MFC - MFC 확장확장

Type Prefix 예CRect rect rectScrollCPoint pt ptMouseClickCSize sz szRectangleCString str strFindCWnd Wnd WndControlCWnd * pWnd pWndDialog

Page 68: Windows Programming

MFC Tutorial 68

ISLab ICE HUFSISLab ICE HUFS

Hungarian Hungarian 표기법 표기법 - Symbol- Symbol

Type Prefix 예 범위여러 리소스에서 공유 IDR_ IDR_MAINFRAME 1-0x6FFFDialog 리소스 IDD_ IDD_ABOUT 1-0x6FFFDialog 리소스 Help context ID HIDD_ HIDD_HELP_ABOUT 0x2001-

0x26FF(for context-sensitive help)비트맵 리소스 IDB_ IDB_SMILEY 1-0x6FFF커서 리소스 IDC_ IDC_HAND 1-0x6FFF아이콘 리소스menu, toolbar command ID_ ID_CIRCLE_TOOL 0x8000-

0xDFFFCommand help context HID_ HID_CIRCLE_TOOL 0x1800-0x1DFFMessage box prompt IDP_ IDP_FATALERROR 8-0xDFFFMessage box help contextHIDP_ HIDP_FATALERROR 0x3008-0x3DFFString 리소스 IDS_ IDS_ERROR12 1-0x7FFF다이얼로그 템플릿의 control IDC_ IDC_COMBO1 8-0xDFFF

Page 69: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 기본 구조 이해의 기본 구조 이해

Page 70: Windows Programming

MFC Tutorial 70

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 철학의 철학 (1)(1)

• 예제 프로그램 컴파일 후 수행– Open 메뉴 선택

• 화일 선택시 일반적인 절차에 대한 코딩1 화일 오픈 다이얼로그 박스를 띄운다 .2 사용자의 입력을 받아 해당 화일을 연다 . 만일 MDI 프로그램이면 자식

윈도우를 하나 연다 . SDI 프로그램이라면 전에 갖고 있던 자료 구조를 해제한다 .

3 화일을 프로그램의 정의에 맞게 해석하여 읽어들인다화일을 프로그램의 정의에 맞게 해석하여 읽어들인다 . . 즉 화일의 즉 화일의 내용을 메모리 상의 자료구조로 변환한다내용을 메모리 상의 자료구조로 변환한다 .

4 읽어들인 내용을 윈도에 그린다 . 이 부분의 구현은 대개 윈도를 무효화(invalidate) 하여 이루어진다 .

Page 71: Windows Programming

MFC Tutorial 71

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 철학의 철학 (2)(2)

• 실제 사용자가 해야 할 일 (3 번 )– 장점

• 에러의 가능성 감소• 프로그래밍 시간 및 노력 감소

Page 72: Windows Programming

MFC Tutorial 72

ISLab ICE HUFSISLab ICE HUFS

CDocumentCDocument

class CDocument : public CCmdTarget

{

...

void OnFileOpen(); // 파일오픈 명령을 실행하면 불려진다 .

BOOL GetOpenFileName(LPCTSTR); // 다이얼로그를 띄워 파일이름을 입력

// 화일 입출력을 담당하는 함수 (pure virtual function) virtual void Serialize(CFile cfile) = 0;

CWnd* GetWindow(); // 현재 문서의 내용을 보여주는 윈도우 포인터를 리턴 ...

}

Page 73: Windows Programming

MFC Tutorial 73

ISLab ICE HUFSISLab ICE HUFS

CDocument::OnFileOpenCDocument::OnFileOpen

void CDocument::OnFileOpen()

{

CString szFileName; // CString 은 문자배열에 해당하는 클래스

if (!GetOpenFileName(szFileName)) // 다이얼로그 박스를 띄워 파일이름을 return; // 입력받는다 .

CFile cfile(szFileName); // CFile 은 MFC 에서 화일 I/O 를 담당 cfile.Open(); // 화일을 오픈한다 .

Serialize(cfile); // 화일의 내용을 읽어들인다 (user 가 작성 )

cfile.Close(); // 화일을 닫는다 .

CWnd* pWnd = GetWindow(); // 이 문서의 내용을 보여주는 윈도의 핸들을 pWnd->Invalidate(NULL); // 얻어 그 내용을 그리도록 WN_PAINT 메시지 // 발생}

Page 74: Windows Programming

MFC Tutorial 74

ISLab ICE HUFSISLab ICE HUFS

CMyDocument CMyDocument 클래스클래스

// CDocument 는 실제 바로 사용하지 못함 (MFC class)

// 계승하여 사용하여야class CMyDocument : public CDocument

{

// My data structure

int m_nNumOfObjects;

Objects obj[100];

public:

void Serialize(CFile cfile); // virtual function

};

Page 75: Windows Programming

MFC Tutorial 75

ISLab ICE HUFSISLab ICE HUFS

WinMainWinMain

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

if (!hPrevInstance) // 처음으로 실행되는 경우에는 InitApplication(hInstance); // 윈도우 클래스를 등록한다 .

InitInstance(hInstance); // 메인 윈도우를 생성한다 .

while(GetMessage(....)) // 메시지 루프 {

....

DispatchMessage(...); // 메시지를 윈도우 프로시저로 나눔 }

// 프로그램이 종료되기 전에 청소 작업을 행한다 .

....

return msg.wParam;

}

Page 76: Windows Programming

MFC Tutorial 76

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 의 WinMainWinMain

• MFC\SRC\winmain.cpp

• CWinApp 클래스에 존재CWinApp::InitApplicationCWinApp::InitInstanceCWinApp::RunCWinApp::ExitInstance

• InitInstance, ExitInstance 만 override 하여 사용 가능

• 가상 함수의 중요성

Page 77: Windows Programming

MFC Tutorial 77

ISLab ICE HUFSISLab ICE HUFS

SDISDI

• CObeditApp -> CWinApp• CMainFrame -> CMDIFrameWnd• CObeditDoc -> CDocument• CObeditView -> CView

Page 78: Windows Programming

MFC Tutorial 78

ISLab ICE HUFSISLab ICE HUFS

MDIMDI

CObeditApp -> CWinAppCMainFrame -> CMDIFrameWndCChildFrame -> CMDIChildWndCObeditDoc -> CDocumentCObeditView -> CView

Page 79: Windows Programming

MFC Tutorial 79

ISLab ICE HUFSISLab ICE HUFS

Document/View Document/View 구조구조

뷰클래스뷰클래스

문서클래스문서클래스

1. 사용자의 입력을받는다

2. 그 내용을 반영한다 .

3. 윈도우로출력한다 .

Page 80: Windows Programming

MFC Tutorial 80

ISLab ICE HUFSISLab ICE HUFS

전체 구조전체 구조

• CWinApp– 하나의 응용 프로그램을 가리키는 클래스

• CDocument– 응용 프로그램의 자료구조를 저장하는 클래스

• CView– 응용 프로그램의 모습을 화면에 출력하는 클래스

• 하나의 document 에는 여러 개의 view 가 연관될 수 있음– 예 ) 탐색기 , Visual C++ 에디터 창

Page 81: Windows Programming

MFC Tutorial 81

ISLab ICE HUFSISLab ICE HUFS

CObeditApp CObeditApp 클래스클래스

class CObeditApp : public CWinApp

{

public:

CObeditApp();

//{{AFX_VIRTUAL(CObeditApp)

public:

virtual BOOL InitInstance(); // 프로그램의 초기화 //}}AFX_VIRTUAL

//{{AFX_MSG(CObeditApp)

afx_msg void OnAppAbout();

...

//}}AFX_MSG

Page 82: Windows Programming

MFC Tutorial 82

ISLab ICE HUFSISLab ICE HUFS

InitInstance InitInstance 함수함수

BOOL CObeditApp:InitInstance()

{

....

LoadStdProfileSettings(); // 표준 INI 화일 option 을 읽어들임

CMultiDocTemplate* pDocTemplate;

pDocTemplate = new CMultiDocTemplate(

IDR_OBEDITTYPE,

RUNTIME_CLASS(CObeditDoc),

RUNTIME_CLASS(CChildFrame),

RUNTIME_CLASS(CObeditView));

AddDocTemplate(pDocTemplate); // View-Doc 등록

CMainFrame* pMainFrame = new CMainFrame; // main window 생성 if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame;

Page 83: Windows Programming

MFC Tutorial 83

ISLab ICE HUFSISLab ICE HUFS

...

RegisterShellFileTypes(TRUE); // 화일의 icon, 확장자 등록

CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo);

if (!ProcessShellCommand(cmdInfo)) return FALSE;

pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow();

return TRUE;}

Page 84: Windows Programming

MFC Tutorial 84

ISLab ICE HUFSISLab ICE HUFS

Obedit.iniObedit.ini 화일화일

[Recent File List]File1=D:\obedit\step8\new.OBEFile2=D:\obedit\step7\test4.OBE

Page 85: Windows Programming

MFC Tutorial 85

ISLab ICE HUFSISLab ICE HUFS

레지스트리 작업레지스트리 작업

• INI 파일 기록 및 읽기

– UINT GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault);

– CString GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL);

– BOOL WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue);

– BOOL WriteProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue );

• 레지스트리에 읽기 및 쓰기

– void SetRegistryKey( LPCTSTR lpszRegistryKey );

– void SetRegistryKey( UINT nIDRegistryKey );

Page 86: Windows Programming

MFC Tutorial 86

ISLab ICE HUFSISLab ICE HUFS

레지스트리레지스트리

void CObeditApp::LoadStdProfileSettings()

{

// 나름대로 초기화 값을 읽어다 저장한다 .

// GetProfileInt...

//

CWinApp::LoadStdProfileSettings(); // 선조 함수 호출}

Page 87: Windows Programming

MFC Tutorial 87

ISLab ICE HUFSISLab ICE HUFS

윈도우 생성윈도우 생성

• WM_CREATE– OnCreate 함수 호출

Page 88: Windows Programming

MFC Tutorial 88

ISLab ICE HUFSISLab ICE HUFS

CMainFrame CMainFrame 클래스클래스

class CMainFrame : public CMDIFrameWnd

{

DECLARE_DYNAMIC(CMainFrame)

....

protected:

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

protected:

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT

lpCreateStruct);

//}}AFX_MSG

DECLARE_MESSAGE_MAP() // 메시지 맵};

Page 89: Windows Programming

MFC Tutorial 89

ISLab ICE HUFSISLab ICE HUFS

OnCreate OnCreate 함수함수

Page 90: Windows Programming

MFC Tutorial 90

ISLab ICE HUFSISLab ICE HUFS

MFC MDI MFC MDI 프로그램의 윈도우 구조프로그램의 윈도우 구조

타이틀파일 편집

타이틀

MDI 메인 윈도우

MDI 클라이언트윈도우MDI 자식 윈도우

뷰 윈도우

Page 91: Windows Programming

MFC Tutorial 91

ISLab ICE HUFSISLab ICE HUFS

CObeditView CObeditView 클래스클래스

class CObeditView : public CView

{

....

public:

CObeditDoc* GetDocument(); // 뷰에 연결된 문서객체의 포인터 반환

....

//{{AFX_VIRTUAL(CObeditView)

public:

virtual void OnDraw(CDC* pDC); // WM_PAINT 가 왔을 때 실행

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

//}}AFX_VIRTUAL

....

Page 92: Windows Programming

MFC Tutorial 92

ISLab ICE HUFSISLab ICE HUFS

주요 주요 CView CView 멤버함수멤버함수

GetDocument뷰와 연계된 문서 오브젝트에 대한 포인터를 돌려준다 . AddDocTemplate 함수를 통해 m_pDocument 멤버는MFC 가 뷰를 생성할 때 알아서 초기화

OnInitialUpdate 뷰가 처음 만들어질 때 호출된다 .

OnDraw 뷰와 연계된 문서오브젝트의 내용을 윈도우 위에 그려준다 .

OnPrint 뷰와 연계된 문서오브젝트의 내용을 프린터로 출력

OnUpdate 문서오브젝트의 내용이 변경되었을 때 문서오브젝트쪽에 불러준다 .

Page 93: Windows Programming

MFC Tutorial 93

ISLab ICE HUFSISLab ICE HUFS

CObeditDoc CObeditDoc 클래스클래스

class CObeditDoc : public CDocument

{

....

//{{AFX_VIRTAUL(CObeditDoc)

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar); // file I/O

//}}AFX_VIRTUAL

....

};

Page 94: Windows Programming

MFC Tutorial 94

ISLab ICE HUFSISLab ICE HUFS

주요 주요 CDocument CDocument 멤버 함수멤버 함수

IsModified 문서오브젝트의 내용이 마지막으로 저장된 후에 변경된적이 있는지 알려준다 .

SetModifiedFlag 문서오브젝트의 내용이 변경되었음을 표시했다 .

UpdateAllViews 문서오브젝트의 내용이 바뀌었을 때 이 내용을 연계된뷰에게 알려준다 . 이 안에서는 뷰클래스의 OnUpdate함수를 부른다 .

DeleteContent 문서오브텍트가 닫힐 때 불려진다 . 이 때 문서오브젝트

의 청소 작업을 해야 한다 .

OnNewDocument 사용자가 File 메뉴의 New 명령을 수행하면 불린다 .

OnOpenDocument 사용자가 File 메뉴의 Open 명령을 수행하면 불린다 .

OnSaveDocument 사용자가 File 메뉴의 Save 명령을 수행하면 불린다 .

OnCloseDocument 사용자가 File 메뉴의 Close 명령을 수행하면 불린다 .

Page 95: Windows Programming

MFC Tutorial 95

ISLab ICE HUFSISLab ICE HUFS

모든 뷰 수정모든 뷰 수정

• Document class 는 자신과 연관이 있는 view object 를 리스트의 형태로 관리– CPtrList m_viewList

• View 에서 수정

• Document 수정

• UpdateAllViews 호출

Page 96: Windows Programming

MFC Tutorial 96

ISLab ICE HUFSISLab ICE HUFS

UpdateAllViewsUpdateAllViews

View Document

GetDocument 함수로 관련문서 오브젝트를 알아낸다.그 다음 데이터를 갱신한다.

자료구조에 변화가 생긴다.이 변화를 관련된 모든 뷰에반영하기위해 UpdateAllViews함수를 호출한다.

각 뷰별로 화면을 다시 그린다.

UpdateAllViews 함수에서는OnUpdate 함수를 호출한다.

Page 97: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

UI UI 붙이기붙이기

Page 98: Windows Programming

MFC Tutorial 98

ISLab ICE HUFSISLab ICE HUFS

메뉴 작성메뉴 작성File Object View Window Help New Line Toolbar New Window

About Open Ellipse Status Bar Cascade

Time Close Rectangle Color Bar Title Save --------- ---------- Arrange Icons Save As… Pen Attribute Zoom ---------- Print Print Preview Print Setup… ---------- Send Summary Info ---------- Recent File ---------- Exit

Page 99: Windows Programming

MFC Tutorial 99

ISLab ICE HUFSISLab ICE HUFS

메뉴 리소스 작성메뉴 리소스 작성

• 리소스 뷰에서– IDR_MAINFRAME(child window 가 없을 때 ) – IDR_OBEDITTYPE

Page 100: Windows Programming

MFC Tutorial 100

ISLab ICE HUFSISLab ICE HUFS

메뉴 작성메뉴 작성&Line ID_OBJECT_LINE Draw a line\nLine&Ellipse ID_OBJECT_ELLIPSE Draw a ellipse\nEllipse&Rectangle ID_OBJECT_RECTANGLE Draw a rectangle\nRectangle

&Pen Attribute ID_OBJECT_PENATTR Change the attribute of a pen\nPen

&Color Bar ID_VIEW_COLORBAR Show or hide color palette&Zoom\tCtrl+Z ID_VIEW_ZOOM Set zoom ratio

ID_SEPARATOR( 분리자 메뉴 )

풍선 도움말

MEMU ID

단축키

Page 101: Windows Programming

MFC Tutorial 101

ISLab ICE HUFSISLab ICE HUFS

단축키 작성단축키 작성

• 리소스 뷰의 Accelerator 이용

Page 102: Windows Programming

MFC Tutorial 102

ISLab ICE HUFSISLab ICE HUFS

아이콘 변경아이콘 변경

Page 103: Windows Programming

MFC Tutorial 103

ISLab ICE HUFSISLab ICE HUFS

툴바의 수정툴바의 수정

• 리소스 뷰에서– IDR_MAINFRAME

Page 104: Windows Programming

MFC Tutorial 104

ISLab ICE HUFSISLab ICE HUFS

배율 설정배율 설정

• 새로운 ToolBar 생성

Page 105: Windows Programming

MFC Tutorial 105

ISLab ICE HUFSISLab ICE HUFS

MyToolBar.h MyToolBar.h 수정수정

Class CMyToolBar : public CToolBarCtrl -> CToolBarCToolBar 로 수정(.net 에서는 바로 선택 )

{

// Construction

public:

CMyToolBar();

// Attributes

. . . .

Page 106: Windows Programming

MFC Tutorial 106

ISLab ICE HUFSISLab ICE HUFS

MyToolBar.cpp MyToolBar.cpp 수정수정

BEGIN_MESSAGE_MAP(CMyToolBar, CToolBarCtrl) -> CToolBarCToolBar 로 수정 //{{AFX_MSG_MAP(CMyToolBar)

// NOTE - the ClassWizard will add and remove mapping ..

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

Page 107: Windows Programming

MFC Tutorial 107

ISLab ICE HUFSISLab ICE HUFS

MainFrm.h MainFrm.h 수정수정

#include “MyToolBar.h” #include “MyToolBar.h” // 추가

class CMainFrame : public CMDIFrameWnd

{

DECLARE_DYNAMIC(CMainFrame)

public:

CMainFrame();

. . . .

protected:

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar; -> CMyToolBar m_wndToolBarCMyToolBar m_wndToolBar 로 수정

Page 108: Windows Programming

MFC Tutorial 108

ISLab ICE HUFSISLab ICE HUFS

리소스 파일리소스 파일

• obedit.rc• 텍스트를 리소스 뷰에서 그래픽으로 나타냄

– 리소스 편집의 편리

Page 109: Windows Programming

MFC Tutorial 109

ISLab ICE HUFSISLab ICE HUFS

Obedit.rc Obedit.rc 수정수정

IDR_MAINFRAME TOOLBAR DISCARDABLE 16,15

BEGIN

BUTTON ID_FILE_NEW

BUTTON ID_FILE_OPEN

BUTTON ID_FILE_SAVE

SEPARATOR

BUTTON ID_OBJECT_LINE

BUTTON ID_OBJECT_ELLIPSE

BUTTON ID_OBJECT_RECTANGLE

SEPARATOR

BUTTON ID_OBJECT_PENATTR

BUTTON ID_FILE_PRINT

BUTTON ID_APP_ABOUT

SEPARATORSEPARATOR

SEPARATORSEPARATOR // 12번째 스태택바 붙일 위치 (0 부터 세어서 )

SEPARATORSEPARATOR

SEPARATORSEPARATOR // 14번째 스태틱컨트롤을 붙일 위치END

Page 110: Windows Programming

MFC Tutorial 110

ISLab ICE HUFSISLab ICE HUFS

MainFrameMainFrame 에 변수 추가에 변수 추가

• CMainFrame 에 멤버 추가– CScrollBar m_zoomScroll;– CStatic m_zoomStatic

Page 111: Windows Programming

MFC Tutorial 111

ISLab ICE HUFSISLab ICE HUFS

CMainFrame::OnCreate CMainFrame::OnCreate 수정수정

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

. . .

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar);

CRect rect;

// Scroll Bar 생성 m_wndToolBar.SetButtonInfo(12, ID_ZOOMSCROLL, TBBS_SEPARATOR, 80);

m_wndToolBar.GetItemRect(12, &rect);

rect.top = 3;

if (!m_wndToolBar.m_zoomScroll.Create(WS_VISIBLE | SBS_HORZ |

WS_TABSTOP, rect, &m_wndToolBar, ID_ZOOMSCROLL))

return -1;

80 픽셀

Resource Symbol 로 등록

Page 112: Windows Programming

MFC Tutorial 112

ISLab ICE HUFSISLab ICE HUFS

// 스태택 컨트롤 추가 m_wndToolBar.SetButtonInfo(14, ID_ZOOMSTATIC, TBBS_SEPARATOR, 60); m_wndToolBar.GetItemRect(14, &rect); rect.top = 6; if (!m_wndToolBar.m_zoomStatic.Create(“ 배율” , WS_VISIBLE | SS_LEFT |

WS_TABSTOP, rect, &m_wndToolBar, ID_ZOOMSTATIC)) return -1;

return 0;}

Resource Symbol 로 등록

Page 113: Windows Programming

MFC Tutorial 113

ISLab ICE HUFSISLab ICE HUFS

리소스 심볼 등록리소스 심볼 등록#define ID_ZOOMSCROLL 101 // 리소스 심볼을 등록하는 것과 왼쪽과 같이 // 정의하는 것은 동일한 효과임

심볼 등록

Page 114: Windows Programming

MFC Tutorial 114

ISLab ICE HUFSISLab ICE HUFS

생성된 모습생성된 모습

Page 115: Windows Programming

MFC Tutorial 115

ISLab ICE HUFSISLab ICE HUFS

CToolBar CToolBar 클래스의 주요 함수클래스의 주요 함수

CommandToIndex 버튼 ID 를 주면 툴바의 좌측부터 세어 그에 해당하는 인덱스를 준다 . 0부터 센다 .

GetItemID CommandToIndex와는 반대로 버튼의 인덱스로부터 버튼 ID 를 얻어준다 .Create 툴바를 생성한다 .EnableDocking 도커블 툴바로 동작할 수 있도록 설정하며 프로임 윈도우의 어느 곳에 붙을 수 있는지도 명시한다 .GetBarStyle 툴바의 스타일을 얻어온다 .SetBarStyle 툴바의 스타일을 설정한다 .GetButtonInfo 특정 버튼에 대한 정보를 얻어온다 .SetButtonInfo 특정 버튼의 정보를 변경한다 .GetCount 툴바 버튼의 총수를 얻어온다 (SEPARATOR 포함 ).GetItemRect 버튼 ID 를 주면 그 버튼의 툴바에서의 위치를 돌려준다 .LoadBitmap 버튼 모양을 담고 있는 비트맵을 로드한다 .SetHeight 툴바의 버튼 높이를 변경한다 .SetSizes 툴바의 크기를 변경한다 .

Page 116: Windows Programming

MFC Tutorial 116

ISLab ICE HUFSISLab ICE HUFS

상태바상태바 (Status Bar)(Status Bar)

• 생성 순서– CStatusBar 오브젝트를 만든다 .– CStatusBar 오브젝트의 Create 함수를 호출하여 상태바

윈도우를 생성– SetIndicator 함수를 호출하여 각 텍스트 출력창과 스트링 ID 를 연결시킨다 .

static UINT indicators[ ] ={ ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL,};

Page 117: Windows Programming

MFC Tutorial 117

ISLab ICE HUFSISLab ICE HUFS

클래스 위저드클래스 위저드

클래스 이름

메시지

가상함수

메뉴

이미 만든 함수들

Page 118: Windows Programming

MFC Tutorial 118

ISLab ICE HUFSISLab ICE HUFS

Pane Pane 텍스트 수정텍스트 수정

• SetWindowText 함수로 텍스트 갱신• Command UI 핸들러의 SetText 함수 호출

void CMainFrame::OnUpdateIndicatorTime(CCmdUI* pCmdUI){ pCmdUI->SetText(“Pane 에 출력” );}

• SetPaneText 함수 이용CStatusBar bar;bar.SetPaneText(0, “Pane 에 출력” );

Page 119: Windows Programming

MFC Tutorial 119

ISLab ICE HUFSISLab ICE HUFS

상태바의 수정상태바의 수정 (1)(1)

• indicators 변수 수정 (MainFrm.cpp)static UINT indicators [] ={ ID_SEPARATOR, // status line indicator ID_SEPARATOR, // 추가 ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL,};

Page 120: Windows Programming

MFC Tutorial 120

ISLab ICE HUFSISLab ICE HUFS

상태바의 수정상태바의 수정 (2)(2)• CMainFrame 클래스의 OnCreate 함수 수정

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){ ... DockControlBar(&m_wndToolBar); m_wndStatusBar.SetPaneInfo(1,ID_INDICATOR_TIME,SBPS_NORMAL,60); return 0;}

– 1 은 상태바의 두 번째 창을 가리킨다 .– 폭은 오른쪽부터 계산– Resource Symbol 을 이용하여 ID_INDICATOR_TIME 등록

Page 121: Windows Programming

MFC Tutorial 121

ISLab ICE HUFSISLab ICE HUFS

시간 출력시간 출력

• 클래스 위저드를 이용하여 명령 UI 갱신핸들러 생성– View 메뉴의 ClassWizard 선택

• Object IDs: ID_INDICATOR TIME• Messages: UPDATE_COMMAND_UI

– 함수 생성 (OnUpdateIndicatorTime)void CMainFrame::OnUpdateIndicatorTime(CCmdUI* pCmdUI){ char timebuf[12]; _strtime(timebuf); pCmdUI->SetText(timebuf);}

• 이벤트 발생시 마다 매번 함수 호출

Page 122: Windows Programming

MFC Tutorial 122

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 주요 전역 함수의 주요 전역 함수AfxGetApp 프로그램을 대표하는 프로그램 오브젝트에 대한

포인터를 돌려준다 .AfxGetAppName 프로그램의 이름을 돌려준다 .AfxGetInstanceHandle 프로그램의 인스턴스 핸들을 돌려준다 .AfxGetMainWnd 메인 프레임 윈도우 오브젝트에 대한 포인터를

돌려준다 .GetCurrentMessage 현재 처리 중인 메시지에 대한 메시지 스트럭처를

돌려준다 . 메시지 핸들러 등에서 메시지 스트럭처를 직접 접근하고 싶을 때 이용한다 .

AfxSocketInit 윈도우 소켓을 초기화하기 위해 부른다 .AfxBeginThread 새로운 스레드를 시작한다 .AfxEndThread 현재의 스레드를 끝낸다 .AfxGetThread 현재 실행 중인 스레드에 대한 포인터

(CWinThread) 를 돌려준다 .

Page 123: Windows Programming

MFC Tutorial 123

ISLab ICE HUFSISLab ICE HUFS

컬러 바 클래스 생성컬러 바 클래스 생성

• 클래스 위저드에서 새로운 클래스 생성– Add Class/New 에서 CMyColorBar 클래스 생성– 상위 클래스로 CToolBarCtrl 을 선택– MyColorBar.cpp, MyColorBar.h 에서 CToolBarCtrl 을 CToolBar 로

수정– 정확한 색 선택 : Image 메뉴의 Adjust Colors... 선택 후 숫자로

색 입력

Page 124: Windows Programming

MFC Tutorial 124

ISLab ICE HUFSISLab ICE HUFS

툴바 리소스 생성툴바 리소스 생성

• 리소스 뷰에서 새로운 Toolbar 생성– 버튼의 자료구조 (MyColorBar.cpp 에 정의 )

COLORREF color[16] ={ RGB( 0, 0, 0), RGB(255,255,255), RGB(192,192,192), RGB(128,128,128), RGB(255, 0, 0), RGB(255,255, 0), RGB( 0,255, 0), RGB( 0,255,255), RGB( 0, 0,255), RGB(255, 0,255), RGB(128, 0, 0), RGB(128,128, 0), RGB( 0,128, 0), RGB( 0,128,128), RGB( 0, 0,128), RGB(128, 0,128)};

Page 125: Windows Programming

MFC Tutorial 125

ISLab ICE HUFSISLab ICE HUFS

색깔 선택색깔 선택

• Image 메뉴– Adjust Colors...

Page 126: Windows Programming

MFC Tutorial 126

ISLab ICE HUFSISLab ICE HUFS

ColorBar ColorBar 생성생성

#include “MyColorBar.h”

class CMainFrame : public CMDIFrameWnd{ DECLARE_DYNAMIC(CMainFrame) ...protected: CToolBar m_wndToolBar; CMyColorBar m_wndColorBar; ...};

Page 127: Windows Programming

MFC Tutorial 127

ISLab ICE HUFSISLab ICE HUFS

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

....

m_wndStatusBar.SetPaneInfo(1,ID_INDICATOR_TIME,SBPS_NORMAL,60);

if (!m_wndColorBar.Create(this,WS_CHILD | WS_VISIBLE |

CBRS_SIZE_FIXED | CBRS_LEFT | CBRS_FLYBY, ID_COLORBAR) ||

!m_wndColorBar.LoadToolBar(IDR_MYCOLORBAR))

{

return FALSE;

}

m_wndColorBar.SetColumns(2);

m_wndColorBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);

DockControlBar(&m_wndColorBar);

return 0;}

Page 128: Windows Programming

MFC Tutorial 128

ISLab ICE HUFSISLab ICE HUFS

void CMyColorBar::SetColumns(UINT nColumn)

{

int nCount = GetToolBarCtrl().GetButtonCount();

for(int i = 0; i < nCount; i++)

{

UINT nStyle = GetButtonStyle(i);

BOOL bWrap = (((i+1) % nColumn) == 0);

if (bWrap)

nStyle |= TBBS_WRAPPED;

else

nStyle &= ~TBBS_WRAPPED;

SetButtonStyle(i, nStyle);

}

Invalidate();

GetParentFrmae()->RecalcLayout();

}

Page 129: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

도형 처리 추가도형 처리 추가

Page 130: Windows Programming

MFC Tutorial 130

ISLab ICE HUFSISLab ICE HUFS

사용자 클래스 디자인사용자 클래스 디자인

CDrawObjectCDrawObject

CLineCLine CEllipseCEllipse CRectangleCRectangle

Page 131: Windows Programming

MFC Tutorial 131

ISLab ICE HUFSISLab ICE HUFS

사용자 클래스사용자 클래스class CDrawObject : public CObject{protected: CDrawObject(WORD objType, COLORREF crColor, int nPenStyle, int nPenWidth);public: COLORREF m_crColor; // 이 도형의 색상 int m_nPenStyle; // 도형 둘레를 긋는 선의 스타일 . PS_SOLID, // PS_DOT,PS_DASH,PS_DASHDOT,PS_DASHDOTDOT // 등의 값이 가능하다 . int m_nPenWidth; // 도형 둘레를 긋는 선의 폭 int m_rcRect; // 도형의 위치를 나타낸다 .public: WORD m_wObjType; // 이 오브젝트의 타입을 가리킨다 . 이 타입을 가리키는 // 값은 밑에 있는 enum ObjectType 의 objectLine, // objectRectangle, objectEllipse 중의 하나가 // 될 수 있다 .

Page 132: Windows Programming

MFC Tutorial 132

ISLab ICE HUFSISLab ICE HUFS

enum ObjectType { objectLine, objectEllipse, objectRectangle };

virtual ~CDrawObject();

virtual void DrawObject(CDC *pDC) = 0; // pure virtual function

virtual void SetStartPoint(CPoint pt) {m_rcRdct.TopLeft() = pt;}

virtual void SetEndPoint(CPoint pt) {m_rcRect.BottomRight()=pt;}

virtual CPoint& GetStartPoint() { return m_rcRect.TopLeft(); }

virtual CPoint& GetEndPoint() { return m_rcRect.BottomRight(); }

virtual void GetBoundingRect(CRect *pRect);

virtual void Serialize(CArchive& ar);

#ifdef _DEBUG

virtual void AssertValid() const; // 유효성 여부 검사 virtual void Dump(CDumpContext& dc) const; // 객체의 내용을 디버그 // 윈도우로#endif

};

Page 133: Windows Programming

MFC Tutorial 133

ISLab ICE HUFSISLab ICE HUFS

class CLine : public CDrawObject

{

protected:

DECLARE_SERIAL(CLine)

public:

CLine();

CLine(COLORREF crColor, int nPenStyle, int nPenWidth);

virtual ~CLine();

virtual void DrawObject(CDC *pDC);

virtual void Serialize(CArchive& ar);

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

};

Page 134: Windows Programming

MFC Tutorial 134

ISLab ICE HUFSISLab ICE HUFS

class CEllipse : public CDrawObject

{

protected:

DECLARE_SERIAL(CEllipse)

public:

CEllipse();

CEllipse(COLORREF crColor, int nPenStyle, int nPenWidth);

virtual ~CEllipse();

virtual void DrawObject(CDC* pDC);

virtual void Serialize(CAarchive& ar);

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

};

Page 135: Windows Programming

MFC Tutorial 135

ISLab ICE HUFSISLab ICE HUFS

class CRectangle : public CDrawObject

{

protected:

DECLARE_SERIAL(CRectangle)

public:

CRectangle();

CRectangle(COLORREF crColor, int nPenStyle, int nPenWidth);

virtual ~CEllipse();

virtual void DrawObject(CDC* pDC);

virtual void Serialize(CAarchive& ar);

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

};

Page 136: Windows Programming

MFC Tutorial 136

ISLab ICE HUFSISLab ICE HUFS

#include “stdafx.h”#include “DrawObj.h”

CDrawObject::CDrawObject(WORD objType, COLORREF crColor, int nPenStyle, int nPenWidth)

: m_wObjType(objType), m_crColor(crColor), m_nPenStyle(nPenStyle), m_nPenWidth(nPenWidth)

{ m_rcRect.SetRectEmpty();}

CDrawObject::~CDrawObject(){}

void CDrawObject::GetBoundingRect(CRect* pRect){ pRect->left = min(m_rcRect.left, m_rcRect.right); pRect->right = max(m_rcRect.left, m_rcRect.right); pRect->top = min(m_rcRect.top, m_rcRect.bottom); pRect->bottom = max(m_rcRect.top, m_rcRect.bottom); pRect->InflateRect(m_nPenWidth, m_nPenWidth);

}

Page 137: Windows Programming

MFC Tutorial 137

ISLab ICE HUFSISLab ICE HUFS

void CDrawObject::Serialize(CArchive& ar){ if (ar.IsStoring()) { } else { }}

#ifdef _DEBUGvoid CDrawObject::AssertValid() const{ CObject::AssertValid();}

void CDrawObject::Dump(CDumpContext& dc) const{ CObject::Dump(dc);}#endif

Page 138: Windows Programming

MFC Tutorial 138

ISLab ICE HUFSISLab ICE HUFS

IMPLEMENT_SERIAL(CLine, CObject, 1)

CLine::CLine(): CDrawObject(objectLine, RGB(0,0,0), PS_SOLID, 1){ }

CLine::CLine(COLORREF crColor, int nPenStyle, int nPenWidth): CDrawObject(objectLine, crColor, nPenStyle, nPenWidth){ }

CLine::~CLine(){ }

void CLine::DrawObject(CDC* pDC){ CPen pen, *ppenOld; pen.CreatePen(m_nPenStyle, m_nPenWidth, m_crColor); ppenOld = pDC->SelectObject(&pen); pDC->MoveTo(m_rcRect.TopLeft()); pDC->LineTo(m_rcRect.BottomRight()); pDC->SelectObject(ppenOld);}

Page 139: Windows Programming

MFC Tutorial 139

ISLab ICE HUFSISLab ICE HUFS

void CLine::Serialize(CArchive& ar){ CDrawObject::Serialize(ar); if (ar.IsStoring()) { } else { }}

#ifdef _DEBUGvoid CLine::AssertValid() const{ CDrawObject::AssertValid();}

void CLine::Dump(CDumpContext& dc) const{ CDrawObject::Dump(dc);}#endif

Page 140: Windows Programming

MFC Tutorial 140

ISLab ICE HUFSISLab ICE HUFS

IMPLEMENT_SERIAL(CEllipse, CObject, 1)

CEllipse::CEllipse() : CDrawObject(objectEllipse,RGB(0,0,0),PS_SOLID,1){ }

CEllipse::CEllipse(COLORREF crColor, int nPenStyle, int nPenWidth) : CDrawObject(objectEllipse, crColor, nPenStyle, nPenWidth){ }

void CEllipse::DrawObject(CDC* pDC){ CBrush br, *pbrOld; CPen pen, *ppenOld; br.CreateSolidBrush(m_crColor); pen.CreatePen(m_nPenStyle, m_nPenWidth, m_crColor); pbrOld = pDC->SelectObject(&br); ppenOld = pDC->SelectObject(&pen); pDC->Ellipse(&m_rcRect); pDC->SelectObject(pbrOld); pDC->SelectObject(ppenOld);}

Page 141: Windows Programming

MFC Tutorial 141

ISLab ICE HUFSISLab ICE HUFS

CEllipse::~CEllipse(){ }

void CEllipse::Serialize(CArchive& ar){ CDrawObject::Serialize(ar); if (ar.IsStoring()) { } else { }}

#ifdef _DEBUGvoid CEllipse::AssertValid() const{ CDrawObject::AssertValid();}

void CEllipse::Dump(CDumpContext& dc) const{ CDrawObject::Dump(dc);}#endif

Page 142: Windows Programming

MFC Tutorial 142

ISLab ICE HUFSISLab ICE HUFS

IMPLEMENT_SERIAL(CRectangle, CObject, 1)

CRectangle::CRectangle(): CDrawObject(objectRectangle,RGB(0,0,0),PS_SOLD,1){ }

CRectangle::CRectangle(COLORREF crColor,int nPenStyle,int nPenWidth): CDrawObject(objectEllipse, crColor, nPenStyle, nPenWidth){ }

void CRectangle::DrawObject(CDC* pDC){ CBrush br, *pbrOld; CPen pen, *ppenOld; br.CreateSolidBrush(m_crColor); pen.CreatePen(m_nPenStyle, m_nPenWidth, m_crColor); pbrOld = pDC->SelectObject(&br); ppenOld = pDC->SelectObject(&pen); pDC->Rectangle(&m_rcRect); pDC->SelectObject(pbrOld); pDC->SelectObject(ppenOld);}

Page 143: Windows Programming

MFC Tutorial 143

ISLab ICE HUFSISLab ICE HUFS

CRectangle::~CRectangle(){ }

void CRectangle::Serialize(CArchive& ar){ CDrawObject::Serialize(ar); if (ar.IsStoring()) { } else { }}

#ifdef _DEBUGvoid CRectangle::AssertValid() const{ CDrawObject::AssertValid();}

void CRectangle::Dump(CDumpContext& dc) const{ CDrawObject::Dump(dc);}#endif

Page 144: Windows Programming

MFC Tutorial 144

ISLab ICE HUFSISLab ICE HUFS

윈도우 운영체제에서의 출력윈도우 운영체제에서의 출력

GDI (Graphic Device Interface)GDI (Graphic Device Interface)

디바이스 드라이버디바이스 드라이버

실제 출력 장치실제 출력 장치

WIN32 API

응용 프로그램응용 프로그램

Page 145: Windows Programming

MFC Tutorial 145

ISLab ICE HUFSISLab ICE HUFS

DirectXDirectX

• 윈도우 3.1 의 그래픽 출력 속도 저하 극복을 위해– 게임 (WinG)

• DirectDraw– DirectX 의 그래픽 부분 라이브러리

• DirectPlay– 네트워크 게임을 만드는데 사용할 수 있는 라이브러리

• DirectSound– 사운드 기능을 제공해 주는 라이브러리

• DirectInput– 조이스틱 등의 제어에 사용할 수 있는 라이브러리

Page 146: Windows Programming

MFC Tutorial 146

ISLab ICE HUFSISLab ICE HUFS

디바이스 컨텍스트디바이스 컨텍스트

• Device Context• 윈도우 운영체제에서 출력 대상을 지칭하는 것• 논리적으로 볼 때 붓 , 펜 , 팔레트 , 종이 (비트맵 ), 폰트 등의 그림을 그리기 위한 도구의 집합

• 장치와 문관하게 GDI 함수 호출 가능• 붓과 펜은 DC 내에 하나씩 존재• GetDC & ReleaseDC

Page 147: Windows Programming

MFC Tutorial 147

ISLab ICE HUFSISLab ICE HUFS

DCDC 의 종류의 종류

• CClientDC– 윈도우의 클라이언트 영역

• CWindowDC– 윈도우 전체 디바이스 컨텍스트– 윈도우의 경계선 , 캡션 영역 등에도 그리기 가능

• CPaintDC– WM_PAINT 발생시에 사용

Page 148: Windows Programming

MFC Tutorial 148

ISLab ICE HUFSISLab ICE HUFS

윈도우 운영체제에서의 출력 절차윈도우 운영체제에서의 출력 절차

출력할 장치의 디바이스 컨텍스트의 핸들을 얻는다 .출력할 장치의 디바이스 컨텍스트의 핸들을 얻는다 .

GDI 로 앞에서 얻은 핸들에 출력을 행한다 .GDI 로 앞에서 얻은 핸들에 출력을 행한다 .

디바이스 컨텍스트를 제거한다 .디바이스 컨텍스트를 제거한다 .

Page 149: Windows Programming

MFC Tutorial 149

ISLab ICE HUFSISLab ICE HUFS

SDKSDK 에서의 붓과 펜의 변경 절차에서의 붓과 펜의 변경 절차1. 펜이나 붓을 생성한다 (CreatePen, CreateSolidBrush).1. 펜이나 붓을 생성한다 (CreatePen, CreateSolidBrush).

2. 디바이스 컨텍스트를 얻는다 (GetDC 나 BeginPaint).2. 디바이스 컨텍스트를 얻는다 (GetDC 나 BeginPaint).

3. 2 에서 얻은 디바이스 149 컨텍스트의 드로잉 툴을 1 에서 만든 드로잉 툴로 바꾼다 (SelectObject). 교체하면서 원래 들어있던 펜이나 붓을 기억해야 .

3. 2 에서 얻은 디바이스 149 컨텍스트의 드로잉 툴을 1 에서 만든 드로잉 툴로 바꾼다 (SelectObject). 교체하면서 원래 들어있던 펜이나 붓을 기억해야 .

4. GDI 를 이용해 출력 작업을 수행한다 .4. GDI 를 이용해 출력 작업을 수행한다 .

5. 3 에서 기억해 놓았던 원래의 붓이나 펜을 원상복구 시킨다 (SelectObject).5. 3 에서 기억해 놓았던 원래의 붓이나 펜을 원상복구 시킨다 (SelectObject).

6. 디바이스 컨텍스트를 윈도우 운영체제로 반환한다 .6. 디바이스 컨텍스트를 윈도우 운영체제로 반환한다 .

7. 1 에서 만든 펜이나 붓을 삭제한다 (DeleteObject).7. 1 에서 만든 펜이나 붓을 삭제한다 (DeleteObject).

Page 150: Windows Programming

MFC Tutorial 150

ISLab ICE HUFSISLab ICE HUFS

CDC CDC 클래스의 주요 함수클래스의 주요 함수 (1)(1)

CreateCompatibleDC 인자로 주어진 DC 와 같은 속성을 갖는 DC 를메모리에 만든다 .

GetSafeHdc 현재 오브젝트가 둘러싸고 있는 디바이스 컨텍스트핸들을 돌려준다 .

IsPrinting 프린트 DC 인지 아닌지의 여부를 돌려준다 .SetROP2 그리기모드를 변경하는데 사용된다 .SetBkColor 글자출력 시의 배경색을 지정한다 .SetTextColor 글자출력 시의 글자색을 지정한다 .MoveTo, LineTo 직선을 긋는데 사용한다 .Arc, ArcTo 원호를 그리는데 사용한다 .PolyDraw 직선과 베지어 스프라인을 연속적으로 그림PloyLine 직선을 연속적으로 그리는데 사용Polygon 직선을 연속적으로 그리는데 처은 점과 마지막

점을 잇는다

Page 151: Windows Programming

MFC Tutorial 151

ISLab ICE HUFSISLab ICE HUFS

CDC CDC 클래스의 주요 함수클래스의 주요 함수 (2)(2)

PolyBezier 베이어 스프라인을 연속적으로 그리는데 사용InvertRect 주어진 영역을 반전하는데 사용한다 .DrawIcon 주어진 위치에 주어진 아이콘을 그려준다 .Draw3dRect 입체적인 사각형을 그리는데 사용한다 .Ellipse 타원 ( 원 포함 ) 을 그리는데 사용한다 .Pie 부채꼴을 그리는데 사용한다 .Rectangle 사각형을 그리는데 사용한다 .RountRect 모서리가 둥근 사각형을 그리는데 사용한다 .SetPixel 점을 찍는데 사용한다 .BitBlt 한 디바이스 컨텍스트의 내용을 다른 디바이스 컨텍스트로

복사한다 .TextOut 주어진 위치에 텍스트를 출력한다 .DrawText 주어진 사각형 내에 텍스트를 출력한다 .

Page 152: Windows Programming

MFC Tutorial 152

ISLab ICE HUFSISLab ICE HUFS

View View 클래스 변경클래스 변경 (1)(1)

#include “DrawObj.h”

class CObeditView : public CScrollView

{

....

// Attributes

public:

CObeditDoc* GetDocument();

int m_nSelectedColorID; // 현재 컬러 팔레트에서 선택된 버튼의 인덱스 COLORREF m_crCurColor; // 컬러 팔레트에서 선택된 버튼에 해당하는 RGB 값 int m_nPenStyle; // 현재 선택된 펜 스타일 int m_nPenWidth; // 현재 선택된 펜의 굵기 CDrawObject* m_pCurDrawObject; // 현재 만들어지고 있는 도형 WORD m_wCurDrawObject; // 현재 선택된 도형이 무엇인지 나타낸다 .

....

};

Page 153: Windows Programming

MFC Tutorial 153

ISLab ICE HUFSISLab ICE HUFS

View View 클래스 변경클래스 변경 (2)(2)

extern COLORREF color[16];

CObeditView::CObeditView()

{

m_nSelectedColorID = 0; // 디폴트로 선택되는 컬러 팔레트의 버튼은 첫번째 m_crCurColor = color[m_nSelectedColorID]; // 첫번째 버튼에 해당하는 색 m_nPenStyle = PS_SOLID; // 펜의 초기 스타일 m_nPenWidth = 1;

m_pCurDrawObject = NULL;

m_wCurDrawObject = CDrawObject::objectLine;

}

Page 154: Windows Programming

MFC Tutorial 154

ISLab ICE HUFSISLab ICE HUFS

메뉴 선택 코드 추가메뉴 선택 코드 추가

• 클래스 위저를 통한 메뉴 함수 구현

Page 155: Windows Programming

MFC Tutorial 155

ISLab ICE HUFSISLab ICE HUFS

메뉴 선택 함수메뉴 선택 함수

void CObeditView::OnObjectLine()

{

m_wCurDrawObject = CDrawObject::objectLine;

}

void CObeditView::OnObjectRectangle()

{

m_wCurDrawObject = CDrawObject::objectRectangle;

}

void CObeditView::OnObjectEllipse()

{

m_wCurDrawObject = CDrawObject::objectEllipse;

}

Page 156: Windows Programming

MFC Tutorial 156

ISLab ICE HUFSISLab ICE HUFS

메뉴의 메뉴의 UPDATE_COMMAND_UIUPDATE_COMMAND_UI

void CObeditView::OnUpdateObjectLine(CCmdUI* pCmdUI)

{

pCmdUI->SetCheck(m_wCurDrawObject == CDrawObject::objectLine);

}

void CObeditView::OnUpdateObjectRectangle(CCmdUI* pCmdUI)

{

pCmdUI->SetCheck(m_wCurDrawObject == rawObject::objectRectangle);

}

void CObeditView::OnUpdateObjectRectangle(CCmdUI* pCmdUI)

{

pCmdUI->SetCheck(m_wCurDrawObject == DrawObject::objectRectangle);

}

Page 157: Windows Programming

MFC Tutorial 157

ISLab ICE HUFSISLab ICE HUFS

칼라 메뉴칼라 메뉴void CObeditView::OnPalettecolor1() // // 컬러 팔레트 메뉴 함수컬러 팔레트 메뉴 함수 . 16. 16번 반복번 반복{ m_nSelectedColorID = 0; m_crCurColor = color[0];}

void CObeditView::OnUpdatecolor1(CCmdIO* pCmdUI){ pCmdUI->SetCheck(m_nSelectedColorID == 0);}

Page 158: Windows Programming

MFC Tutorial 158

ISLab ICE HUFSISLab ICE HUFS

Message MapMessage Map

• 기존 윈도우 프로시저를 대신BEGIN_MESSAGE_MAP(CObeditView, CScrollView) //{{AFX_MSG_MAP(CObeditView) ON_COMMAND(ID_OBJECT_ELIIPSE, OnObjectEllipse) ON_UPDATE_COMMAND_UI(ID_OBJECT_ELLIPSE, OnUpdateObjectEllise) ON_COMMAND(ID_OBJECT_LINE, OnObjectLine) ON_UPDATE_COMMAND_UI(ID_OBJECT_LINE, OnUpdateObjectLine) ON_COMMAND(ID_OBJECT_RECTANGLE, OnObjectRectangle) ON_UPDATE_COMMAND_UI(ID_OBJECT_RECTANGLE, OnUpdateObjectRectangle) //}}AFX_MSG_MAP //Standard printing commands ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)END_MESSAGE_MAP()

Page 159: Windows Programming

MFC Tutorial 159

ISLab ICE HUFSISLab ICE HUFS

윈도우의 입력 메시지 종류윈도우의 입력 메시지 종류• 하드웨어적인 이유로 발생하는 메시지

– 키보드– 마우스– 타이머

• 키보드 메시지나 마우스 메시지를 해석하여 발생하는 메시지– 캐릭터– 스크롤 바– 메뉴

Page 160: Windows Programming

MFC Tutorial 160

ISLab ICE HUFSISLab ICE HUFS

키보드 입력 메시지키보드 입력 메시지• 종류

– WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP

• 가상 키 코드 (virtual keycode) - lParam비트 0 - 15 키의 반복 횟수비트 16 - 23 키의 스캔 코드

( 키보드 제조업체에 따라 다를 수 있다 )비트 24 확장 키 여부 (1 : 확장키 , 0 : 아님 )비트 25 - 26 쓰이지 않음비트 27 - 28 윈도우 운영체제가 내부적으로 사용비트 29 컨텍스트 코드 (1 : Alt 키가 눌림 , 0 : 안 눌림 )비트 30 키의 이전 상태 (1 : 키가 눌려져 있었음 , 0 : 아님 )비트 31 키의 현재 전환 상태

(1 : 키가 떼어지는 것 , 0 : 눌려지는 것 )

Page 161: Windows Programming

MFC Tutorial 161

ISLab ICE HUFSISLab ICE HUFS

문자 입력 메시지문자 입력 메시지

• 종류– WM_CHAR, WM_SYSCHAR

• 메시지 발생 순서– 아스키 코드가 있을 때 (SDK 에서는 TranslateMessage 함수가 반드시 불려야WM_KEYDOWN --> WM_CHAR --> WM_KEYUP

– 아스키 코드가 없을 때 (예 : ENTER)WM_KEYDOWN --> WM_KEYUP

• 인자– wParam : 아스키 코드– lParam : WM_KEYDOWN, WM_KEYUP 에서와 같음

Page 162: Windows Programming

MFC Tutorial 162

ISLab ICE HUFSISLab ICE HUFS

마우스 메시지의 처리마우스 메시지의 처리

• 마우스 이벤트의 종류– WM_LBUTTONDBLCLK– WM_LBUTTONDOWN– WM_LBUTTONUP– WM_MOUSEMOVE– WM_RBUTTONDBLCLK– WM_RBUTTONDOWN– WM_RBUTTONUP

• 넘어오는 좌표 : Pixel 단위

Page 163: Windows Programming

MFC Tutorial 163

ISLab ICE HUFSISLab ICE HUFS

마우스 메시지와 윈도우마우스 메시지와 윈도우

1

2

t1

t2t3

t1 에서 t2 사이에는 1 번 윈도우로마우스 메시지가 발생하고 ,t2 와 t3 사이에는 2 번 윈도우로메시지가 발생한다 .

마우스 커서의 이동 자취

Page 164: Windows Programming

MFC Tutorial 164

ISLab ICE HUFSISLab ICE HUFS

드래그시의 문제점드래그시의 문제점

1. 드래그 시작

2. 윈도우 바깥으로 나가면 마우스 메시지가 이 윈도우에게로 발생하지 않는다 .

• SetCapture, ReleaseCapture

Page 165: Windows Programming

MFC Tutorial 165

ISLab ICE HUFSISLab ICE HUFS

타이머 입력 메시지타이머 입력 메시지

• 종류– WM_TIMER

• 주기적으로 하고 싶은 일이 있을 때 사용되는 메시지– 예 ) 워드프로세서에서 주기 저장 , 테트리스 게임에서 적당 시간 간격으로 블록을 떨어뜨릴 때

• SetTimer, KillTimer

Page 166: Windows Programming

MFC Tutorial 166

ISLab ICE HUFSISLab ICE HUFS

타이머 설정타이머 설정

• CMainFrame 클래스의 OnCreate 함수에서 설정int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){ ... DockControlBar(&m_wndToolBar); m_wndStatusBar.SetPaneInfo(1,ID_INDICATOR_TIME,SBPS_NORMAL,60);

SetTimer(1, 1000, NULL); return 0;}

Page 167: Windows Programming

MFC Tutorial 167

ISLab ICE HUFSISLab ICE HUFS

WM_TIMER WM_TIMER 메시지 처리 함수메시지 처리 함수void CMainFrame::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default char timebuf[12]; _strtime(timebuf); m_wndStatusBar.SetPaneText(1, timebuf, TRUE); CMDIFrameWnd::OnTimer(nIDEvent);}

• CMainFrame 이 아닌 다른 클래스에서 불릴때void f(){ ... ((CMainFrame*)AfxGetMainWnd())->UpdateTime(); // 다른 클래스에서 ...}

Page 168: Windows Programming

MFC Tutorial 168

ISLab ICE HUFSISLab ICE HUFS

타이머 해제타이머 해제void CMainFrame::f(){ ... SetTimer(1, 1000, NULL); SetTimer(2, 10000, lpFuction); ...}

void CMainFrame::g(){ ... KillTimer(1); KillTimer(2); ...}

void lpFunction(HWND hWnd, UINT, UINT, DWORD){ ...}

Page 169: Windows Programming

MFC Tutorial 169

ISLab ICE HUFSISLab ICE HUFS

타이머 사용시 주의점타이머 사용시 주의점

• PC 타이머 칩이 발생시키는 최소 시간 간격 : 55 밀리초• 메시지 큐에서 약간의 지연 발생• WM_TIMER 메시지 처리가 늦어지면 메시지가 쌓여 큐가 넘칠 수 있으므로 메시지 큐에서는 하나의 WM_TIMER 만 가능 (WM_PAINT 도 마찬가지 )

Page 170: Windows Programming

MFC Tutorial 170

ISLab ICE HUFSISLab ICE HUFS

스크롤 바 입력 메시지스크롤 바 입력 메시지

• 종류– WM_VSCROLL, WM_HSCROLL

SB_PAGEUP SB_PAGEDOWN

SB_LINEUP SB_LINEDOWN

Page 171: Windows Programming

MFC Tutorial 171

ISLab ICE HUFSISLab ICE HUFS

메뉴 입력 메시지메뉴 입력 메시지

• 종류– WM_COMMAND, WM_SYSCOMMAND

• 단축키 사용 가능• ASCII vs. VIRTKEY

Page 172: Windows Programming

MFC Tutorial 172

ISLab ICE HUFSISLab ICE HUFS

LButtonDownLButtonDown

void CObeditView::OnLButtonDown(UINT nFlags, CPoint point){ switch(m_wCurDrawObject) // 객체 생성 { case CDrawObject::objectLine : m_pCurDrawObject = new CLine(m_crCurColor, m_nPenStyle, m_nPenWidth); break; case CDrawObject::objectRectangle : m_pCurDrawObject = new CRectangle(m_crCurColor,m_nPenStyle,m_nPenWidth); break; case CDrawObject::objectEllipse : m_pCurDrawObject = new CEllipse(m_crCurColor, m_nPenStyle, m_nPenWidth); break; }

m_pCurDrawObject->SetStartPoint(point); // 객체의 시작위치 저장 m_pCurDrawObject->SetEndPoint(point);

SetCaptureSetCapture(); // 모든 마우스 메시지가 CObeditView 객체로 온다 . // 마우스 메시지 독점 . 마우스 드래그를 지원하기 위해} // ReleaseCapture 호출 때까지

Page 173: Windows Programming

MFC Tutorial 173

ISLab ICE HUFSISLab ICE HUFS

MouseMoveMouseMove

void CObeditView::OnMouseMove(UINT nFlags, CPoint point){ if (GetCapture() GetCapture() == this) // 드래그 중인지 판단 { CClientDC dc(this);

dc.SetROP2(R2_NOTXORPEN); // XOR 모드로 그림을 그린다 . m_pCurDrawObject->DrawObject(&dc); // 이전에 그려졌던 도형을 지운다 m_pCurDrawObject->SetEndPoint(point); // 새로운 도형의 위치 저장 m_pCurDrawObject->DrawObject(&dc); // 새로운 위치에 도형을 그린다 . // virtual function }}

Page 174: Windows Programming

MFC Tutorial 174

ISLab ICE HUFSISLab ICE HUFS

LButtonUpLButtonUp

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point){ if (GetCapture() == this) { CClientDC dc(this);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCaptureReleaseCapture(); // 마우스 독점 해제 }}

Page 175: Windows Programming

MFC Tutorial 175

ISLab ICE HUFSISLab ICE HUFS

윈도우에서의 화면 복구윈도우에서의 화면 복구

1

2 2 2

1 1

1 번 윈도우에 의해 가려졌던 2 번 윈도우가 클릭된다 .

가려졌던 영역이 일단WM_ERASEBKGND메시지에 의해 지워진다 .

WM_PAINT 메시지에의해 가려졌던 영역이복구된다 .

Page 176: Windows Programming

MFC Tutorial 176

ISLab ICE HUFSISLab ICE HUFS

WM_PAINTWM_PAINT

• 화면을 복구하는데 사용– 윈도우로 출력하는데 사용되는 메시지가 아니다 .

• 윈도우가 처음 생성될 때도 한번 발생• 새로 그려야 할 영역 고려

Page 177: Windows Programming

MFC Tutorial 177

ISLab ICE HUFSISLab ICE HUFS

WM_PAINT - SDKWM_PAINT - SDK

• SDK 에서– 반드시 BeginPaint / EndPaint 함수를 이용하여야 한다 .– 그려야 할 영역을 PAINTSTRUCT 인자로 알 수 있기 때문

HDC hDC;PAINTSTRUCT ps;

hDC = BeginPaint(hWnd, &ps);

// ps.rcPaint 에 복구 영역의 좌표가 들어있다 .// 이 부분만 딱 그려줄 수 있다면 가장 이상적이다 .

EndPaint(hWnd, &ps);

Page 178: Windows Programming

MFC Tutorial 178

ISLab ICE HUFSISLab ICE HUFS

WM_PAINTWM_PAINT

• OnDraw 함수 호출

void CView::OnPaint()

{

CPaintDC dc(this);

OnPrepareDC(&dc);

OnDraw(&dc);

}

Page 179: Windows Programming

MFC Tutorial 179

ISLab ICE HUFSISLab ICE HUFS

자료 구조 유지자료 구조 유지

• 다시 그리기 위한 자료 구조 유지

class CObeditDoc : public CDocument

{

....

// Attributes

public:

CObList m_objectListCObList m_objectList;

....

}

Page 180: Windows Programming

MFC Tutorial 180

ISLab ICE HUFSISLab ICE HUFS

LButtonUp LButtonUp 수정수정

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point){ if (GetCapture() == this) { CClientDC dc(this);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCapture(); // 마우스 독점 해제

CObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_objectList.AddTail(m_pCurDrawObject); }}

Page 181: Windows Programming

MFC Tutorial 181

ISLab ICE HUFSISLab ICE HUFS

OnDrawOnDraw

void CObeditView::OnDraw(CDC* pDC){ ObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

CRect rectClip, rectObject; pDC->GetClipBoxGetClipBox(&rectClip); // 복구해야할 영역

POSITION pos = pDoc->m_objectList.GetHeadPosition(); while( pos != NULL ) { CDrawObject* pObject = (CDrawObject*) pDoc->m_objectList.GetNext(pos); pObject->GetBoundingRect(&rectObject); // 복구해야할 영역과 겹치는 부분만 다시 그림

if (!rectObject.IntersectRectIntersectRect(&rectObject, &rectClip)) continue; pObject->DrawObject(pDC); }}

Page 182: Windows Programming

MFC Tutorial 182

ISLab ICE HUFSISLab ICE HUFS

SDK/MFCSDK/MFC 에서의 메시지 처리에서의 메시지 처리LONG __export FAR PASCALMainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_CREATE : OnCreate(); break; case WM_PAINT : OnPaint(); break; case WM_DESTROY : OnDestroy(); break; default : DefWindowProc(); } return OL;}

BEGIN_MESSAGE_MAP(CMyWnd, CWnd)

ON_WM_CREATE()

ON_WM_PAINT()

ON_WM_DESTROY()

END_MESSAGE_MAP()

AFX_MSGMAP_ENTRY _messageEntries[]=

{

{ WM_CREATE, OnCreate },

{ WM_PAINT, OnPaint },

{ WM_DESTROY, OnDestroy }

};

Page 183: Windows Programming

MFC Tutorial 183

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 에서의 메시지 처리에서의 메시지 처리 (1)(1)

• CMainFrame

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)

ON_WM_CREATE()

END_MESSAGE_MAP()

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

// 상위 클래스의 OnCreate 부터 부른 다음 작업 수행 if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)

return -1;

if (!m_wndToolBar.Create(this) ||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

....

Page 184: Windows Programming

MFC Tutorial 184

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 에서의 메시지 처리에서의 메시지 처리 (2)(2)

• CWnd

_AFXWIN_INLINE afx_msg int CWnd::OnCreate(LPCREATESTRUCT)

{

return (int)Default(); // DefWindowProc() 을 부름}

– 대부분의 메시지는 거의 모두 Default() 를 부름

Page 185: Windows Programming

MFC Tutorial 185

ISLab ICE HUFSISLab ICE HUFS

명령 경로 배정명령 경로 배정 (command routing)(command routing)

• WM_COMMAND, WM_UPDATE_COMMAND_UI– CCmdTarget 로부터 계승받은 클래스만 받을 수 있다 .

• 메뉴 처리– CWnd 가 아닌 CDocument, CView 에서 처리하는 것이 자연스러움

• 예 ) 화일 저장 , 색 선택

Page 186: Windows Programming

MFC Tutorial 186

ISLab ICE HUFSISLab ICE HUFS

CCmdTarget CCmdTarget 클래스클래스

CObject

CCmdTarget

CWinApp CDocTemplate CWnd CDocument

CMultiDocTemplate CSingleDocTemplate CFrameWnd CView CDialog

Page 187: Windows Programming

MFC Tutorial 187

ISLab ICE HUFSISLab ICE HUFS

Routing Routing 순서순서Comand 를 받은 오브젝트 routing 순서

프레임 윈도우 1. 활성화된 자식윈도우 혹은 뷰 2. 자기 자신

3. CWinApp 오브젝트

뷰 (View) 1. 자기 자신2. 자신과 연관된 문서오브젝트

문서 (Document) 1. 자기 자신2. 이 문서가 속한 문서템플릿

다이얼로그 1. 자기 자신2. 이 다이얼로그를 소유한 윈도우

오브젝트3. CWinApp 오브젝트

Page 188: Windows Programming

MFC Tutorial 188

ISLab ICE HUFSISLab ICE HUFS

CCmdUICCmdUI 의 멤버 함수의 멤버 함수

멤버함수 이름 기능

Enable 메뉴 항목의 상태를 활성화시키거나 그레이

상태로만든다 .

SetCheck 메뉴 항목의 옆에 체크 표시를 만든다 . 툴바 버튼의경우에는 눌려진 상태로 표시한다 .

SetRadio 기능 자체는 SetCheck 와 같은데 체크 표시

대신에 표시를 사용한다 .

SetText 메뉴 항목의 텍스트를 변경한다 . 툴바 버튼에대해서는 별 의미가 없다 .

Page 189: Windows Programming

MFC Tutorial 189

ISLab ICE HUFSISLab ICE HUFS

메시지 맵 매크로메시지 맵 매크로 (1)(1)

• 기존의 윈도우 메시지– WM_XXXX, ON_WM_XXXX, OnXxxxx

• 예 ) WM_CHAR, ON_WM_CHAR, OnChar– WM_COMMAND, WM_UPDATE_COMMAND_UI 메시지는 예외

• 함수의 이름을 사용자가 정할 수 있음 , void 처리함수이름 (void);

• 사용자 정의 메시지– WM_USER에서 0x7FFF 사이의 값– ON_MESSAGE– LONG 처리함수 이름 (DWORD, LONG);

Page 190: Windows Programming

MFC Tutorial 190

ISLab ICE HUFSISLab ICE HUFS

등록된 메시지등록된 메시지 (2)(2)

• 등록된 메시지– RegisterWindowMessage 함수를 이용해 메시지 값을 만든 경우– ON_REGISTERED_MESSAGE, 함수의 인자는 사용 자 정의

메시지와 동일

• 콘트롤로부터의 알림 (notification) 메시지– ON_CONTROL(알림코드 , 컨트롤 ID, 처리함수 이름 )– void 처리함수이름 (void);

Page 191: Windows Programming

MFC Tutorial 191

ISLab ICE HUFSISLab ICE HUFS

사용자 정의 메시지사용자 정의 메시지

• 종류– WM_USER(0x7fff) 부터

• 메시지 전달 방법– SendMessage

• 메시지를 발생시켜 해당 윈도우에서 그 메시지의 처리가 끝난 다음에야 리턴

– PostMessage• 메시지를 해당 윈도우가 소속된 메시지 큐에 집어넣고 바로 리턴

– 메시지 부가 인자로 다량의 데이타를 보낼 때는 사용자 데이타 타입을 WPARAM이나 LPARAM로 캐스팅해서 보낸다 .

Page 192: Windows Programming

MFC Tutorial 192

ISLab ICE HUFSISLab ICE HUFS

사용자 정의 메시지 예사용자 정의 메시지 예#define WM_MYMESSAGE (WM_USER + 1)

SendMessage(hTargetWnd, WM_MYMESSAGE, 0, (LPARAM)lpStr);

BEGIN_MESSAGE_MAP(...)

WM_MESSAGE(WM_MYMESSAGE, OnMyMessage)

END_MESSAGE()

void CMyWin::OnMyMessage(WPARAM wParam, LPARAM lParam)

{

lpData = (LPSTR)lParam;

...

}

Page 193: Windows Programming

MFC Tutorial 193

ISLab ICE HUFSISLab ICE HUFS

메시지맵 매크로메시지맵 매크로

• 종류– ON_COMMAND_RANGE– ON_COMMAND_EX– ON_UPDATE_COMMAND_UI_RANGE– ON_CONTROL_RANGE

Page 194: Windows Programming

MFC Tutorial 194

ISLab ICE HUFSISLab ICE HUFS

Message Map MacroMessage Map Macro 의 예의 예

• CObeditView.cpp

BEGIN_MESSAGE_MAP(CObeditView, CScrollView)

//{{AFX_MSG_MAP(CObeditView)

....

//}}AFX_MSG_MAP

// Standard printing commands

....

ON_COMMAND_RANGE(ID_PALETTECOLOR1, ID_PALETTECOLOR16,

OnColorPalette)

ON_UPDATE_COMMAND_UI_RANGE(ID_PALETTECOLOR1, ID_PALETTECOLOR16,

OnUpdateColorPalette)

END_MESSAGE_MAP()

Page 195: Windows Programming

MFC Tutorial 195

ISLab ICE HUFSISLab ICE HUFS

class CObeditView : public CScrollView{ ....protected: //{{AFX_MSG(CObeditView) .... //}}AFX_MSG afx_msg void OnColorPalette(UINT nID); afx_msg void OnUpdateColorPalette(CCmdUI* pCmdUI); DECLARE_MESSAGE_MAP()};

void CObeditView::OnColorPalette(UINT nID){ m_nSelectedColorID = nID; m_crCurColor = color[nID - (UINT)ID_PALETTECOLOR1];}

void CObeditView::OnUpdateColorPalette(CCmdUI* pCmdUI){ pCmdUI->SetCheck(pCmdUI->m_nID == (UINT)m_nSelectedColorID);}

Page 196: Windows Programming

MFC Tutorial 196

ISLab ICE HUFSISLab ICE HUFS

void CMainFrame::OnViewColorbar()

{

if (m_wndColorBar.GetStyle() & WS_VISIBLE)

m_wndColorBar.ShowWindow(SH_HIDE);

else

m_wndColorBar.ShowWindow(SH_SHOW);

RecalcLayoutRecalcLayout();

void CMainFrame::OnUpdateViewColorbar(CCmdUI* pCmdUI)

{

pCmdUI->SetCheck(m_wndColorBar.GetStyle() & WS_VISIBLE);

}

Page 197: Windows Programming

MFC Tutorial 197

ISLab ICE HUFSISLab ICE HUFS

GDI GDI 객체객체

• GDI 객체 종류– CBitmap, CBrush, CFont, CPalette, Cpen, CRgn

• GDI 존속기간– GetSafeHdc 함수 이용

void A::f(){ CFont* pOldFont = pDC->SelectObject(m_pPrintFont); m_hOldFont = (HFONT) pOldFont->GetSafeHandle();}

void A::g(){ if (m_hOldFont) pDC->SelectObject(CFont::FromHandle(m_hOldFont));}

Page 198: Windows Programming

MFC Tutorial 198

ISLab ICE HUFSISLab ICE HUFS

폰트 설정폰트 설정void CTestView::ShowFont(CDC* pDC, int& nPos, int nPoints)

{

TEXTMETRIC tm;

CFont fontText;

CString strText;

CSize sizeText;

fontText.CreateFont(-nPoint*20, 0, 0, 0, 400, FALSE, FALSE, 0,

ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, “Arial”);

CFont* pOldFont = (CFont*)pDC->SelectObject(&fontText);

pDC->GetTextMetrics(&tm);

strText.Format(“This is %d-point Arial”, nPoints);

sizeText = pDC->GetTextExtent(strText);

pDC->TextOut(0, nPos, strText);

pDC->SelectObject(pOldFont);

nPos -= tm.tmHeight + tm.tmExternalLeading;

}

Page 199: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

스크롤 기능스크롤 기능

Page 200: Windows Programming

MFC Tutorial 200

ISLab ICE HUFSISLab ICE HUFS

목차목차

• 매핑 모드• 좌표계• 스크롤 기능• 스크롤 바• 논리 물리 좌표간 변환

Page 201: Windows Programming

MFC Tutorial 201

ISLab ICE HUFSISLab ICE HUFS

Mapping ModeMapping Mode

• 매핑 모드 (mapping mode)– 윈도우 출력함수 (GDI) 에서 출력좌표를 해석하는 방법– 디바이스 컨텍스트 (device context) 마다 존재– 디폴트 매핑 모드는 MM_TEXT

• MM_TEXT– 출력 원점이 윈도우 클라이언트 영역의 좌측 상단– 출력 원점에서 X 좌표는 오른쪽으로 증가 , Y 좌표는 아래 방향으로 증가

– 단위 : 픽셀 (pixel)– 단점 : 해상도에 따라 출력되는 내용의 크기가 달라진다 .

• 예 ) 프린트

Page 202: Windows Programming

MFC Tutorial 202

ISLab ICE HUFSISLab ICE HUFS

Mapping ModeMapping Mode 의 종류의 종류

매핑모드 단위 X 방향증가 Y 방향증가MM_TEXT 픽셀 오른쪽 아래쪽MM_LOMETRIC 0.1 mm 오른쪽 위쪽MM_HIMETRIC 0.01 mm 오른쪽 위쪽MM_LOENGLISH 0.1 in 오른쪽 위쪽MM_HIENGLISH 0.01 in 오른쪽 위쪽MM_TWIPS 1/1440 in 오른쪽 위쪽MM_ISOTROPIC 지정가능 지정가능 지정가능MM_ANISOTROPIC 지정가능 지정가능 지정가능

– MM_ISOTROPIC, MM_ANISOTROPIC 을 이용하여 화면 확대 / 축소 가능

Page 203: Windows Programming

MFC Tutorial 203

ISLab ICE HUFSISLab ICE HUFS

MM_TWIPSMM_TWIPS

• 프린터에 가장 많이 사용• 1 twip 은 1/20 포인트에 해당 (1 포인트는 1/72

인치에 해당 )• 예 : 12 포인트 문자

– 12 X 20 = 240 트윕

Page 204: Windows Programming

MFC Tutorial 204

ISLab ICE HUFSISLab ICE HUFS

매핑 모드의 변경매핑 모드의 변경

• CDC 클래스의 SetMapMode 함수 이용CClientDC dc(this);dc.SetMapMode(MM_LOMETRIC);dc.TextOut(100, 500, “ 테스트중입니다 .-1”);dc.TextOut(100, -500, “ 테스트중입니다 .-2”);

테스트중입니다 .-1

테스트중입니다 .-2

500

500

100

윈도우 밖으로 출력되어 보이지 않는다 .

Page 205: Windows Programming

MFC Tutorial 205

ISLab ICE HUFSISLab ICE HUFS

좌표계좌표계

• 디바이스 (device) 좌표– 실제 출력 장치의 좌표

• 논리 (logical) 좌표– 출력함수에 사용하는 좌표

• 디바이스 좌표와 논리 좌표간의 변환이 필요– DPtoLP– LPtoDP

Page 206: Windows Programming

MFC Tutorial 206

ISLab ICE HUFSISLab ICE HUFS

좌표계의 원점 이동좌표계의 원점 이동

• SetWindowOrg– 논리 좌표의 원점 이동

• SetViewportOrg– 디바이스 좌표의 원점 이동

Page 207: Windows Programming

MFC Tutorial 207

ISLab ICE HUFSISLab ICE HUFS

CClientDC dc(this);

dc.SetMapMode(MM_LOMETRIC);

dc.MoveTo(0,0);dc.LineTo(100, -100);

1 cm

1 cm

(0,0)

Page 208: Windows Programming

MFC Tutorial 208

ISLab ICE HUFSISLab ICE HUFS

CClientDC dc(this);

dc.SetMapMode(MM_LOMETRIC);dc.SetViewportOrg(100,100); // 디바이스 좌표의 원점 이동

dc.MoveTo(0,0);dc.LineTo(100,-100);

1 cm

1 cm

(0,0)

(100,100)

Page 209: Windows Programming

MFC Tutorial 209

ISLab ICE HUFSISLab ICE HUFS

CClientDC dc(this);

dc.SetMapMode(MM_LOMETRIC);dc.SetWindowOrg(100,100); // 윈도우 좌표의 원점 이동

dc.MoveTo(0,0);dc.LineTo(100,-100);

1 cm

1 cm

(0,0)

1 cm

1 cm

변경된 원점

Page 210: Windows Programming

MFC Tutorial 210

ISLab ICE HUFSISLab ICE HUFS

좌표계 사이의 좌표 변환좌표계 사이의 좌표 변환

• DPtoLP– 디바이스 좌표를 현재 사용중인 매핑모드에 맞춰 논리 좌표로

변환

• LPtoDP– 논리 좌표를 현재 사용중인 매핑모드에 맞춰 디바이스 좌표로

변환– 예 ) 마우스 커서의 위치를 논리 좌표로 변환하는 경우

• 마우스 좌표는 디바이스 좌표와 동일한 특성을 갖는다 . 즉 윈도우 클라이언트 영역의 좌측 상단을 기준으로 픽셀 단위의 좌표가 넘어온다 .

Page 211: Windows Programming

MFC Tutorial 211

ISLab ICE HUFSISLab ICE HUFS

단위 길이 계산단위 길이 계산

• SetWindowExt / GetWindowExt• SetViewportExt / GetViewportExt

Page 212: Windows Programming

MFC Tutorial 212

ISLab ICE HUFSISLab ICE HUFS

CScrollViewCScrollView 를 이용한 스크롤 기능를 이용한 스크롤 기능

• 스크롤에 관계된 작업이 CScrollView 에 이미 구현• 편집 문서의 크기 결정

– 스크롤 영역 설정의 기능

void CObeditView::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

CSize sizeTotal;

// TODO: calculate the total size of this view

sizeTotal.cx = sizeTotal.cy = 100;

SetScrollSizes(MM_TEXT, sizeTotal);

}

Page 213: Windows Programming

MFC Tutorial 213

ISLab ICE HUFSISLab ICE HUFS

SetScrollSizeSetScrollSize

• OnInitialUpdate 함수– 뷰 오브젝트가 생성된 뒤에 바로 호출되는 함수

• SetScrollSize– void CScrollView::SetScrollSize(int nMapMode, SIZE sizeTotal, const SIZE& sizePage, const SIZE& sizeLine);

– 편집 문서의 크기 , 매핑모드 , 스크롤 작업의 크기를 알림– 스크롤 작업의 크기

• 스크롤 바를 눌렀을 때 얼마나 스크롤할 것인지 그 양을 말함• 실행 중에 매핑모드에 변경이 생기면 그때마다 SetScrollSize 를

호출하여 변경사항을 반드시 반영해야 함– sizePage : PageDown 을 눌렀을 때 . 디폴트 값 = 문서 크기의 1

/10– sizeLine : 스크롤 라인 . 디폴트 값 = 문서 크기의 1/100

Page 214: Windows Programming

MFC Tutorial 214

ISLab ICE HUFSISLab ICE HUFS

문서 크기의 지정문서 크기의 지정class CObeditDoc : public CDocument{ ....public: CObList m_objectList; CSize m_sizeDoc; // 문서의 크기 CSize GetDocumentSize() { return m_sizeDoc; }; ....}

CObeditDoc::CObeditDoc(){ m_sizeDoc = CSize(500, 500);}

void CObeditView::OnInitialUpdate(){ CScrollView::OnInitialUpdate(); SetScrollSizes(MM_TEXT, GetDocument()->GetDocumentsSize());}

Page 215: Windows Programming

MFC Tutorial 215

ISLab ICE HUFSISLab ICE HUFS

스크롤 바스크롤 바

• 문서 영역• 엄지 (thumb)

– 현재 뷰가 보여주고 있는 부분이 편집문서에서 어디에 위치한 것인가

– 현재 보이는 부분이 전체적으로 볼 때 어느 정도의 부분을 차지하는지

• 비례 스크롤바 (proportional scrollbar)

Page 216: Windows Programming

MFC Tutorial 216

ISLab ICE HUFSISLab ICE HUFS

출력 원점의 보정출력 원점의 보정

• 스크롤이 일어나면 편집 문서와 출력함수의 원점이 달라짐– SetViewportOrg, SetWindowOrg 을 이용하여 두 원점을 하나로 만듬– 즉 CDC 클래스의 출력함수에서 사용하는 출력원점을 편집 문서의

원점으로 이동시킴– 항상 편집 문서의 원점을 바탕으로 한 좌표를 사용하도록 하면 좌표의

변환없이 문서의 좌표를 그대로 출력에 이용할 수 있음

• 이와 같은 일을 CScrollView 가 알아서 한다 .

Page 217: Windows Programming

MFC Tutorial 217

ISLab ICE HUFSISLab ICE HUFS

편집문서

윈도우

100

100

500

500300

300

Page 218: Windows Programming

MFC Tutorial 218

ISLab ICE HUFSISLab ICE HUFS

마우스 좌표와 논리 좌표의 충돌마우스 좌표와 논리 좌표의 충돌

전체문서

마우스가 넘겨주는 좌표

편집문서의 좌표

Page 219: Windows Programming

MFC Tutorial 219

ISLab ICE HUFSISLab ICE HUFS

LButtonDownLButtonDown

void CObeditView::OnLButtonDown(UINT nFlags, CPoint point){ CClientDC dc(NULL); OnPrepareDC(&dc); // 오브젝트의 매핑 모드와 원점을 현재의 스크롤 상태에 // 맞게 변환 // 즉 1. 매핑 모드 변환 // 2. 스크롤 바의 엄지 값을 읽어 그만큼 출력 장치의 // 원점을 뒤로 이동 dc.DPtoLP(&point); // 좌표 단위의 변환 및 원점의 위치까지 고려하여 좌표 // 좌표 변환 수행 // 즉 , 마우스 좌표를 편집 문서의 원점으로부터의 // 좌표로 변환

switch(m_wCurDrawObject) { case CDrawObject::objectLine : ..........}

Page 220: Windows Programming

MFC Tutorial 220

ISLab ICE HUFSISLab ICE HUFS

MouseMoveMouseMove

void CObeditView::OnMouseMove(UINT nFlags, CPoint point){ if (GetCapture() == this) { CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point);

dc.SetROP2(R2_NOTXORPEN); m_pCurDrawObject->DrawObject(&dcdc); m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dcdc);}

Page 221: Windows Programming

MFC Tutorial 221

ISLab ICE HUFSISLab ICE HUFS

LButtonUpLButtonUp

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point){ if (GetCapture() == this) { CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCapture(); CObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_objectList.AddTail(m_pCurDrawObject);}

Page 222: Windows Programming

MFC Tutorial 222

ISLab ICE HUFSISLab ICE HUFS

ViewView 의 화면 출력 과정의 화면 출력 과정

• OnDraw 에서 OnPrepareDC 를 불러야 하나 ?• WM_PAINT 처리 시 OnPaint 호출

void CView::OnPaint()

{

CPaintDC dc(this);

OnPrepareDC(&dc);

OnDraw(&dc);

}

– 화면 출력 과정을 분리– OnDraw 는 순수 가상 함수 (pure virtual function) 이다 . 그러므로 반드시 하위 클래스에서 작성해야 한다 .

– OnPrepareDC 는 가상 함수 (virtual function)– virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo=NULL);

Page 223: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

화면 확대화면 확대 // 축소 기능축소 기능

Page 224: Windows Programming

MFC Tutorial 224

ISLab ICE HUFSISLab ICE HUFS

목차목차

• 익스텐트 (extent) 란 ?• 배율 설정• 다이얼로그 만들기• DDX/DDV• SDK 와의 비교

Page 225: Windows Programming

MFC Tutorial 225

ISLab ICE HUFSISLab ICE HUFS

익스텐트익스텐트 (extent)(extent) 란란

• 특정 매핑 모드에서의 단위 길이– MM_ISOTROPIC– MM_ANISOTROPIC

• 현재 논리 좌표와 디바이스 좌표의 단위 길이를 구하거나 새로 설정 가능

• 논리 좌표와 디바이스 좌표는 단위 길이가 다를 수 있다 . • 익스텐트 (extent) 조절GetWindowExt 논리 좌표의 단위 길이 구함GetViewportExt 디바이스 좌표의 단위 길이 구함SetWindowExt 논리 좌표의 단위 길이 설정SetViewportExt 디바이스 좌표의 단위 길이 설정

Page 226: Windows Programming

MFC Tutorial 226

ISLab ICE HUFSISLab ICE HUFS

간단한 배율 설정 방법간단한 배율 설정 방법

• 배율 : N%CClientDC dc(this); dc.MoveTo(100, 100); dc.LineTo(300, 400);

CClientDC dc(this);dc.MoveTo((int)(float)100*N/100, (int)(float)100*N/100);dc.LineTo((int)(float)300*N/100, (int)(float)400*N/100);

• 단점– 실수 연산 시 발생할 수 있는 값의 오차 문제– 코드의 복잡도 증가

Page 227: Windows Programming

MFC Tutorial 227

ISLab ICE HUFSISLab ICE HUFS

익스텐트 조절을 통한 배율익스텐트 조절을 통한 배율

• 디바이스좌표 = 논리좌표 X ED / EL– ED : 디바이스 좌표의 단위 길이– EL : 논리 좌표의 단위 길이

CClientDC dc(this);

dc.SetViewportExt(N, N);dc.SetWindowExt(100, 100); // 좌표 X N / 100

dc.MoveTo(100, 100);dc.LineTo(300, 400);

Page 228: Windows Programming

MFC Tutorial 228

ISLab ICE HUFSISLab ICE HUFS

View View 수정수정

• CObeditView 클래스에 멤버 변수로 배율 추가

class CObeditView : public CScrollView{ .... UINT m_zoomRatio; ....};

CObeditView::CObeditView(){ m_nSelectedColorID = 0; m_crCurColor = color[m_nSelectedColorID]; .... m_zoomRation = 100; // 초기값으로 100% 설정}

Page 229: Windows Programming

MFC Tutorial 229

ISLab ICE HUFSISLab ICE HUFS

OnPrepareDC OnPrepareDC 함수 수정함수 수정

• 클래스 바나 위저드를 이용하여 OnPrepareDC 함수 삽입

void CObeditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo){ CScrollView::OnPrepareDC(pDC, pInfo);

pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportExt(m_zoomRatio, m_zoomRatio); pDC->SetWindowExt(100, 100);}

• 익스텐트의 값을 음수로 주면 그림의 방향이 반대가 된다 .

Page 230: Windows Programming

MFC Tutorial 230

ISLab ICE HUFSISLab ICE HUFS

다이얼로그 박스 만들기다이얼로그 박스 만들기

• 리소스 뷰에서 새로운 다이얼로그 추가

IDD_ZOOMDLG

IDC_SPINZOOMIDC_EDITZOOM

Spin Control 의 Properties

Page 231: Windows Programming

MFC Tutorial 231

ISLab ICE HUFSISLab ICE HUFS

다이얼로그 클래스 생성다이얼로그 클래스 생성

• 클래스 위저드 이용

Page 232: Windows Programming

MFC Tutorial 232

ISLab ICE HUFSISLab ICE HUFS

DDX/DDVDDX/DDV

Page 233: Windows Programming

MFC Tutorial 233

ISLab ICE HUFSISLab ICE HUFS

데이타 맵데이타 맵

class CZoomDlg : public CDialog{ ...... // Dialog Data //{{AFX_DATA(CZoomDlg) enum { IDD = IDD_ZOOMDLG }; CSpinButtonCtrl m_spinZoom; UINT m_editZoom; //}}AFX_DATA ......};

Page 234: Windows Programming

MFC Tutorial 234

ISLab ICE HUFSISLab ICE HUFS

DoDataExchangeDoDataExchange

void CZoomDlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CZoomDlg) DDX_Control(pDX, IDC_SPINZOOM, m_spinZoom); DDX_Text(pDX, IDC_EDITZOOM, m_editZoom); DDX_MinMaxUInt(pDX, m_editZoom, 10, 800); //}}AFX_DATA_MAP}

CDialog 클래스의데이타맵에 있는 변수

다이얼로그박스호출전에 값을 설정

다이얼로그박스의실행이 정상적으로끝나면 값을읽어온다 .

OnInitDialog 에서 컨트롤의 값을 설정한다 .

OnOK 에서 컨트롤의 값을 읽어온다 .

Page 235: Windows Programming

MFC Tutorial 235

ISLab ICE HUFSISLab ICE HUFS

UpdateDataUpdateData

• UpdateData 함수를 이용하여 DoDataExchange 함수 호출– 인자

• TRUE : 컨트롤의 값을 데이타맵의 변수로 읽어옴• FALSE : 데이타맵의 변수 값을 컨트롤로 설정

Page 236: Windows Programming

MFC Tutorial 236

ISLab ICE HUFSISLab ICE HUFS

OnInitDialogOnInitDialog

• WM_INITDIALOG– 클래스 위저드에서 선택

BOOL CZoomDlg::OnInitDialog(){ CDialog::OnInitDialog();

m_spinZoom.SetBuddy(GetDlgItem(IDC_EDITZOOM); m_spinZoom.SetRange(10, 500); m_spinZoom.SetBase(10); m_spinZoom.SetPos(m_editZoom);

return TRUE;}

Page 237: Windows Programming

MFC Tutorial 237

ISLab ICE HUFSISLab ICE HUFS

CSpinButtonCtrlCSpinButtonCtrl

SetBuddy 스핀 콘트롤이 증감시킨 값을 표시할 윈도우를 지정이런 윈도우를 버디 (buddy) 윈도우라고 함GetDlgItem 함수를 이용하여 콘트롤 객체의 포인터를

구함

SetRange 스핀 콘트롤로 입력할 수 있는 최대값 , 최소값을 지정

SetBase 스핀 콘트롤이 버디 윈도우에 값을 출력할 때 그 값의 형식16 이면 16 진수 , 10이면 십진수

SetPos 스핀 콘트롤에 표시할 값을 지정

Page 238: Windows Programming

MFC Tutorial 238

ISLab ICE HUFSISLab ICE HUFS

OnOKOnOK

• 클래스 위저드를 이용하여 함수 생성 가능• UpdateData 호출을 해야 한다 .

– 생성시 UpdateDate(TRUE) 를 OK 버튼이 눌려지면 UpdateData(FALSE) 를 호출하여야 하나 이것은 모두 상위 클래스인 CDialog 에 만들어져 있으므로 하위 클래스에서 생성하지 않아도 된다 .

Page 239: Windows Programming

MFC Tutorial 239

ISLab ICE HUFSISLab ICE HUFS

배율 메뉴 추가배율 메뉴 추가

• 메뉴 ID_VIEW_ZOOM를 처리하는 함수 추가 (CObeditView.cpp)#include “stdafx.h”#include “Obedit.h”...#include “ZoomDlg.h”

void CObeditView::OnViewZoom(){ CZoomDlg zoomDlg(this);

zoomDlg.m_editZoom = m_zoomRatio; if (zoomDlg.DoModal() != IDOK) return; m_zoomRatio = zoomDlg.m_editZoom; SetZoomFactor(zoomDlg.m_editZoom); Invalidate();}

Page 240: Windows Programming

MFC Tutorial 240

ISLab ICE HUFSISLab ICE HUFS

SetZoomFactorSetZoomFactor

void CObeditView::SetZoomFactor(UINT zoomFactor){ m_zoomRatio = zoomFactor; CClientDC dc(this);

OnPrepareDC(&dc); CSize size = GetDocument()->GetDocumentSize();

dc.LPtoDP(&size); SetScrollSize(MM_TEXT, size);}

Page 241: Windows Programming

MFC Tutorial 241

ISLab ICE HUFSISLab ICE HUFS

Dialog Dialog 생성 방법생성 방법

• 모든 다이얼로그는 CDialog 로 부터 계승• 생성 방법

– Resource view 에서 dialog template 생성– Class Wizard 호출

• Control 로부터의 노티피케이션 (notification) 메시지 처리• 각각의 다이얼로그 박스 컨트롤에서 입력되는 값 저장 및 컨트롤에서의 값을 읽어 오는 데이터 멤버도 만듦 (DDX)

• 데이타 값의 범위 지정 가능 (DDV)

Page 242: Windows Programming

MFC Tutorial 242

ISLab ICE HUFSISLab ICE HUFS

Modal/ModelessModal/Modeless

• Modal– DoModal 함수 호출

• Modeless– Create 함수 호출– Dialog box를 resource view 에서 그릴 때 dialog box의

프로퍼티로 VISIBLE을 반드시 주어야 한다 .

Page 243: Windows Programming

MFC Tutorial 243

ISLab ICE HUFSISLab ICE HUFS

SDKSDK 에서의 다이얼로그 생성 방법에서의 다이얼로그 생성 방법

IDC_NUMBER

IDOK

IDCANCEL

IDD_TESTDIALOG

Page 244: Windows Programming

MFC Tutorial 244

ISLab ICE HUFSISLab ICE HUFS

class CTestDialog : public CDialog{// Constructionpublic: CTestDialog(CWnd* pParent = NULL);// Dialog Data //{{AFX_DATA(CTestDialog) enum { IDD = IDD_TESTDIALOG }; //}}AFX_DATA

WORD m_wInputVal;// Overrides //{{AFX_VIRTUAL(CTestDialog)protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementationprotected: //{{AFX_MSG(CTestDialog) //}}AFX_MSG DECLARE_MESSAGE_MAP()};

Page 245: Windows Programming

MFC Tutorial 245

ISLab ICE HUFSISLab ICE HUFS

GetDlgItem - GetDlgItem - 값 설정값 설정

BOOL CTestDialog::OnInitDialog(){ CDialog::OnInitDialog(); // UpdateDate(FALSE) 호출 CString szStr;

szStr.Format(“%d”, m_wInputVal); ((CEdit*)GetDlgItem(IDC_NUMBER))->SetWindowText(szStr); ((CEdit*)GetDlgItem(IDC_NUMBER))->SetFocus(); return FALSE;}

• 반드시 cast 연산자 사용• SetFocus : 윈도우에 입력 포커스 설정

Page 246: Windows Programming

MFC Tutorial 246

ISLab ICE HUFSISLab ICE HUFS

GetDlgItem - GetDlgItem - 값 읽기값 읽기

void CTestDialog::OnOK(){ CString szStr;

((CEdit*)GetDlgItem(IDC_NUMBER))->GetWindowText(szStr); m_wInputVal = atoi(szStr); CDialog::OnOK(); // UpdateData(TRUE) 호출 // EndDialog(IDOK) 호출}

Page 247: Windows Programming

MFC Tutorial 247

ISLab ICE HUFSISLab ICE HUFS

SDK Dialog SDK Dialog 사용시사용시{ . . .

CTestDialog testDlg(this);

testDlg.m_wInputVal = nVal; if (testDlg.DoModal() == IDOK) { nVal = testDlg.m_wInputVal; }}

Page 248: Windows Programming

MFC Tutorial 248

ISLab ICE HUFSISLab ICE HUFS

Modeless DialogModeless Dialog

• 지역 변수로 생성하면 않된다 .

CTestDialog::CTestDialog(CWnd* pParent) : CDialog(CTestDialog::IDD, pParent){ Create(CTestDialog::IDD, pParent); // modeless dialog 생성}

void CObeditView::f(){ CTestDialog testDlg(this); // 지역변수로 만들면 lifetime 이 끝나면서} // 사라진다 .

void CObeditView::g(){ CTestDialog* pDlg = new CTestDialog(this);}

Page 249: Windows Programming

MFC Tutorial 249

ISLab ICE HUFSISLab ICE HUFS

모드리스 다이얼로그 생성모드리스 다이얼로그 생성

Visible 세팅

Page 250: Windows Programming

MFC Tutorial 250

ISLab ICE HUFSISLab ICE HUFS

DDX/DDV DDX/DDV 사용시사용시

Page 251: Windows Programming

MFC Tutorial 251

ISLab ICE HUFSISLab ICE HUFS

DDX/DDVDDX/DDV 를 사용한 클래스 정의를 사용한 클래스 정의class CTestDialog : public CDialog{public: WORD m_nVal; CTestDialog(CWnd* pParent = NULL);

//{{AFX_DATA(CTestDialog) enum { IDD = IDD_TESTDIALOG }; UINT m_wNumber; //}}AFX_DATA

//{{AFX_VIRTUAL(CTestDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

....}

Page 252: Windows Programming

MFC Tutorial 252

ISLab ICE HUFSISLab ICE HUFS

DoDataExchangeDoDataExchange

void CTestDialog::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTestDialog) DDX_TEXT(pDX, IDC_NUMBER, m_wNumber); DDV_MinMaxUInt(pDX, m_wNumber, 50, 200); //}}AFX_DATA_MAP}

Page 253: Windows Programming

MFC Tutorial 253

ISLab ICE HUFSISLab ICE HUFS

DDX/DDV DDX/DDV 매크로매크로DDX_CBIndex, DDX_CBString, DDX_CBStringExact 콤보 박스 관련DDX_LBIndex, DDX_LBString, DDX_LBStringExact 리스트 박스 관련DDX_Check 체크 박스 관련DDX_Radio 라디오 박스 관련DDX_Scroll 스크롤바 관련DDX_TextDDX_Control 에디트 콘트롤 관련

Page 254: Windows Programming

MFC Tutorial 254

ISLab ICE HUFSISLab ICE HUFS

다이얼로그 클래스다이얼로그 클래스

CDialog

CCommonDialog

CFileDialog

CColorDialog

CFontDialog

CFindReplaceDialog

CPrintDialog

CPageSetupDialog

Page 255: Windows Programming

MFC Tutorial 255

ISLab ICE HUFSISLab ICE HUFS

배율 설정 기능의 배율 설정 기능의 ToolBarToolBar 로의 적용로의 적용

• CMainFrame 클래스에 다음 함수 정의

void CMainFrame::SetZoomRange(int nMin, int nMax){ m_wndToolBar.m_zoomScroll.SetScrollRange(nMin, nMax);}

void CMainFrame::SetZoomPos(int nPos){ m_wndToolBar.m_zoomScroll.SetScrollPos(nPos); CString szTemp; szTemp.Format(“%d %%”, nPos); m_wndToolBar.m_zoomStatic.SetWindowText(szTemp);}

Page 256: Windows Programming

MFC Tutorial 256

ISLab ICE HUFSISLab ICE HUFS

CObeditView::OnInitialUpdateCObeditView::OnInitialUpdate

#include “MainFrm.h”. . .

void CObeditView::OnInitialUpdate(){ CScrollView::OnInitialUpdate(); CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); pFrame->SetZoomRange(10, 800); pFrame->SetZoomPos(m_zoomRatio); SetScrollSize(MM_TEXT, GetDocument()->GetDocumentSize());}

Page 257: Windows Programming

MFC Tutorial 257

ISLab ICE HUFSISLab ICE HUFS

CObeditView::SetZoomFactorCObeditView::SetZoomFactor

void CObeditView::SetZoomFactor(UINT zoomFactor){ m_zoomRatio = zoomRatio; CClientDC dc(NULL);

OnPrepareDC(&dc); CSize size = GetDocument()->GetDocumentSize();

dc.LPtoDP(&size); SetScrollSize(MM_TEXT, size);

CMainFrame *pMain = (CMainFrame*)AfxGetMainWnd(); pMain->SetZoomPos(m_zoomRatio);}

Page 258: Windows Programming

MFC Tutorial 258

ISLab ICE HUFSISLab ICE HUFS

WM_HSCROLL WM_HSCROLL 처리처리#include “ObeditDoc.h”#include “ObeditView.h”

. . .

void CMyToolBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){ int nMin, nMax;

m_zoomScroll.GetScrollRange(&nMin, &nMax); int nOldPos, nCurPos = m_zoomScroll.GetScrollPos(); nOldPos = nCurPos; switch(nSBCode) { case SB_LEFT : nCurPos = nMin; break;

Page 259: Windows Programming

MFC Tutorial 259

ISLab ICE HUFSISLab ICE HUFS

case SB_RIGHT : nCurPos = nMax; break; case SB_LINELEFT : nCurPos -= 10; break; case SB_LINERIGHT : nCurPos += 10; break; case SB_PAGELEFT : nCurPos -= 50; break; case SB_PAGERIGHT : nCurPos += 50; break; case SB_THUMBTRACK : case SB_THUMBPOSITION : nCurPos = nPos; break;}

Page 260: Windows Programming

MFC Tutorial 260

ISLab ICE HUFSISLab ICE HUFS

if (nCurPos < nMin) nCurPos = nMin; else if (nCurPos > nMax) nCurPos = nMax; if (nOldPos == nCurPos) return; m_zoomScroll.SetScrollPos(nCurPos);

CString szTemp; szTemp.Format(“%d %%”, nCurPos); m_zoomStatic.SetWindowText(szTemp);

// set zoom ratio to view window CMDIChildWnd* pChildFrame = (CMDIChildWnd *) (((CMDIFrameWnd*)AfxGetMainWnd())->MDIGetActive()); CObeditView* pView = (CObeditView*)pChildFrame->GetActiveView(); pView->SetZoomFactor(nCurPos); pView->Invalidate();}

Page 261: Windows Programming

MFC Tutorial 261

ISLab ICE HUFSISLab ICE HUFS

마우스 커서의 변환마우스 커서의 변환

• SetCursor

void CObeditView::OnLButtonDown(){ . . . ::SetCapture(AfxGetApp()->LoadCursor(IDC_MYCURSOR1);}

// WM_SETCURSOR 메시지 처리BOOL CObeditView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){ ::SetCursor(AfxGetApp()->LoadCursor(IDC_MYCURSOR2); return TRUE;}

Page 262: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

기타 기타 Dialog Box Dialog Box 구현구현

Page 263: Windows Programming

MFC Tutorial 263

ISLab ICE HUFSISLab ICE HUFS

목차목차

• Owner Draw List Box• Property Sheet

Page 264: Windows Programming

MFC Tutorial 264

ISLab ICE HUFSISLab ICE HUFS

Owner-Draw List BoxOwner-Draw List Box

• 펜 속성을 선택하는 dialog• 각 펜의 모양을 그림으로 list box 에 표현• List box 의 각 항목을 직접 그려야 함• List box 의 각 항목의 순서를 지정할 수 있어야 함• List box 에 그릴 각 항목의 크기를 알 수 있어야 함

Page 265: Windows Programming

MFC Tutorial 265

ISLab ICE HUFSISLab ICE HUFS

펜 속성 지정 다이얼로그펜 속성 지정 다이얼로그

Spin. IDC_SPINWIDTH

List Box. IDC_LISTSTYLE

Edit Box. IDC_EDITWIDTHStatic. IDC_STATIC

비트맵이들어가기

때문

Page 266: Windows Programming

MFC Tutorial 266

ISLab ICE HUFSISLab ICE HUFS

CPenAttrDlgCPenAttrDlg

• CPenAttrDlg 클래스 생성• Member Variable - Class Wizard

– m_editWidth Value UINT– m_listStyle Control CListBox– m_spinWidth Control CSpinButtonCtrl

Page 267: Windows Programming

MFC Tutorial 267

ISLab ICE HUFSISLab ICE HUFS

CLineStyleListBox CLineStyleListBox 클래스 생성클래스 생성

• CListBox로부터 계승• Owner-Draw List Box를 위하여 다음 함수를 재정의

– CompareItem• 정렬의 대상이 명확하지 않기 때문에 이를 비교하기 위한 함수

– DrawItem• 리스트 박스의 항목을 그릴 때 각 항목마다 호출되는 함수

– MeasureItem• 항목의 높이를 정하기 위해 각 항목마다 호출되는 함수

Page 268: Windows Programming

MFC Tutorial 268

ISLab ICE HUFSISLab ICE HUFS

MeasureItemMeasureItem#define COLOR_ITEM_HEIGHT 20

void CLineStyleListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem){ lpMeasureItem->itemHeight = COLOR_ITEM_HEIGHT;}

Page 269: Windows Programming

MFC Tutorial 269

ISLab ICE HUFSISLab ICE HUFS

DrawItem(1)DrawItem(1)

void CLineStyleListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); int nStyle = (int)lpDrawItemStruct->itemData;

if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE) { CPen Pen(nStyle, 1, RGB(0,0,0)); // 검은 색 펜을 만든다 CPen* pOldPen = pDC->SelectObject(&Pen);

int y = lpDrawItemStruct->rcItem.top + (lpDrawItemStruct ->rcItem.bottom + lpDrawItemStruct->rcItem.top)/2); pDC->MoveTo(0, y); pDC->LineTo(lpDrawItemStruct->rcItem.right, y); pDC->SelectObject(pOldPen); }

Page 270: Windows Programming

MFC Tutorial 270

ISLab ICE HUFSISLab ICE HUFS

DrawItem(2)DrawItem(2) if ((lpDrawItemStruct->itemState & ODS_SELECTED) && (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))) { // item has been selected - hilite frame pDC->InvertRect(&lpDrawItemStruct->rcItem); }

if (!(lpDrawItemStruct->itemState & ODS_SELECTED) && (lpDrawItemStruct->itemAction & ODA_SELECT)) { pDC->InvertRect(&lpDrawItemStruct->rcItem); }}

Page 271: Windows Programming

MFC Tutorial 271

ISLab ICE HUFSISLab ICE HUFS

CompareItemCompareItem

int CLineStyleListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct){ int nStyle1 = (int)lpCompareItemStruct->itemData1; int nStyle2 = (int)lpCompareItemStruct->itemData2;

if (nStyle1 == nStyle2) return 0; else if (nStyle1 < nStyle2) return -1; else return 1;}

Page 272: Windows Programming

MFC Tutorial 272

ISLab ICE HUFSISLab ICE HUFS

DRAWITEMSTRUCTDRAWITEMSTRUCTtypedef struct tagDRAWITEMSTRUCT { UINT CtlType; // Owner-Draw 리스트 박스의 경우에는 ODT_LISTBOX 가 들어옴 UINT CtlID; // Control ID 가 들어온다 . UINT itemID; // List box 에서 몇 번째 항목인지를 나타내는 인덱스가 들어옴 UINT itemAction; // 지금 list box 에 취해진 작업의 종류를 나타낸다 . // ODA_DRAWENTIRE : list box 자체가 다시 그려져야 할 때 // ODA_FOCUS : list box 에 포커스가 새로 왔거나 포커스를 잃을 때 // ODA_SELECT : list box 의 선택 상태가 변경되었을 때 UINT itemState; // 지금 항목의 상태를 나타낸다 . 상태에 따라 그려주는 것이 // 달라지기 때문에 중요하다 . Ownerdraw list box 의 경우에는 // ODS_DISABLED : 이 항목이 비활성화된 것으로 그려져야 하는 경우 // ODS_FOCUS : 이 항목에 입력 포커스가 있는 것으로 그려져야 할 때 // ODS_SELECTED : 이 항목이 선택된 것으로 그려져야 할 경우 HWND hWnditem; // ownerdraw list box 의 window handle HDC hDC; // 이 항목이 그려질 영역에 대한 device context handle // 핸들을 기반으로 존재하는 모든 클래스들은 핸들로부터 클래스 // 오브젝트를 만들어 주는 FromHandle 이라는 멤버함수를 가지고 있다 . // DrawItem 함수에서는 이 핸들을 CDC 클래스로 변환하여 사용한다 . RECT rcItem; //

이 항목의 위치를 나타낸다 . 반드시 이 안에만 그려야 함 DWORD itemDate; // 이 항목에 들어간 값을 나타낸다 . 보통의 list box 라면 // 여기에 텍스트가 들어가게 된다 .} DRAWITEMSTRUCT;

Page 273: Windows Programming

MFC Tutorial 273

ISLab ICE HUFSISLab ICE HUFS

리스트 박스에 항목 추가리스트 박스에 항목 추가

• InsertString– 절렬 순서에 관계없이 항목을 지정한 곳에 넣는다 .

• AddString– 정렬한 다음에 리스트 박스에 추가– CompareItem 함수를 호출하여 정렬하게 된다 .

• 오너드로인 경우 그 항목을 그릴 때 사용할 수 있는 값을 줌– 예제에서는 펜의 스타일을 인자로 사용

• 직접 데이타 맵을 수정해야

Page 274: Windows Programming

MFC Tutorial 274

ISLab ICE HUFSISLab ICE HUFS

Data Map Data Map 수정수정// PenAttrDlg.h : header file//#include “LineStyleListBox.h”

class CPenAttrDlg : public CDialog{// Constructionpublic: int m_lineStyle; // 선의 스타일을 가리키는 변수 CPenAttrDlg(CWnd* pParent = NULL);

// Dialog Data //{{AFX_DATA(CPenAttrDlg) enum { IDD = IDD_PENATTRIBUTE; }; CSpinButtonCtrl m_spinWidth; CLineStyleListBox m_listStyle; UINT m_editWidth; //}}AFX_DATA

Page 275: Windows Programming

MFC Tutorial 275

ISLab ICE HUFSISLab ICE HUFS

WM_INITDIALOGWM_INITDIALOG

BOOL CPenAttrDlg::OnInitDialog(){ CDialog::OnInitDialog();

m_spinWidth.SetBuddy(GetDlgItem(IDC_EDITWIDTH)); m_spinWidth.SetRange(1, 20); m_spinWidth.SetBase(10); m_spinWidth.SetPos(m_editWidth);

m_listStyle.AddString((LPCTSTR)(PS_SOLID)); m_listStyle.AddString((LPCTSTR)(PS_DASH)); m_listStyle.AddString((LPCTSTR)(PS_DOT)); m_listStyle.AddString((LPCTSTR)(PS_DASHDOT)); m_listStyle.AddString((LPCTSTR)(PS_DASHDOTDOT)); m_listStyle.AddString((LPCTSTR)(PS_NULL));

return TRUE;}

Page 276: Windows Programming

MFC Tutorial 276

ISLab ICE HUFSISLab ICE HUFS

OnOKOnOK

void CPenAttrDlg::OnOK(){ int index = m_listStyle.GetCurSel();

m_lineStyle = (UINT)m_listStyle.GetItemData(index); CDialog::OnOK();}

Page 277: Windows Programming

MFC Tutorial 277

ISLab ICE HUFSISLab ICE HUFS

메뉴 처리 함수 생성메뉴 처리 함수 생성

• ID_OBJECT_PENATTR 명령의 COMMAND 메시지 핸들러

#include “PenAttrDlg.h” . . . void CObeditView::OnObjectPenattr() { CPenAttrDlg penAttrDlg(this);

penAttrDlg.m_editWidth = m_nPenWidth; penAttrDlg.m_lineStyle = m_nPenStyle;

if (penAttrDlg.DoModal() != IDOK) return;

m_nPenWidth = penAttrDlg.m_editWidth; m_nPenStyle = penAttrDlg.m_lineStyle; }

Page 278: Windows Programming

MFC Tutorial 278

ISLab ICE HUFSISLab ICE HUFS

Property SheetProperty Sheet

• 여러 개의 Property Page 로 하나의 Property Sheet 를 생성

Page 279: Windows Programming

MFC Tutorial 279

ISLab ICE HUFSISLab ICE HUFS

파일 정보 다이얼로그 생성파일 정보 다이얼로그 생성

IDD_SUMM_PAGE

Edit. IDC_AUTHOR Edit. IDC_KEYWORDS

List Box.IDC_COMMENTS

Edit. IDC_TITLE

Edit. IDC_SUBJECT

Static. IDC_APPNAME

Page 280: Windows Programming

MFC Tutorial 280

ISLab ICE HUFSISLab ICE HUFS

Dialog PropertiesDialog Properties

Page 281: Windows Programming

MFC Tutorial 281

ISLab ICE HUFSISLab ICE HUFS

CSummaryPage CSummaryPage 클래스 생성클래스 생성

• 상위 클래스로 CPropertyPage 선택• Member Variables (Class Wizard)

– IDC_APPNAME m_AppName Value CString– IDC_AUTHOR m_Author Value CString– IDC_COMMENTS m_Comments Value CString– IDC_KEYWORDS m_Keywords Value CString– IDC_SUBJECT m_Subject Value CString– IDC_TITLE m_Title Value CString

Page 282: Windows Programming

MFC Tutorial 282

ISLab ICE HUFSISLab ICE HUFS

파일 통계 다이얼로그파일 통계 다이얼로그IDC_REVNUM IDC_EDITTIME IDC_LASTPRINT

IDC_CREATEDATE IDC_LASTSAVE

Page 283: Windows Programming

MFC Tutorial 283

ISLab ICE HUFSISLab ICE HUFS

CFileStatPage CFileStatPage 클래스 생성클래스 생성

• 상위 클래스로 CPropertyPage 선택• Member Variables (Class Wizard)

– IDC_CREATEDATE m_CreateDate Value CString– IDC_EDITTIME m_EditTime Value CString– IDC_LASTPRINT m_LastPrint Value CString– IDC_LASTSAVE m_LastSave Value CString– IDC_REVNUM m_RevNum Value CString

Page 284: Windows Programming

MFC Tutorial 284

ISLab ICE HUFSISLab ICE HUFS

Document Document 클래스에 멤버 추가클래스에 멤버 추가class CObeditDoc : public CDocument{ . . .public: CString m_AppName; CString m_Author; CString m_Comments; CString m_Keywords; CString m_Subject; CString m_Title;

CString m_CreateDate; UINT m_EditTime; CString m_LastPrint; CString m_LastSave; UINT m_RevNum; CTime m_StartTime; . . .

Page 285: Windows Programming

MFC Tutorial 285

ISLab ICE HUFSISLab ICE HUFS

생성자생성자CObeditDoc::CObeditDoc(){ m_sizeDoc = CSize(500, 500); m_AppName = _T(“ 도형편집기” ); // 유니코드 혹은 ANSI 문자열}

Page 286: Windows Programming

MFC Tutorial 286

ISLab ICE HUFSISLab ICE HUFS

OnNewDocumentOnNewDocument

BOOL CObeditDoc::OnNewDocument(){ if (!CDocument::OnNewDocument()) return FALSE;

m_EditTime = 0; m_RevNum = 0;

char szTemp[32]; _strdate(szTemp); m_CreateDate = szTemp; m_CreateDate += “ “; _strtime(szTemp); m_CreateDate += szTemp;

m_StartTime = CTime::GetCurrentTime();

return TRUE;}

Page 287: Windows Programming

MFC Tutorial 287

ISLab ICE HUFSISLab ICE HUFS

Property Sheet Property Sheet 생성생성

• CPropertySheet– 하나 이상의 Property Page 로 구성– 각 PropertyPage 객체를 AddPage 함수를 이용하여 등록

Page 288: Windows Programming

MFC Tutorial 288

ISLab ICE HUFSISLab ICE HUFS

ID_FILE_SUMMARY_INFOID_FILE_SUMMARY_INFO

#include “FileStatPage.h”#include “SummaryPage.h”. . .void CObeditView::OnFileSummaryInfo(){ CPropertySheet sheet(_T(“ 문서정보” )); CSummaryPage sum; CFileStatPage state;

sheet.AddPage(&sum); sheet.AddPage(&state);

sum.m_AppName = GetDocument()->m_AppName; sum.m_Author = GetDocument()->m_Author; sum.m_Comments = GetDocument()->m_Comments; sum.m_Keywords = GetDocument()->m_Keywords; sum.m_Subject = GetDocument()->m_Subject; sum.m_Title = GetDocument()->m_Title;

Page 289: Windows Programming

MFC Tutorial 289

ISLab ICE HUFSISLab ICE HUFS

state.m_CreateDate = GetDocument()->m_CreateDate; state.m_EditTime.Format(“%d”, GetDocument()->m_EditTime); state.m_LastPrint = GetDocument()->m_LastPrint; state.m_LastSave = GetDocument()->m_LastSave; state.m_RevNum.Format(“%d”, GetDocument()->m_RevNum);

if (sheet.DoModal() != IDOK) return;

GetDocument()->m_AppName = sum.m_AppName; GetDocument()->m_Author = sum.m_Author; GetDocument()->m_Comments = sum.m_Comments; GetDocument()->m_Keywords = sum.m_Keywords; GetDocument()->m_Subject = sum.m_Subject; GetDocument()->m_Title = sum.m_Title;}

Page 290: Windows Programming

MFC Tutorial 290

ISLab ICE HUFSISLab ICE HUFS

CProperySheet CProperySheet 클래스클래스

• 보통의 윈도우임• 일반적인 다이얼로그처럼 사용

– DoModal– Create

• Style– Child– Thin– More Styles - Disabled

CObject

CCmdTarget

CWnd

CPropertySheet

Page 291: Windows Programming

MFC Tutorial 291

ISLab ICE HUFSISLab ICE HUFS

CProperSheet CProperSheet 클래스 멤버 함수클래스 멤버 함수

• AddPage• RemovePage• GetPageCount• SetActivePage

– 특정 페이지를 전면으로– CPropertyPage* pPropPage = GetPage(0);

• OnCreate– 프라퍼티시트에 다른 콘트롤을 달때– MoveWindow : 프로퍼티시트의 크기 확대시– GetWindowRect : 현재 윈도우의 크기와 위치를 알고자 할때

Page 292: Windows Programming

MFC Tutorial 292

ISLab ICE HUFSISLab ICE HUFS

적용 버튼 활성화적용 버튼 활성화

• CPropertyPage::SetModified(TRUE)– 적용 버튼이 활성화된다 .

• 적용 버튼에 대한 핸들러 작성– 적용 버튼의 컨트롤 ID : ID_APPLY_NOW– COMMAND 메시지 핸들러 작성– 직접 메시지맵을 수정해야

BEGIN_MESSAGE_MAP(CMyPropertySheet, CPropertySheet)//{{AFX_DATA(CMyPropertySheet)ON_COMMAND(ID_APPLY_NOW, OnApplyNow)//}}AFX_MSG_MAPEND_MESSAGE_MAP()

Page 293: Windows Programming

MFC Tutorial 293

ISLab ICE HUFSISLab ICE HUFS

적용 처리 함수적용 처리 함수class CMyPropertySheet : public CPropertySheet{public: DECLARE_DYNAMIC(CMyPropertySheet) ....// Message Handlersprotected: //{{AFX_MSG(CMyPropertySheet) afx_msg void OnApplyNow(); //}}AFX_MSG DECLARE_MESSAGE_MAP()};

void CMyPropertySheet::OnApplyNow(){ Default(); .... // 리턴하기 전에 프로퍼티시트를 구성하는 각 페이지마다 // SetModified(FALSE) 를 호출해야}

Page 294: Windows Programming

MFC Tutorial 294

ISLab ICE HUFSISLab ICE HUFS

Wizard Wizard 모드모드

• SetWizardMode• SetWizardButton• SetFinishText

– Finish 버튼에 나타나는 타이틀을 변경하고자 할 때

Page 295: Windows Programming

MFC Tutorial 295

ISLab ICE HUFSISLab ICE HUFS

SetWizardModeSetWizardMode

void CObeditView::OnFileSummaryInfo() { CPropertySheet sheet(_T(" 문서정보 ")); CSummaryPage sum; CFileStatPage state;

sheet.AddPage(&sum); sheet.AddPage(&state);

sheet.SetWizardMode();

sum.m_AppName = GetDocument()->m_AppName; sum.m_Author = GetDocument()->m_Author; sum.m_Comments = GetDocument()->m_Comments;

Page 296: Windows Programming

MFC Tutorial 296

ISLab ICE HUFSISLab ICE HUFS

SetWizardButtonSetWizardButton

PSWIZB_BACK 뒤로 버튼을 활성화한다 .PSWIZB_NEXT 다음 버튼을 활성화한다 .PSWIZB_FINISH 종료 버튼을 활성화한다 .PSWIZB_DISABLEDFINISH 종료 버튼을 disable 한다 .

BOOL CMyPropertyPage::OnSetActive() // virtual function{ CPropertySheet* pSheet = (CPropertySheet*)GetParent(); pSheet->SetWizardButton( PSWIZB_NEXT ); return CPropertySheet::OnSetActive();}

Page 297: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

파일 파일 I/O I/O 기능의 추가기능의 추가

Page 298: Windows Programming

MFC Tutorial 298

ISLab ICE HUFSISLab ICE HUFS

목차목차

• MFC 의 파일 I/O 구조• 문서 변경 여부• CFile, CArchive• Serialize

Page 299: Windows Programming

MFC Tutorial 299

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 파일 의 파일 I/O I/O 구조구조

• CWinApp, CDocument 클래스에서 미리 일반화시켜 놓았다 .

• 사용자는 필요한 부분의 가상 함수만 제공New CWinApp::OnFileNewOpen CWinApp::OnFileOpenClose CDocument::OnFileCloseSave CDocument::OnFileSaveSave As CDocument::OnFileSaveAs

• New, Open 도 실제로는 CDocument 클래스 내에 정의된 부분을 호출

Page 300: Windows Programming

MFC Tutorial 300

ISLab ICE HUFSISLab ICE HUFS

OnFileNewOnFileNew

• MDI 프로그램의 경우라면 -> MDI 자식윈도우 클래스와 뷰 클래스의 오브젝트를 만든다 .

• SDI 프로그램의 경우라면 -> 이미 만들어져 있는 뷰를 그대로 사용한다 .

• 다음으로 문서클래스의 오브젝트를 생성한다 .• 그리고 나서 문서클래스 (CDocument 클래스 ) 의 OnNew

Document 멤버함수를 호출한다 .• 뷰클래스의 OnInitialUpdate 함수를 호출한다 .

Page 301: Windows Programming

MFC Tutorial 301

ISLab ICE HUFSISLab ICE HUFS

OnFileOpenOnFileOpen

• 읽어 들일 파일 이름을 입력받기 위한 파일 열기 다이얼로그 박스를 띄운다 .

• MDI 프로그램의 경우라면 -> MDI 자식윈도우 클래스의 오브젝트와 뷰클래스의 오브젝트를 만든다 .

• SDI 프로그램의 경우라면 -> 이미 만들어져 있는 뷰를 그대로 사용한다 .

• 다음으로 문서클래스의 오브젝트를 생성한다 .• 파일의 내용을 읽어들이기 위해 문서클래스의 OnOpenD

ocument 멤버함수를 호출한다 .• 뷰클래스의 OnInitialUpdate 함수를 호출한다 .

Page 302: Windows Programming

MFC Tutorial 302

ISLab ICE HUFSISLab ICE HUFS

파일 열기 다이얼로그 박스파일 열기 다이얼로그 박스

Page 303: Windows Programming

MFC Tutorial 303

ISLab ICE HUFSISLab ICE HUFS

OnFileCloseOnFileClose

• 현재 문서가 저장되지 않았으면 (IsModified 함수 호출 ) 저장 여부를 묻는 메시지박스를 띄운다 . 저장하겠다고 하면 파일 이름이 있는 경우 , 문서클래스의 OnSaveDocument 함수를 불러 저장

• 저장하겠다고 했지만 파일 이름이 없는 경우 , 파일 이름을 입력받기 위한 다이얼로그 박스를 띄워 이름을 입력받아 저장한다 ( 역시 OnSaveDocument 호출 )

• 문서 클래스의 OnCloseDocument 함수를 불러 이 문서와 관련된 청소 작업을 한다 .

Page 304: Windows Programming

MFC Tutorial 304

ISLab ICE HUFSISLab ICE HUFS

OnCloseDocumentOnCloseDocument

• 현재 편집중이던 문서와 관련된 자료 구조 등을 정리하는 작업과 윈도우 등을 닫는 작업을 수행한다 .

• 자료 구조를 정리하기 위해 문서클래스의 DeleteContents 함수를 호출한다 .

Page 305: Windows Programming

MFC Tutorial 305

ISLab ICE HUFSISLab ICE HUFS

문서 변경 여부문서 변경 여부

• SetModifiedFlag– 문서가 변경되는 지점에서 SetModifiedFlag() 함수 호출

• IsModified– 문서가 변경되었는지를 알아내는 함수 . 이전에 SetModifiedFlag

함수를 불렀다면 TRUE가 아니면 FALSE가 반환된다 .– 파일을 저장하면 이 플래그는 다시 FALSE로 바뀐다 .

Page 306: Windows Programming

MFC Tutorial 306

ISLab ICE HUFSISLab ICE HUFS

OnFileSaveOnFileSave

• 편집중인 문서의 파일 이름이 있으면 문서클래스의 OnSaveDocument 함수를 불러 저장

• 편집중인 문서의 파일 이름이 없으면 파일 이름을 입력받기 위한 다이얼로그 박스를 띄워 이름을 입력받아 저장 ( 역시 OnSaveDocument 호출 )

Page 307: Windows Programming

MFC Tutorial 307

ISLab ICE HUFSISLab ICE HUFS

OnFileSaveAsOnFileSaveAs

• 파일 이름을 입력받기 위한 다이얼로그 박스를 띄운다 .• 이름이 입력되면 OnSaveDocument 함수를 불러 문서의

내용을 저장한다 .

Page 308: Windows Programming

MFC Tutorial 308

ISLab ICE HUFSISLab ICE HUFS

CFile, CArchiveCFile, CArchive

CFile file; // CFile 클래스의 file 오브젝트를 정의한다 .file.Open( “sample”, CFile::modeRead ); // 파일을 오픈한다 .DeleteContents(); // 지금까지 편집중이던 이전 문서의 내용을 삭제CArchive archive(&file, CArchive::loadArchive); // file 오브젝트를 대신

// 하는 CArchive 클래스의 archive 오브젝트를 // 생성한다 .Serialize(archive); // 파일의 내용을 읽어들인다 .archive.Close(); // 파일 입출력을 대행하던 archive 를 닫는다 .file.Close(); // 파일을 닫는다 .

Page 309: Windows Programming

MFC Tutorial 309

ISLab ICE HUFSISLab ICE HUFS

CArchiveCArchive

• 저장될 대상과 실제 저장 매체 (storage medium) 사이의 매개체 역할을 수행

• 저장 매체의 특성에 관계없이 CArchive 클래스의 멤버 함수만을 이용하여 입출력– 파일 , 소켓 , OLE

파일

네트웍CArchive클래스

저장대상이 되는자료구조나

전송대상이 되는자료구조

Page 310: Windows Programming

MFC Tutorial 310

ISLab ICE HUFSISLab ICE HUFS

CArchive CArchive 클래스의 멤버 함수클래스의 멤버 함수

>> operator BYTE, WORD, LONG, DWORD, float, double 과 같은 일반수형과 Cobject 로부터 계승된 클래스의 읽기 담당

<< operator BYTE, WORD, LONG, DWORD, float, double 과 같은 일반수형과 Cobject 로부터 계승된 클래스의 저장 담당

Read 이진 데이터를 읽어들인다 .Write 이진 데이터를 저장한다 .WriteString 한 줄의 문자열을 저장한다 .ReadString 한 줄의 문자열을 읽어들인다 .GetFile CArchive 클래스의 오브젝트가 대신하고 있는 CFile

오브젝트의 포인터를 돌려준다IsLoading CArchive 클래스의 오브젝트를 읽기 작업을 위해 오픈한

경우에는 TRUE가 리턴IsWriting CArchive 클래스의 오브젝트를 저장 작업을 위해 오픈한 경우에는

TRUE가 리턴

Page 311: Windows Programming

MFC Tutorial 311

ISLab ICE HUFSISLab ICE HUFS

SerializeSerialize

void CObeditDoc::Serialize(CArchive& ar){ if (ar.IsLoading()) { // TODO: add storing code here } else { // TODO: add loading code here }}

Page 312: Windows Programming

MFC Tutorial 312

ISLab ICE HUFSISLab ICE HUFS

직렬화직렬화 (serialization)(serialization)

• 디스크에 저장하거나 읽는 작업• 디스크에 저장할 때는 순서대로 데이터를 저장해야 하므로

직렬화라는 이름을 붙임• Linked list 의 멤버 함수에도 Serialize 함수가 있음 .

– 이것은 각 노드에 있는 객체의 Serialize 함수를 불러준다 .

Page 313: Windows Programming

MFC Tutorial 313

ISLab ICE HUFSISLab ICE HUFS

CObeditDoc::Serialize(1)CObeditDoc::Serialize(1)

....#include “stdafx.h”#include “Obedit.h”#include “ObeditDoc.h”#include “DrawObj.h”....

void CObeditDoc::Serialize(CArchive& ar){ if (ar.IsStoring()) { CTime curTime = CTime::GetCurrentTime(); m_LastSave = curTime.Format("%m/%d/%y %H:%M:%S"); CTimeSpan elapsedTime = curTime - m_StartTime; m_EditTime += elapsedTime.GetTotalSeconds(); m_StartTime = curTime;

Page 314: Windows Programming

MFC Tutorial 314

ISLab ICE HUFSISLab ICE HUFS

CObeditDoc::Serialize(2)CObeditDoc::Serialize(2)

m_RevNum++;

ar << m_AppName; ar << m_Author; ar << m_Comments; ar << m_Keywords; ar << m_Subject; ar << m_Title;

ar << m_CreateDate; ar << m_EditTime; ar << m_LastPrint; ar << m_LastSave; ar << m_RevNum;

ar << m_sizeDoc;

} else {

m_StartTime = CTime::GetCurrentTime();

ar >> m_AppName; ar >> m_Author; ar >> m_Comments; ar >> m_Keywords; ar >> m_Subject; ar >> m_Title; ar >> m_CreateDate; ar >> m_EditTime; ar >> m_LastPrint; ar >> m_LastSave; ar >> m_RevNum;

ar >> m_sizeDoc; } m_objectList.Serialize(ar);}

Page 315: Windows Programming

MFC Tutorial 315

ISLab ICE HUFSISLab ICE HUFS

CLine::SerializeCLine::Serialize

void CLine::Serialize(CArchive& ar){ CDrawObject::Serialize(ar); if (ar.IsLoading()) { } else { }}

Page 316: Windows Programming

MFC Tutorial 316

ISLab ICE HUFSISLab ICE HUFS

CDrawObject::SerializeCDrawObject::Serialize

void CDrawObject::Serialize(CArchive& ar){ CObject::Serialize(ar); if (ar.IsStoring()) { ar << m_wObjType; ar << m_crColor; ar << m_nPenStyle; ar << m_nPenWidth; ar << m_rcRect; } else { ar >> m_wObjType; ar >> m_crColor; ar >> m_nPenStyle; ar >> m_nPenWidth; ar >> m_rcRect; }}

Page 317: Windows Programming

MFC Tutorial 317

ISLab ICE HUFSISLab ICE HUFS

CObject::SerializeCObject::Serialize

• 호출하지 않으면 파일 입출력이 제대로 동작 안함• CObject 클래스에 관한 정보를 저장하고 읽어들이는

기능• 이 정보를 바탕으로 도형클래스를 따로 생성하지 않아도

자동으로 도형클래스를 생성하고 있다 .

Page 318: Windows Programming

MFC Tutorial 318

ISLab ICE HUFSISLab ICE HUFS

Serialize Serialize 함수 호출 순서함수 호출 순서CDocument 의 Serialize 함수

도형리스트의 Serialize 함수호출(m_objectList.Serialize)

도형별로 Serialize 함수를 호출

일단 프로그램전체에 걸친 정보를 입출력 한다

Page 319: Windows Programming

MFC Tutorial 319

ISLab ICE HUFSISLab ICE HUFS

SetModifiedFlagSetModifiedFlag

Page 320: Windows Programming

MFC Tutorial 320

ISLab ICE HUFSISLab ICE HUFS

SetModifiedFlag SetModifiedFlag 추가추가

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point) {

if (GetCapture() == this){

CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCapture();

CObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_objectList.AddTail(m_pCurDrawObject); pDoc->SetModifiedFlag(TRUE);

}}

Page 321: Windows Programming

MFC Tutorial 321

ISLab ICE HUFSISLab ICE HUFS

DeleteContentsDeleteContents

void CObeditDoc::DeleteContents() {

while(!m_objectList.IsEmpty()){

delete m_objectList.RemoveHead();}CDocument::DeleteContents();

}

Page 322: Windows Programming

MFC Tutorial 322

ISLab ICE HUFSISLab ICE HUFS

CArchive CArchive 클래스 연산자 클래스 연산자 <<, >><<, >>가 가능한 가 가능한 타입타입

• CObject 에 대한 포인터• CString• SIZE, CSize, POINT, CPoint, RECT, CRect• CTime, CTimeSpan• float, double• BYTE, WORD, DWORD, LONG

• CObject 포인터가 아닌 일반 객체는 Serialize 함수를 호출하여 입출력해야 한다 .

Page 323: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

프린터 관련 명령프린터 관련 명령

Page 324: Windows Programming

MFC Tutorial 324

ISLab ICE HUFSISLab ICE HUFS

목차목차

• MFC 의 프린트 구조• MFC 에서의 미리보기 구조

Page 325: Windows Programming

MFC Tutorial 325

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 에서의 프린터에서의 프린터

• 관련 메뉴– Print, Print Setup, Print Preview

• CPrintDialog

Page 326: Windows Programming

MFC Tutorial 326

ISLab ICE HUFSISLab ICE HUFS

프린트 관련 메뉴프린트 관련 메뉴

메뉴메뉴 기능기능 처리함수 이름 및 정의 위치처리함수 이름 및 정의 위치Print 프린터로 인쇄 OnFilePrint(CView)Print Setup프린터의 환경 설정 OnFilePrintSetup(CWinApp)Print Preview 프린터 출력을 화면 OnFilePrintPreview(CView)

으로

Page 327: Windows Programming

MFC Tutorial 327

ISLab ICE HUFSISLab ICE HUFS

화면과 프린터출력의 비교화면과 프린터출력의 비교

• 거의 모든 함수가 표준화되어 있다 .– 화면 출력에도 사용하는 그래픽 디바이스에 관계없이 단일한

하나의 함수 집합 (GDI, Graphic Device Interface) 을 이용할 수 있다 . - CDC 클래스

– 그외• ODBC(Open Database Connectivity)• MCI(Media Control Interface)

– 프린터 출력시에도 CDC 클래스를 이용하여 출력

• 차이점– 여러 장의 종이에 출력– 출력 상태 표시

Page 328: Windows Programming

MFC Tutorial 328

ISLab ICE HUFSISLab ICE HUFS

프린터 작업시 뷰클래스가 해야 하는 일프린터 작업시 뷰클래스가 해야 하는 일

• 최대 몇페이지나 출력할 수 있는지 , 어느 페이지서부터 어느 페이지까지 출력할 것인지를 결정 - 프린터 다이얼로그 박스를 띄워 선택을 입력받는다 .

• 특정 페이지를 출력하도록 요구받았을 때 그 부분을 그릴 수 있어야 한다 . 필요하다면 머리말과 꼬리말을 출력할 수 있어야 한다 .

• 출력에 필요한 폰트와 다른 GDI 자원들을 할당하고 제거할 수 있어야 한다 .

• 프린터 다이얼로그를 띄워 프린터 DC 를 구함• 일반적인 코딩은 가상함수로 제공

Page 329: Windows Programming

MFC Tutorial 329

ISLab ICE HUFSISLab ICE HUFS

CView::OnFilePrintCView::OnFilePrintCView::OnPreparePrintingCView::OnPreparePrinting

CView::OnBeginPrintingCView::OnBeginPrinting

CDC::StartDocCDC::StartDoc

CView::OnPrepareDCCView::OnPrepareDC

CDC::StartPageCDC::StartPage

CView::OnPrintCView::OnPrint

CDC::EndPageCDC::EndPage

CDC::EndDocCDC::EndDoc

CView::OnEndPrintingCView::OnEndPrinting

출력문서의 페이지 수를 결정해 준다 .다음으로 DoPreparePrinting 함수를 호출하여 프린트 다이얼로그박스를 표시하고 DC 를 생성한다 .

프린트 작업동안 필요한 각종 리소스를 할당한다 .

프린트 작업이 시작됨을 프린터에 알린다 .

프린트와 관계된 여러가지 DC 의 속성들을 바꾸어준다 .더 출력할 페이지가 있는지 검사한다 .

프린트 디바이스 쪽에 새 페이지의 출력이 시작되었음을알린다 .

머릿말과 꼬릿말이 있으면 출력하고 지정된 페이지를출력한다 .

페이지의 출력이 끝났음을 알린다 .

문서 전체의 출력이 끝났음을 알린다 .

OnBeginPrinting 에서 할당했던 리소스들을 제거한다 .

Page 330: Windows Programming

MFC Tutorial 330

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 의 프린트 기능의 구현의 프린트 기능의 구현

• 뷰클래스의 다음 함수의 구현을 어떻게 만드느냐에 달림– OnPreparePrinting– OnBeginPrinting– OnEndPrinting– OnPrepareDC– OnPrint

• 프린트 다이얼로그를 띄우고 프린트 DC 를 만들고 프린트 취소 다이얼로그를 띄우고 하는 일은 MFC 가 알아서 수행

Page 331: Windows Programming

MFC Tutorial 331

ISLab ICE HUFSISLab ICE HUFS

프린트 제어를 위한 프린트 제어를 위한 CDC CDC 클래스의 함수클래스의 함수

• Escape Sequence 함수• StartDoc

– 새로운 문서의 출력이 나감을 알린다 .

• StartPage– 새로운 페이지의 출력이 나감을 알린다 .

• EndPage– 페이지의 출력이 끝났음을 알린다 .

• EndDoc– 문서의 출력이 종료되었음을 알린다 .

Page 332: Windows Programming

MFC Tutorial 332

ISLab ICE HUFSISLab ICE HUFS

CPrintInfo(1)CPrintInfo(1)

• OnPreparePrinting 함수의 인자로 넘어옴• 프린터와 관련한 사용자의 입력을 저장하거나 프린트 , 미리보기 관련 정보를 보관

• 예– 프린트 할 페이지의 범위– 현재 프린트하고 있는 페이지의 번호– 출력용지의 크기 등

Page 333: Windows Programming

MFC Tutorial 333

ISLab ICE HUFSISLab ICE HUFS

CPrintInfo(2)CPrintInfo(2)

struct CPrintInfo // Printing information structure{ CPrintInfo(); ~CPrintInfo();

CPrintDialog* m_pDD; // 여기에 프린트 공통 다이얼로그의 포인터를 보관

BOOL m_bPreview; // 미리보기상태 (TRUE) 인지 프린트상태 (FALSE) 인지 표시 BOOL m_bContinuePrinting; // 프린트를 계속할 것인지의 여부를 표시 UINT m_nCurPage; // 현재 인쇄중이거나 미리보기중인 페이지 UINT m_nNumPreviewPages; // 동시에 미리보기하려는 페이지 수 CString m_strPageDesc; // 페이지번호를 표시하기위한 포맷 스트링 LPVOID m_lpUserData; // pointer to user created struct CRect m_rectDraw; // 인쇄할 종이의 크기

void SetMinPage(UINT nMinPage); void SetMaxPage(UINT nMaxPage); UINT GetMinPage() const; // 출력가능한 페이지의 범위 UINT GetMaxPage() const; UINT GetFromPage() const; // 사용자가 입력한 출력 페이지의 UINT GetToPage() const; // 범위};

Page 334: Windows Programming

MFC Tutorial 334

ISLab ICE HUFSISLab ICE HUFS

OnPrintOnPrint 의 디폴트 코딩의 디폴트 코딩

void CView::OnPrint(CDC* pDC, CPrintInfo*){ ASSERT_VALID(pDC);

// Override and set printing variables based on page number OnDraw(pDC); // Call Draw}

• 페이지의 개념이 없음• OnDraw 를 조금 수정하여 프린트에도 적용• OnPrint 호출 전에 OnPrepareDC 를 먼저 호출한다 .

– 윈도우 매핑모드 변경– CScrollView 의 경우 : 스크롤 상황에 맞추어 원점을 이동

Page 335: Windows Programming

MFC Tutorial 335

ISLab ICE HUFSISLab ICE HUFS

View View 클래스 수정클래스 수정

• 출력이 나가는 종이의 높이 지정

class CObeditView : public CScrollView{ ... int m_nPaperHeight; ...};

Page 336: Windows Programming

MFC Tutorial 336

ISLab ICE HUFSISLab ICE HUFS

OnPreparePrintingOnPreparePrinting

BOOL CObeditView::OnPreparePrinting(CPrintInfo* pInfo){ pInfo->m_nNumPreviewPages = 1; // 미리보기 할 페이지 수를 1 로 정함 return DoPreparePrinting(pInfo);}

• 사용자가 출력 용지를 설정하기 전까지는 몇 페이지에 걸쳐 출력이 일어날지 모름

• 워드 프로세서의 경우 미리 출력 용지를 결정하므로 pInfo->SetMaxPage 함수를 호출하여 출력할 페이지를 결정할 수 있음

Page 337: Windows Programming

MFC Tutorial 337

ISLab ICE HUFSISLab ICE HUFS

OnBeginPrinting(1)OnBeginPrinting(1)

void CObeditView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo){ m_nPaperHeight = pDC->GetDeviceCaps(VERTRES); CSize docSize = GetDocument()->GetDocumentSize(); int nMaxPage = max(1,(docSize.cy+m_nPaperHeight-1)/m_nPaperHeight)); pInfo->SetMaxPage(nMaxPage);}

Page 338: Windows Programming

MFC Tutorial 338

ISLab ICE HUFSISLab ICE HUFS

OnBeginPrinting(2)OnBeginPrinting(2)

• CDC::SetDeviceCaps 함수를 이용하여 출력 용지의 높이를 구함

• 프린트 중에 사용할 GDI 리소스 (펜 , 폰트 , 브러쉬등 )를 할당해 두는 일을 하는 곳– 페이지 출력시마다 리소스 할당을 하지 않기 위해– 즉 , 프린트 작업에 들어가기에 앞서 전체적으로 필요한 GDI

리소스를 할당– OnEndPrinting 에서 이 리소스들을 제거

Page 339: Windows Programming

MFC Tutorial 339

ISLab ICE HUFSISLab ICE HUFS

GetDeviceCapsGetDeviceCaps 의 인자의 인자

HORZRES 현재 선택된 출력용지의 폭을 픽셀 단위로 알고자 할 때VERTRES 현재 선택된 출력용지의 높이를 픽셀 단위로 알고자 할 때HORSIZE 현재 선택된 출력용지의 폭을 밀리미터 단위로 알고자 할 때VERTSIZE 현재 선택된 출력용지의 높이를 밀리미터 단위로 알고자 할때LOGPIXELSX현재 프린터의 수평방향의 DPI(Dot Per Inch) 를 알고자 할 때LOGPIXELSY현재 프린터의 수직방향의 DPI(Dot Per Inch) 를 알고자 할 때NUMCOLORS 프린터가 지원하는 색상의 수를 리턴한다 . 흑백이면 2TECHNOLOGY 현재 디바이스컨텍스트가 나타내는 출력장치가 무엇인지를

돌려준다 . 예로 프린터의 경우에는 DT_RASPRINTER가리턴될 것이다 .DT_PLOTTER : 백터 플로터DT_RASDISPLAY : 래스터 디스플레이DT_RASPRINTER : 래스터 프린터DT_RASCAMERA : 래스터 카메라. . . .

Page 340: Windows Programming

MFC Tutorial 340

ISLab ICE HUFSISLab ICE HUFS

OnEndPrintingOnEndPrinting

• 본 예제에서는 할당한 리소스들이 없으므로 OnEndPrinting 에서 할 일이 없음

void CObeditView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){}

Page 341: Windows Programming

MFC Tutorial 341

ISLab ICE HUFSISLab ICE HUFS

OnPrepareDC OnPrepareDC 함수의 수정함수의 수정

void CObeditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { if (pInfo == NULL) { CScrollView::OnPrepareDC(pDC, pInfo); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportExt(m_zoomRatio, m_zoomRatio); pDC->SetWindowExt(100, 100); } else { pDC->SetViewportOrg(0, -(pInfo->m_nCurPage-1)*m_nPaperHeight); }}

Page 342: Windows Programming

MFC Tutorial 342

ISLab ICE HUFSISLab ICE HUFS

OnPrepareDCOnPrepareDC 에서의 주의점에서의 주의점

• 인자로 넘어오는 CDC 클래스의 오브젝트에 대한 포인터에 대하여 출력을 할 경우– 윈도우 출력의 경우 : 출력이 나감– 프린터 출력의 경우 : 출력이 안 나감– 프린터 출력시에는 OnPrepareDC 의 호출이 끝난 다음에야 새 페이지의 출력을 프린터 드라이버에 알리는 CDC::StartPage 를 호출하기 때문 . 그 전에 호출한 것은 아무런 소용이 없다 .

• 두번째 인자 pInfo– NULL : 화면 출력– NULL 이 아님 : 프린트 출력 . 이때 프린트 쪽의 원점을 뒤로

이동하여 다음 페이지 출력– pInfo->m_nCurPage : 현재 출력이 나갈 페이지의 번호를 가리킴

Page 343: Windows Programming

MFC Tutorial 343

ISLab ICE HUFSISLab ICE HUFS

전체 편집문서

출력용지

3. 종이의 출력원점을전체편집문서의 원점과맞추어주기위해 그만큼뒤로 이동하고OnDraw 를 호출한다 .그러면 1페이지부터N-1 페이지까지의출력은 종이밖으로출력되기 때문에무시된다 .

1. N 페이지만프린트로 출력이나가야한다 .

2. 출력원점의보정없이 OnDraw 를호출하면 항상1 페이지가 출력된다 .종이의 원점에 전체편집문서의원점이 바로 대응되기 때문이다 .

1 페이지

N 페이지

SetViewportOrgSetViewportOrg 를 이용한 페이지의 출력를 이용한 페이지의 출력

Page 344: Windows Programming

MFC Tutorial 344

ISLab ICE HUFSISLab ICE HUFS

편집 문서의 수정편집 문서의 수정

• 출력 용지를 늘리기위해

CObeditDoc::CObeditDoc(){ m_sizeDoc = CSize(1500, 5000); m_AppName = _T(“ 도형편집기” );}

Page 345: Windows Programming

MFC Tutorial 345

ISLab ICE HUFSISLab ICE HUFS

Mapping Mode Mapping Mode 변경변경

• MM_TEXT 로 출력시 출력 결과가 너무 작고 , 프린터 기종 마다 크기가 다르므로

void CObeditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { if (pInfo == NULL) { CScrollView::OnPrepareDC(pDC, pInfo); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportExt(m_zoomRatio, m_zoomRatio); pDC->SetWindowExt(100, 100); } else { pDC->SetMapMode(MM_LOMETRIC); pDC->SetViewportOrg(0, -(pInfo->m_nCurPage-1)*m_nPaperHeight); }}

Page 346: Windows Programming

MFC Tutorial 346

ISLab ICE HUFSISLab ICE HUFS

출력 용지 페이지 수 계산출력 용지 페이지 수 계산void CObeditView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo){ m_nPaperHeight = pDC->GetDeviceCaps(VERTRES); OnPrepareDC(pDC, pInfo); CPoint pt(m_nPaperHeight, m_nPaperHeight); pDC->DPtoLP(&pt);

CSize docSize = GetDocument()->GetDocumentSize(); int nMaxPage = max(1, (docSize.cy + pt.y - 1) / pt.y); pInfo->SetMaxPage(nMaxPage);}

• GetDiviceCaps(VERTSIZE) 를 호출하면 1 밀리미터 단위의 값이 넘어옴 . MM_LOMETRIC 은 0.1 밀미미터 단위의 값임– 오차가 크므로 픽셀 단위의 값을 구한 다음 DPtoLP 를 이용하여

오차를 없앰

Page 347: Windows Programming

MFC Tutorial 347

ISLab ICE HUFSISLab ICE HUFS

프린터로 아무것도 출력이 안되는 이유프린터로 아무것도 출력이 안되는 이유

출력용지

출력원점

+X-X

+Y

-Y

Page 348: Windows Programming

MFC Tutorial 348

ISLab ICE HUFSISLab ICE HUFS

OnPrepareDCOnPrepareDC 의 수정의 수정

void CObeditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { if (pInfo == NULL) { CScrollView::OnPrepareDC(pDC, pInfo); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportExt(m_zoomRatio, m_zoomRatio); pDC->SetWindowExt(100, 100); } else { pDC->SetMapMode(MM_LOMETRIC); pDC->SetMapMode(MM_ANISOTROPIC); CSize size = pDC->GetViewportExt(); pDC->SetViewportExt(size.cx, -size.cy); // 반대방향으로 뒤집음 pDC->SetViewportOrg(0, -(pInfo->m_nCurPage-1)*m_nPaperHeight); }}

Page 349: Windows Programming

MFC Tutorial 349

ISLab ICE HUFSISLab ICE HUFS

MFCMFC 에서의 미리보기 구조에서의 미리보기 구조

• MFC 에서는 기본적인 프린터 출력루틴만 제대로 만들어졌다면 미리보기는 자연스럽게 구현이 된다 .

• 차이점– 미리보기는 윈도우로 출력되기 때문에 프린터 출력과는 달리 WM_PAINT 를 처리할 수 있어야 한다 .

– 사용자의 입력을 기다렸다가 페이지를 출력한다 .

• CPreviewDC– 두개의 DC 를 사용

• 프린터 DC 를 흉내낸 DC• 출력이 실제로 표시되는 윈도우를 나타내는 DC

Page 350: Windows Programming

MFC Tutorial 350

ISLab ICE HUFSISLab ICE HUFS

CPreviewView CPreviewView 클래스클래스

• CPreviewView 클래스– 메인 프레임의 자식 윈도우로 존재

• CPrintInfo 의 m_bPreview 가 TRUE이면 미리보기 중

Page 351: Windows Programming

MFC Tutorial 351

ISLab ICE HUFSISLab ICE HUFS

미리보기 창에 출력미리보기 창에 출력

void CObeditView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo){ m_nPaperHeight = pDC->GetDeviceCaps(VERTRES); OnPrepareDC(pDC, pInfo); CPoint pt(m_nPaperHeight, m_nPaperHeight); pDC->DPtoLP(&pt);

CSize docSize = GetDocument()->GetDocumentSize(); int nMaxPage = max(1, (docSize.cy + pt.x - 1)/pt.x); pInfo->SetMaxPage(nMaxPage);

CString tempString; tempString.Format("총 %d 페이지 중 %%d 페이지 \n총 %d 페이지 중 %%d-%%d 페이지 ",nMa

xPage, nMaxPage); pInfo->m_strPageDesc = tempString; } 한 페이지 모드일

때 나갈 문자열

두 페이지 모드일 때 나갈 문자열분리자

Page 352: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

분리 윈도우분리 윈도우

Page 353: Windows Programming

MFC Tutorial 353

ISLab ICE HUFSISLab ICE HUFS

목차목차

• 분리 윈도우• 동적 분리 윈도우• 정적 분리 윈도우

Page 354: Windows Programming

MFC Tutorial 354

ISLab ICE HUFSISLab ICE HUFS

정적 동적 분리 윈도우정적 동적 분리 윈도우 (1)(1)

동적 분리 윈도우 정적 분리 윈도우

Page 355: Windows Programming

MFC Tutorial 355

ISLab ICE HUFSISLab ICE HUFS

정적 동적 분리 윈도우정적 동적 분리 윈도우 (2)(2)

Page 356: Windows Programming

MFC Tutorial 356

ISLab ICE HUFSISLab ICE HUFS

분리 윈도우의 구현분리 윈도우의 구현

• CSplitterWnd 클래스를 이용– 다음 클래스의 member data 로 존재

• CFrameWnd• CMDIChildWnd

Page 357: Windows Programming

MFC Tutorial 357

ISLab ICE HUFSISLab ICE HUFS

동적 분리 윈도우의 구현동적 분리 윈도우의 구현class CChildWnd : public CMDIChildWnd{ DECLARE_DYNCREATE(CChildFrame)public: CChildFrame();

// Attributespublic: CSplitterWnd m_wndSplitter;

// Operationspublic:

// Overrides // ClassWizard generated virtual function overrides // {{AFX_VIRTUAL(CChildFrame) virtual BOOL PreCreateWindow(CREATESTRUCT& cs); ....

Page 358: Windows Programming

MFC Tutorial 358

ISLab ICE HUFSISLab ICE HUFS

자식 윈도우 생성시자식 윈도우 생성시

• 최대 4 개의 동적 분리 윈도우 생성 가능

BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext){ return m_wndSplitter.Create(this, 2, 2, CSize(10, 10), pContext);}

분리 윈도우의 행갯수

분리 윈도우의 열갯수

동적 분리윈도우의창의

최소 크기

Page 359: Windows Programming

MFC Tutorial 359

ISLab ICE HUFSISLab ICE HUFS

분리 윈도우의 크기 변경분리 윈도우의 크기 변경

• 프로그램에서 변경시– SetColumnInfo,SetRowInfo 함수를 이용하여 크기 변경

void GetRowInfo( int row, int& cyCur, int& cyMin );void GetColumnInfo( int col, int& cxCur, int& cxMin );void SetRowInfo( int row, int cyIdeal, int cyMin );void SetColumnInfo( int col, int cxIdeal, int cxMin );

Page 360: Windows Programming

MFC Tutorial 360

ISLab ICE HUFSISLab ICE HUFS

pContextpContext

struct CCreateContext{ m_pNewViewClass // 생성하고자 하는 새로운 뷰의 CRuntimeClass m_pCurrentDoc // 새로 생성한 뷰가 연관된 이미 존재하는 도큐먼트 객체 m_pNewDocTemplate // 새로운 MDI 프레임 윈도우의 생성과 연관된 // 도큐먼트 템플릿 m_pLastView // 이미 존재하는 뷰 m_pCurrentFrame // 현재 생성하고 있는 프레임 윈도우

Page 361: Windows Programming

MFC Tutorial 361

ISLab ICE HUFSISLab ICE HUFS

다른 윈도우에 갱신이 안 되는 경우다른 윈도우에 갱신이 안 되는 경우

Page 362: Windows Programming

MFC Tutorial 362

ISLab ICE HUFSISLab ICE HUFS

OnLButtonUp OnLButtonUp 코드 수정코드 수정

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point) {

if (GetCapture() == this){

CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCapture();

CObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_objectList.AddTail(m_pCurDrawObject); pDoc->SetModifiedFlag(TRUE); pDoc->UpdateAllViews(this);

}}

자신의 문서 내용을 출력하고 있는 모든 뷰에게 내용을 다시 그리라고 하는데 사용하는 함수

Page 363: Windows Programming

MFC Tutorial 363

ISLab ICE HUFSISLab ICE HUFS

UpdateAllViewsUpdateAllViews

• CDocument 클래스의 멤버 함수• 자신의 문서 내용을 출력하고 있는 모든 뷰에게 내용을

다시 그리라고 하는데 사용• void UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHi

nt = NULL);– pSender : 도큐먼트를 변경한 뷰 , NULL 이면 모든 뷰 갱신– lHint : 변경 정보– pHint : 변경과 관계된 객체에 대한 포인터

• CView 클래스의 OnUpdate 함수 호출

Page 364: Windows Programming

MFC Tutorial 364

ISLab ICE HUFSISLab ICE HUFS

OnUpdateOnUpdate

• UpdateAllView 는 각 뷰 클래스의 OnUpdate 함수 호출– 각각의 OnUpdate 함수는 Invalidate 를 호출하여 윈도우 영역

전체를 다시 그린다 .– 이를 방지하기 위해 수정해야 한다 . 즉 OnUpdate 에 갱신된

정보를 포함하여 이 정보에 따라 그림을 수정해야 함

• 예제에서 OnUpdate 가 불리는 경우– 새로운 객체를 삽입하였을 때 객체 삽입을 알려주어야 할 때– 배율 설정시에 모든 뷰에 배율이 변경되었다는 것을 알려주어야

할 때

Page 365: Windows Programming

MFC Tutorial 365

ISLab ICE HUFSISLab ICE HUFS

분리 윈도우의 배율의 불일치분리 윈도우의 배율의 불일치

Page 366: Windows Programming

MFC Tutorial 366

ISLab ICE HUFSISLab ICE HUFS

OnUpdate OnUpdate 함수 정의함수 정의

void CObeditView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { if (pSender == this) return;

switch(lHint) { case 1 : { CClientDC dc(this); OnPrepareDC(&dc); ((CDrawObject *)pHint)->DrawObject(&dc); break; } case 2 : { SetZoomFactor(((CObeditView *)pSender)->m_zoomRatio); Invalidate(); break; } } }

새로운 객체 추가

한 뷰에서 다른뷰로 배율을 전파

Page 367: Windows Programming

MFC Tutorial 367

ISLab ICE HUFSISLab ICE HUFS

UpdateAllViews UpdateAllViews 호출 수정호출 수정 (1)(1)

void CObeditView::OnLButtonUp(UINT nFlags, CPoint point) {

if (GetCapture() == this){

CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point);

m_pCurDrawObject->SetEndPoint(point); m_pCurDrawObject->DrawObject(&dc); ReleaseCapture();

CObeditDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_objectList.AddTail(m_pCurDrawObject); pDoc->SetModifiedFlag(TRUE); pDoc->UpdateAllViews(this, 1, m_pCurDrawObject);

}}

삽입된 객체

객체 사입

Page 368: Windows Programming

MFC Tutorial 368

ISLab ICE HUFSISLab ICE HUFS

UpdateAllViews UpdateAllViews 호출 수정호출 수정 (2)(2)

void CObeditView::OnViewZoom() { CZoomDlg zoomDlg(this);

zoomDlg.m_editZoom = m_zoomRatio; if (zoomDlg.DoModal() != IDOK) return; m_zoomRatio = zoomDlg.m_editZoom; SetZoomFactor(zoomDlg.m_editZoom); GetDocument()->UpdateAllViews(this, 2); Invalidate(); }

배율 변경

Page 369: Windows Programming

MFC Tutorial 369

ISLab ICE HUFSISLab ICE HUFS

CMyToolBar::OnHScroll CMyToolBar::OnHScroll 수정수정

void CMyToolBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { int nMin, nMax;

m_zoomScroll.GetScrollRange(&nMin, &nMax); int nOldPos, nCurPos = m_zoomScroll.GetScrollPos(); nOldPos = nCurPos; switch(nSBCode) .... // set zoom ratio to view window CMDIChildWnd* pChildFrame = (CMDIChildWnd *) (((CMDIFrameWnd *)AfxGetMainWnd())->MDIGetActive()); CObeditView *pView = (CObeditView *)pChildFrame->GetActiveView(); pView->SetZoomFactor(nCurPos); pView->GetDocument()->UpdateAllViews(pView, 2); pView->Invalidate();}

배율 변경

Page 370: Windows Programming

MFC Tutorial 370

ISLab ICE HUFSISLab ICE HUFS

정적 분리 윈도우정적 분리 윈도우

• 프레임 클래스의 OnCreateClient 함수를 오버라이드 해서 구현

• 서로 다른 뷰를 가지도록 만든다 .

Page 371: Windows Programming

MFC Tutorial 371

ISLab ICE HUFSISLab ICE HUFS

OnCreateClient OnCreateClient 함수함수BOOL CMyFrame::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext){ // 먼저 가로로 두 개의 정적윈도우를 만들 것임을 알린다 . if (!m_wndSplitter.CreateStatic(this, 1, 2); return FALSE;

// 첫번째 정적 윈도우를 생성한다 . 이 윈도우는 템플릿에 등록된 뷰 클래스이다 . if (!m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, CSize(130, 50), pContext)) return FALSE;

// 두번째 정적 윈도우를 생성한다 . 이 윈도우는 CInputView 클래스이다 . if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CInputView), CSize(0, 0), pContext)) return FALSE;

// 두번째 뷰를 활성화한다 . SetActiveView((CView*)m_wndSplitter.GetPane(0, 1);

return TRUE;}

Page 372: Windows Programming

MFC Tutorial 372

ISLab ICE HUFSISLab ICE HUFS

세개의 정적 분리 윈도우 생성세개의 정적 분리 윈도우 생성

Page 373: Windows Programming

MFC Tutorial 373

ISLab ICE HUFSISLab ICE HUFS

세 개의 정적 분리윈도우의 구현세 개의 정적 분리윈도우의 구현if (!m_wndSplitter1.CreateStatic(this, 1, 2)) return FALSE;

if (!m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CFileTreeView), CSize(100,100), pContext)) return FASLE;

if (!m_wndSplitter2.CreateStatic(&m_wndSplitter1, 2, 1, WS_CHILD | WS_VISIBLE | WS_BORDER, m_wndSplitter1.IdFromRowCol(0,1))) return FALSE;

if (!m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CListView), CSize(100, 150), pContext)) return FALSE;

if (!m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CTextView), CSize(100, 120), pContext)) return FALSE;

SetActiveView((CView*)m_wndSplitter2.GetPane(0, 0));

Page 374: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

MFC MFC 디버깅 매크로와 디버깅 매크로와 예외 처리예외 처리

Page 375: Windows Programming

MFC Tutorial 375

ISLab ICE HUFSISLab ICE HUFS

목차목차

• 메시지 출력• ASSERT 매크로• 오브젝트의 유효성 검사• 예외 처리

Page 376: Windows Programming

MFC Tutorial 376

ISLab ICE HUFSISLab ICE HUFS

컴파일 옵션컴파일 옵션

• Debug 모드– _DEBUG

• Release 모드– NODEBUG

Page 377: Windows Programming

MFC Tutorial 377

ISLab ICE HUFSISLab ICE HUFS

디버그 모드로 수행디버그 모드로 수행

Page 378: Windows Programming

MFC Tutorial 378

ISLab ICE HUFSISLab ICE HUFS

디버깅 모드로 수행디버깅 모드로 수행

• 한 문장씩 수행• 함수 안으로 들어가 수행• 수행중인 함수밖으로• 커서 위치까지 수행• Call Stack

Page 379: Windows Programming

MFC Tutorial 379

ISLab ICE HUFSISLab ICE HUFS

TRACE TRACE 매크로매크로

• 디버그 창으로 메시지 출력• 디버그 모드로 컴파일할 때만 수행

TRACE(“Sample TRACE Output : %d == 0x%x\n”, i, i);

Page 380: Windows Programming

MFC Tutorial 380

ISLab ICE HUFSISLab ICE HUFS

ASSERT ASSERT 매크로매크로

• 어떤 조건을 검사하여 거짓이면 그 위치 (파일 이름과 행번호 ) 를 출력하는데 사용

• 주로 프로그램 개발 기간 중에 함수의 인자로 들어온 값이 맞게 들어왔는지의 여부를 판단하는데 사용

• 디버그 모드로 컴파일 시에만 수행

ASSERT(prt != NULL);

Page 381: Windows Programming

MFC Tutorial 381

ISLab ICE HUFSISLab ICE HUFS

VERIFY VERIFY 매크로매크로

• ASSERT 매크로와 동일• 단 , 디버그 모드가 아닌 Release 모드로 컴파일 시에도

수행

VERIFY(LoadAccelTable(hWnd, “MainWnd”));

Page 382: Windows Programming

MFC Tutorial 382

ISLab ICE HUFSISLab ICE HUFS

오브젝트의 유효성 검사오브젝트의 유효성 검사

• CObject 클래스의 후손에만 적용• AssertValid

– 현재 오브젝트의 데이터멤버가 올바른 값을 갖고 있는지의 여부를 검사

• Dump– 현재 오브젝트의 데이터멤버를 출력하는데 사용

• 디버그 모드에서만 수행– _DEBUG

Page 383: Windows Programming

MFC Tutorial 383

ISLab ICE HUFSISLab ICE HUFS

AssertValidAssertValid

class CHorzLine : public CObject{ CPoint m_ptStart, m_ptEnd; ....#ifdef _DEBUG void AssertValid() const; void Dump(CDumpContext& dc) const;#endif};

void CHorzLine::AssertValid() const{ CObject::AssertValid(); // 먼저 선조 클래스의 유효성을 검사한다 . ASSERT(m_ptStart.y == m_ptEnd.y);}

Page 384: Windows Programming

MFC Tutorial 384

ISLab ICE HUFSISLab ICE HUFS

DumpDump

void CHorzLine::Dump(CDumpContext& dc) const{ CObject::Dump(dc); // 먼저 선조클래스의 데이터멤버를 호출한다 . dc << “X : “ << (WORD)m_ptStart.x << “ Y : “ << (WORD)m_ptStart.y << “\n”; dc << “Y : “ << (WORD)m_ptEnd.x << “ Y : “ << (WORD)m_ptEnd.y << “\n”;}

void f(){ CHorzLine* pLine = new CHorzLine; ....#ifdef _DEBUG pLine->Dump(afxDump);#endif ....

afxDump 는 CDumpContext 타입의 전역 변수 . 출력이 윈도우의 Debug 탭으로 출력

Page 385: Windows Programming

MFC Tutorial 385

ISLab ICE HUFSISLab ICE HUFS

예외처리예외처리

체크 되어야

Page 386: Windows Programming

ISLab ICE HUFSISLab ICE HUFS

공통 컨트롤공통 컨트롤 (Common Control)(Common Control)

Page 387: Windows Programming

MFC Tutorial 387

ISLab ICE HUFSISLab ICE HUFS

목차목차

• Common Control 의 종류• Control Message 처리• Animation Control• Progress Control• Slider Control• List Control• Tree Control

Page 388: Windows Programming

MFC Tutorial 388

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 종류의 종류 (1)(1)

• CAnimateCtrl• CHeaderCtrl

• CHotKeyCtrl• CImageList• CListCtrl

Page 389: Windows Programming

MFC Tutorial 389

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 종류의 종류 (2)(2)

• CProgressCtrl

• CRichEditCtrl– OLE 복합문서 컨테이너

Page 390: Windows Programming

MFC Tutorial 390

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 종류의 종류 (3)(3)

• CSliderCtrl

• CSpinButtonCtrl

• CStatusBarCtrl

• CTabCtrl

Page 391: Windows Programming

MFC Tutorial 391

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 종류의 종류 (4)(4)

• CToolBarCtrl

• CToolTipCtrl

• CDragListBox• CCheckListBox

Page 392: Windows Programming

MFC Tutorial 392

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 종류의 종류 (5)(5)

• CTreeCtrl

Page 393: Windows Programming

MFC Tutorial 393

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control

• Common contorl 의 code 는 윈도우의 system\COMCTL32.DLL 에 있다 .– 각 컨트롤에 대한 윈도우 프로시저– 각 컨트롤을 위한 윈도 클래스를 등록하는 코드가 포함– 등록 코드는 DLL 이 로드될 때 호출– 다이얼로그를 초기화할 때 프로그램에서는 다이얼로그

리소스에서 기호 클래스 이름을 사용해서 DLL 에 있는 윈도 프로시저를 연결

– 이렇게 함으로써 프로그램에서는 컨트롤의 윈도를 소유하게 되지만 , 코드는 DLL 에 존재

• 공통 컨트롤은 Class Wizard 가 멤버 변수를 제공하지 않음

• 공통 컨트롤들로부터 통지 메시지들을 매핑하는 일에는 Class Wizard 를 이용할 수 있다 .

Page 394: Windows Programming

MFC Tutorial 394

ISLab ICE HUFSISLab ICE HUFS

Common ControlCommon Control 의 사용의 사용

• Common control 역시 컨트롤이기 때문에 dialog box에서 사용할 수 있다 .

• 보통 윈도우의 자식 윈도우로 존재할 수 있다 .

Page 395: Windows Programming

MFC Tutorial 395

ISLab ICE HUFSISLab ICE HUFS

Dialog BoxDialog Box 에서 사용에서 사용 (1)(1)

Progress Control

Slider Control

Tree ControlHotkey Control

Tap Control

Animation Control

Spin Control

List Control

Page 396: Windows Programming

MFC Tutorial 396

ISLab ICE HUFSISLab ICE HUFS

Dialog BoxDialog Box 에서 사용에서 사용 (2)(2)

• Resource view 에 있는 control palette 이용• 없는 것은 데이터 멤버로 만들어 놓은 다음

WM_INITDIALOG 메시지가 왔을 때 Create 같은 멤버함수를 이용해 직접 생성

• Class wizard 를 이용해 dialog box template 에 해당하는 dialog class 생성

• Add Member Variable 버튼을 택하여 common control 에 해당하는 데이터 멤버를 만듦– 강제적으로 Category 가 CONTROL 이 된다 .

Page 397: Windows Programming

MFC Tutorial 397

ISLab ICE HUFSISLab ICE HUFS

일반윈도우의 자식윈도우로 사용시일반윈도우의 자식윈도우로 사용시• 각 common control 클래스의 오브젝트를 정의• 각 컨트롤의 Create 함수를 이용해 컨트롤 생성• Common control 을 dialog template 에 만들어 놓으면 알아서

생성되기 때문에 직접 common control 클래스의 Create 멤버함수를 불러줄 필요가 없다 .

class CMyView : public CView{ .... CProgressCtrl m_progressBar; ....};

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct){ if (CView::OnCreate(lpCreateStruct) == -1) .... m_progressBar.Create(...); ....

Page 398: Windows Programming

MFC Tutorial 398

ISLab ICE HUFSISLab ICE HUFS

Notification Message Notification Message 처리처리

• Control 은 자신에게 무슨 일이 발생하면 부모 윈도우에게 알려준다 .– Control 이 dialog box 에서 사용된 경우라면 이 때 부모윈도우는

dialog box 가 된다 .

Page 399: Windows Programming

MFC Tutorial 399

ISLab ICE HUFSISLab ICE HUFS

Notification MessageNotification Message

• WM_COMMAND– 원래의 window control 들이 이용– 표준 32비트 wParam, lParam 메시지 파라미터는 common con

trol 이 부모에게 보내는 정보를 위해 사용하기에는 부적절

• WM_NOTIFY– wParam 은 control ID– lParam 은 control 에 의해 운영되는 NMHDR 구조체

포인터이거나 이를 포함하는 더 큰 구조체

Page 400: Windows Programming

MFC Tutorial 400

ISLab ICE HUFSISLab ICE HUFS

NMHDRNMHDR

typedef struct tagNMHDR { HWND hwndFrom; // 메시지를 보내는 control handle UINT idFrom; // 메시지를 보내는 control ID UINT code; // control- 특성적인 notification code} NMHDR;

• code 로 들어오는 notification code 에는 모든 common control 에 공통되는 것과 common control 에 따라 달라지는 것 두 종류가 존재

Page 401: Windows Programming

MFC Tutorial 401

ISLab ICE HUFSISLab ICE HUFS

공통되는 공통되는 Notification CodeNotification Code

NM_CLICK 컨트롤을 좌측 마우스 버튼으로 클릭했을 때NM_DBCLICK 컨트롤을 좌측 마우스 버튼으로 더블 클릭했을 때

NM_RCLICK 컨트롤을 우측 마우스 버튼으로 클릭했을 때NM_RDBCLICK 컨트롤을 우측 마우스 버튼으로 더블 클릭했을 때

NM_RETURN 컨트롤이 입력 포커스를 갖고 있을 때 리턴키를 친 경우

NM_SETFOCUS 컨트롤에 입력 포커스가 갈 때NM_KILLFOCUS 컨트롤이 입력 포커스를 잃을 때NM_OUTOFMEMORY 메모리가 부족해서 하던 일을 끝내지 못할 때

Page 402: Windows Programming

MFC Tutorial 402

ISLab ICE HUFSISLab ICE HUFS

다양한 다양한 Notification Code StructureNotification Code Structure

• 툴팁 컨트롤– NMHDR 스트럭처만을 그대로 이용

• 트리뷰 컨트롤– 한 항목을 선택하면 TVN_SELCHANGING라는 알림코드를 갖는

다 . WM_NOTIFY 메시지 발생 . 이때 lParam 은 NM_TREEVIEW 스트럭처를 갖는다 .

typedef struct _NM_TREEVIEW{ NMHDR hdr; UINT action; TV_ITEM itemNew; TV_ITEM itemOld; POINT ptDrag;} NM_TREEVIEW;

Page 403: Windows Programming

MFC Tutorial 403

ISLab ICE HUFSISLab ICE HUFS

Message MapMessage Map 에서의 에서의 Notification Notification MessageMessage

• ON_NOTIFY 매크로 사용– ON_NOTIFY(wNotifyCode, ctrlID, memberFn)– ctrlID 를 공통 컨트롤 ID 로 갖는 공통컨트롤로부터 wNotifyCo

de 라는 알림코드가 오면 memberFn 이라는 처리함수를 불러달라는 것

– void memberFn(NMHDR* pNotifyStruct, LRESULT* result);

공통 컨트롤에따라 달라진다 .

처리 결과를 돌려준다 .처리했으면 0 을 리턴

Page 404: Windows Programming

MFC Tutorial 404

ISLab ICE HUFSISLab ICE HUFS

Message Map MacroMessage Map Macro

• ON_NOTIFY_RANGE, ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE– 동일한 종류의 여러 control 로부터 오는 notification code 를

처리하고자 할 때– 매번 처리함수를 따로 만들지 않고 하나의 처리함수를 정의해 사용

Page 405: Windows Programming

MFC Tutorial 405

ISLab ICE HUFSISLab ICE HUFS

Notification Code Notification Code 처리 예처리 예

• List control 에서 사용자가 선택하는 항목이 달라질 때

BEGIN_MESSAGE_MAP(....)....ON_NOTIFY(LVN_ITEMCHANGED, IDC_LISTCTRL, OnListCtrlClick)....END_MESSAGE_MAP()

void CCmmCtrlView::OnListCtrlClick(NMHDR* pNotifyStruct, LRESULT* result){ NM_LISTVIEW* pListView = (NM_LISTVIEW *)pNotifyStruct; // 자신의 용도에 맞게 적절히 처리한다 . .... *result = 0;}

적절한 타입으로캐스팅 하여 사용

Page 406: Windows Programming

MFC Tutorial 406

ISLab ICE HUFSISLab ICE HUFS

Message ReflectionMessage Reflection

• Notification message 를 부모 윈도우로 보냈을 때 처리가 안 되었다면 이를 다시 컨트롤로 보내 자체에서 처리가 되도록 하는 기능

• MFC 4.0에서 새로 제공해주는 기능• 부모 윈도우의 의존성에서 벗어나 나름대로의 동작 방식을 더 가질 수 있게 됨

• Message Reflection 의 경우 컨트롤 자체의 message map 에 등록해야– ON_NOTIFY_REFLECT 매크로 사용

ON_NOTIFY_REFLECT(wNotifyCode, memberFn)

Page 407: Windows Programming

MFC Tutorial 407

ISLab ICE HUFSISLab ICE HUFS

예제예제

• 프로젝트 이름 : CmmCtrl• SDI• 데이터베이스 옵션은 주지 않음• Toolbar, status bar, 프린트 관련 옵션도 선택 않음

Page 408: Windows Programming

MFC Tutorial 408

ISLab ICE HUFSISLab ICE HUFS

메뉴 구성메뉴 구성Common Control Help Animate ID_COMM_ANIMATE Image List ID_COMM_IMAGE Slider ID_COMM_SLIDER Progress ID_COMM_PROGRESS Tree ID_COMM_TREE List ID_COMM_LIST ------------ Exit

Page 409: Windows Programming

MFC Tutorial 409

ISLab ICE HUFSISLab ICE HUFS

Control ID Control ID 생성생성// CmmCtrlView.cpp

#define IDC_ANIMATE 200 // Animation control ID#define IDC_PROGRESS 201 // Progress control ID#define IDC_SLIDER 202 // Slider control ID#define IDC_LISTCTRL 203 // List control ID#define IDC_TREECTRL 204 // Tree control ID

• Resource Symbol 을 이용해도 됨

Page 410: Windows Programming

MFC Tutorial 410

ISLab ICE HUFSISLab ICE HUFS

컨트롤 멤버데이터 정의컨트롤 멤버데이터 정의

• CCmmCtrlView 클래스에 정의 CAnimateCtrl m_wndAnimateCtrl; // Animation control CImageList m_wndImageList; // Image list 1 CImageList m_wndSmallImageList; // Image list 2 CSliderCtrl m_wndSliderCtrl; // Slider control CProgressCtrl m_wndProgressCtrl; // Progress control CListCtrl m_wndListCtrl; // List control CTreeCtrl m_wndTreeCtrl; // Tree control HTREEITEM m_treeRoot; // Tree control 에서 사용된다 . // 루트 항목을 가리킨다 . BOOL m_bListCtrl; // List control 의 생성여부 BOOL m_bTreeCtrl; // Tree control 의 생성여부 BOOL m_bSlider; // Slider control 의 생성여부

Page 411: Windows Programming

MFC Tutorial 411

ISLab ICE HUFSISLab ICE HUFS

남아있는 객체 삭제를 위한 함수남아있는 객체 삭제를 위한 함수void CCmmCtrlView::CheckWnd(){ if (m_bListCtrl) // List control 이 있으면 없앤다 . { m_wndImageList.DeleteImageList(); m_wndSmallImageList.DeleteImageList(); m_wndListCtrl.DestroyWindow(); m_bListCtrl = FALSE; } else if (m_bTreeCtrl) // Tree control 이 있으면 없앤다 . { m_wndImageList.DeleteImageList(); m_wndTreeCtrl.DestroyWindow(); m_bTreeCtrl = FALSE; } else if (m_bSlider) { m_wndSliderCtrl.DestroyWindow(); m_bSlider = FALSE; }}

Page 412: Windows Programming

MFC Tutorial 412

ISLab ICE HUFSISLab ICE HUFS

CCmmCtrlViewCCmmCtrlView 의 생성자의 생성자 // 소멸자 변경소멸자 변경

CCmmCtrlView::CCmmCtrlView(){ m_bListCtrl = FALSE; m_bTreeCtrl = FALSE; m_bSlider = FALSE;}

CCmmCtrlView::~CCmmCtrlView(){ CheckWnd();}

Page 413: Windows Programming

MFC Tutorial 413

ISLab ICE HUFSISLab ICE HUFS

Animation ControlAnimation Control

• AVI 파일을 디스플레이• 오디오가 있는 파일은 지원안 함• 즉 하나의 Video Stream 만 있는 avi file 만 지원• 오디오를 지원하는 클래스 : OLE 컨트롤 중

마이크로소프트 멀티미디어 컨트롤

Page 414: Windows Programming

MFC Tutorial 414

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_ANIMATEID_COMM_ANIMATE

void CCmmCtrlView::OnCommAnimate() { CheckWnd(); // 이 함수의 용도는 앞에서 설명하였다 . // AVI 파일을 입력받기 위한 다이얼로그를 띄운다 . CFileDialog dlg( TRUE,_T("AVI"),_T("*.AVI"), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T("Animation (*.AVI)|*.AVI|")); if (dlg.DoModal() != IDOK) // 사용자가 취소한 경우는 return; // 그대로 끝낸다 .

CString strFileName = dlg.GetPathName(); // AVI 파일 이름을 저장한다 . CRect rectAnimateCtrl; GetClientRect(&rectAnimateCtrl); //뷰의 위치를 얻어둔다 . // 애니메이트 컨트롤을 생성한다 . m_wndAnimateCtrl.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ACS_CENTER, rectAnimateCtrl, this, IDC_ANIMATE); m_wndAnimateCtrl.Open(strFileName); InvalidateRect(NULL); UpdateWindow();

m_wndAnimateCtrl.Play(0,0xFFFF,1); // }

Page 415: Windows Programming

MFC Tutorial 415

ISLab ICE HUFSISLab ICE HUFS

Animation ControlAnimation Control 의 속성의 속성

ACS_CENTER 애니메이션 컨트롤의 중앙에서 AVI 파일을 플레이

한다 . 이 스타일이 주어지지 않으면 AVI 파일의크기에 맞춰 애니메이션 컨트롤의 크기가

변경된다위의 예에서 바로 이 스타일을 사용하였다 .

ACS_TRANSPARENT AVI 파일의 배경색 대신에 원래 애니메이션 컨트롤의 자리에 있던 배경색을 사용한다 .

ACS_AUTOPLAY AVI 파일이 오픈됨과 동시에 플레이되도록 하며플레이가 계속 반복되도록 한다 .

Page 416: Windows Programming

MFC Tutorial 416

ISLab ICE HUFSISLab ICE HUFS

CAnimateCtrlCAnimateCtrl 의 멤버 함수의 멤버 함수

Open AVI 파일이나 리소스를 읽어들여 첫 프레임을 윈도우에 표시한다 .Play AVI 클립을 플레이한다 .

첫번째 인자와 두번째 인자가 플레이할 프레임을 지칭시작 프레임일 경우 0을 마지막 프레임일 경우 -1(0xFFFF)마지막 인자는 반복횟수

Seek AVI 클립의 지정된 프레임을 윈도우에 표시한다 .Stop AVI 클립의 표시를 중단한다 .Close 오픈된 AVI 클립을 닫아 버린다 .

Page 417: Windows Programming

MFC Tutorial 417

ISLab ICE HUFSISLab ICE HUFS

Animation ControlAnimation Control 의 의 Notification CodeNotification Code

ACN_START AVI 클립의 플레이가 시작되었음을 알린다 .ACN_STOP AVI 클립의 플레이가 다 끝났음을 알린다 .

• WM_COMMAND 메시지 발생• ON_CONTROL 매크로 사용

Page 418: Windows Programming

MFC Tutorial 418

ISLab ICE HUFSISLab ICE HUFS

Notification Code Notification Code 처리함수처리함수BEGIN_MESSAGE_MAP(CCmmCtrlView, CView)

//{{AFX_MSG_MAP(CCmmCtrlView)ON_COMMAND(ID_COMM_ANIMATE, OnCommAnimate)ON_COMMAND(ID_COMM_IMAGE, OnCommImage)

....//}}AFX_MSG_MAP

ON_CONTROL(ACN_STOP, IDC_ANIMATE, OnAnimateStop)END_MESSAGE_MAP()

void CCmmCtrlView::OnAnimateStop(){ AfxMessageBox("AVI 방영 (?) 이 끝났습니다 ."); m_wndAnimateCtrl.Close(); m_wndAnimateCtrl.DestroyWindow(); InvalidateRect(NULL);}

Page 419: Windows Programming

MFC Tutorial 419

ISLab ICE HUFSISLab ICE HUFS

Image ListImage List

• Mask bitmap• 윈도우가 아님• BOOL Create(int cx, int cy, BOOL bMask, int nInitial, int nGrow);– cx, cy ; 픽셀 단위로 각 이미지의 크기– bMask : mask image 를 사용할 것인지의 여부– nInitial : 처음 이미지 리스트가 생성될 때 이미지 리스트에

들어갈 이미지의 개수– nGrow : 이미지 리스트의 크기가 변할 때 쓰이는 단위

Page 420: Windows Programming

MFC Tutorial 420

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_IMAGE(1)ID_COMM_IMAGE(1)

void CCmmCtrlView::OnCommImage() { CheckWnd();

m_wndImageList.Create(32, 32, TRUE, 2, 2);

CBitmap bitmap, bitmap2, bitmap3, bitmap4, bitmap5; bitmap3.LoadBitmap(IDB_BITMAP3); // Load mask bitmap bitmap.LoadBitmap(IDB_BITMAP1); m_wndImageList.Add(&bitmap, (CBitmap *)&bitmap3); bitmap2.LoadBitmap(IDB_BITMAP2); m_wndImageList.Add(&bitmap2, (CBitmap *)&bitmap3);

CClientDC dc(this); CPoint pt; for(int i = 0;i < m_wndImageList.GetImageCount();i++) { pt.x = 100 + 32*i; pt.y = 100; m_wndImageList.Draw(&dc, i, pt, ILD_NORMAL);

Page 421: Windows Programming

MFC Tutorial 421

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_IMAGE(2)ID_COMM_IMAGE(2)

pt.y += 50; m_wndImageList.Draw(&dc, i, pt, ILD_BLEND50);

pt.y += 50; m_wndImageList.Draw(&dc, i, pt, ILD_BLEND25); } m_wndImageList.DeleteImageList();}

IDB_BITMAP1

IDB_BITMAP2

IDB_BITMAP3

Page 422: Windows Programming

MFC Tutorial 422

ISLab ICE HUFSISLab ICE HUFS

Image ListImage List 의 멤버 함수의 멤버 함수 (1)(1)

GetImageCount Image list 에 들어있는 image 의 개수SetBkColor Image list 의 image 의 배경색을 설정 . Mask

image list 의 경우에는 CLR_NONE을 주면 Mask를

갖고 그리기 때문에 원래 배경이 보존된다GetBkColor 현재 image list 의 image 의 배경색을 얻어온다GetImageInfo 현재 image list 의 image 에 대한 정보를 얻음DeleteImageList Image list 를 삭제한다Add 새로운 image 를 image list 에 추가한다 .Remove Image list 에서 image 를 삭제한다 .Replace Image list 에서 한 image 를 다른 image 로 변경Extraction Image list 의 image 를 icon handle 로 만들려는

경우에 사용Read Image 를 파일에서 읽어 image list 에 추가Write Image 를 image list 에서 읽어 파일에 추가

Page 423: Windows Programming

MFC Tutorial 423

ISLab ICE HUFSISLab ICE HUFS

Image ListImage List 의 멤버 함수의 멤버 함수 (2)(2)

Draw Image list 의 image 를 윈도우 위에 출력한다 .SetOverlayImage Image list 의 image 를 overlay image list 에

추가한다 . Image list 당 4개까지의 image 를overlay mask 로 사용할 수 있다 .

Page 424: Windows Programming

MFC Tutorial 424

ISLab ICE HUFSISLab ICE HUFS

Draw Draw 함수함수BOOL Draw(CDC* pdc, int nImage, POINT pt, UINT nStyle);

IDL_NORMAL Image list 에 지정된 배경색을 갖고 이미지를출력한다 . Mask image list 의 경우에는 배경이보존된 채 출력이 이루어진다 .

IDL_TRANSPARENT 지정된 배경색에 관계없이 배경을 유지한 채 image 를출력하는데 마스크된 image 에만 적용 가능한 옵션

IDL_BLEND50 주어진 image 가 선택되었음을 나타내기 위해 시스템하이라이트 색상으로 혼합한 다음에 출력한다 .

IDL_BLEND25 주어진 image 가 입력포커스를 갖고 있음을 나타내며출력한다 .

IDL_OVERLAYMASK 주어진 image 를 그리고 그 위에 이 스타일과 함께지정된 overlay mask 를 그린다 . Overlay mask지정은 INDEXTOOVERLAYMASK macro 를 통해 이루어진다 . 연산자를 이용해 이 스타일과 함께

지정해준다 .

Page 425: Windows Programming

MFC Tutorial 425

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_PROGRESS(1)ID_COMM_PROGRESS(1)

void CCmmCtrlView::OnCommProgress() { CheckWnd(); InvalidateRect(NULL);

CRect rect; // Progress control 의 위치를 지정한다 rect.left = rect.top = 100; rect.right = 400; rect.bottom = 150; // Progress control 을 생성한다 m_wndProgressCtrl.Create(WS_CHILD|WS_VISIBLE|WS_BORDER,rect, this,IDC_PROGRESS); m_wndProgressCtrl.SetRange(0, 100); // 진행범위를 지정한다 . m_wndProgressCtrl.SetPos(0); // 초기위치를 지정한다

Page 426: Windows Programming

MFC Tutorial 426

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_PROGRESS(2)ID_COMM_PROGRESS(2)

for(int i = 1;i <= 10; i++) { ::Sleep(100); // 0.1 초간 쉰다 . m_wndProgressCtrl.SetPos(i*10); // 10 만큼씩 진행한다 . } AfxMessageBox("Progress Bar 의 끝에 도달했군요 ."); m_wndProgressCtrl.DestroyWindow(); InvalidateRect(NULL);}

Page 427: Windows Programming

MFC Tutorial 427

ISLab ICE HUFSISLab ICE HUFS

Progress ControlProgress Control 의 멤버함수의 멤버함수SetRange Progress bar 의 범위값을 지정하고 그에 맞추어 다시 그림SetPos Progress bar 의 현재 위치를 지정하고 그에 맞추어 다시 그림OffsetPos Progress bar 의 현재 위치를 주어진 값만큼 보정하고 다시 그림SetStep Progress bar 의 진행 단위를 지정한다 . StepIt 함수에서

사용한다 .StepIt Progress bar 의 현재 위치를 SetStep 에서 지정된 값만큼

진행시킨다 .

Page 428: Windows Programming

MFC Tutorial 428

ISLab ICE HUFSISLab ICE HUFS

Slider ControlSlider Control

• 불연속적인 값이나 어떤 범위의 값을 입력받고자 할 때• WM_HSCROLL(혹은 WM_VSCROLL) 로 특이하게 notifica

tion code 를 발생시킨다 .

Page 429: Windows Programming

MFC Tutorial 429

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_SLIDERID_COMM_SLIDER

void CCmmCtrlView::OnCommSlider() { CheckWnd(); InvalidateRect(NULL);

CRect rect; rect.SetRect(100, 100, 300, 200); m_wndSliderCtrl.Create(WS_VISIBLE|WS_CHILD |TBS_HORZ|TBS_BOTH|TBS_AUTOTICKS, rect, this, IDC_SLIDER); m_wndSliderCtrl.SetTicFreq( 2 ); // Set the interval of tick count m_wndSliderCtrl.SetLineSize( 2 ); // Set the size of line movement m_wndSliderCtrl.SetPageSize( 4 ); // Set the size of page movement m_wndSliderCtrl.SetRange( 0, 12, TRUE );

m_wndSliderCtrl.SetPos(0);}

Page 430: Windows Programming

MFC Tutorial 430

ISLab ICE HUFSISLab ICE HUFS

Slider ControlSlider Control 의 윈도우 스타일의 윈도우 스타일TBS_HORZ 수평 slider control 을 만든다 . 이것이 디폴트이다 .TBS_VERT 수직 slider control 을 만든다 .TBS_AUTOTICKS 지정된 슬라이더 범위 내의 각 단위값 마다 눈금을 붙이다 . 만일 이

스타일이 이용된 경우에는 SetTic, SetTicFreq 와 같은 멤버함수를 이용해

눈금의 위치를 지정할 수 있다 .TBS_NOTICKS눈금이 없는 슬라이더를 만든다 .TBS_BOTTOM슬라이더의 하단에 눈금을 표시한다 . TBS_TOP 스타일과 함께 사용되면

위아래 모두에 눈금을 붙일 수 있다 . TBS_BOTTOM과 TBS_TOP 스타일은

수평 슬라이더에만 적용 가능하다 .TBS_TOP 수평 슬라이더의 상단에 눈금을 붙인다 .TBS_RIGHT 수직 슬라이더의 우단에 눈금을 붙인다 . TBS_LEFT 스타일과 함께

사용되면 오른쪽 , 왼쪽 모두에 눈금을 붙인다 .

Page 431: Windows Programming

MFC Tutorial 431

ISLab ICE HUFSISLab ICE HUFS

TBS_LEFT 수직 슬라이더의 좌단에 눈금을 붙인다 .TBS_BOTH 수평 슬라이더이면 위아래에 눈금을 붙이고 수직

슬라이더이면 왼쪽 , 오른쪽에 눈금을 붙인다 .TBS_ENABLESELRANGE 이 스타일을 주면 영역을 선택하는 것이

가능하다 . 선택 영역의 시작과 끝 눈금이 삼각형 모양의 눈금으로 변하고 그 사이의영역이 하이라이트된다 .

Page 432: Windows Programming

MFC Tutorial 432

ISLab ICE HUFSISLab ICE HUFS

CSliderCtrlCSliderCtrl 의 멤버 함수의 멤버 함수 (1)(1)

SetRange Slider control 의 양끝값을 설정한다 .SetRangeMin Slider control 의 최소값을 설정한다 .SetRangeMax Slider control 의 최대값을 설정한다 .GetRangeMax Slider control 의 최대값을 얻어온다 .GetRangeMin Slider control 의 최소값을 얻어온다 .GetRange Slider control 의 양끝값을 얻어온다 .GetLineSize Slider control 의 라인 크기를 얻어온다 . TB_LINEUP,

TB_LINEDOWN 의 발생 시 이동량을 얻어오는 것이다 .SetLineSize Slider control 의 라인 크기를 설정한다 .GetPageSize Slider control 의 페이지 크기를 얻어온다 . TB_PAGEUP,

TB_PAGEDOWN 의 발생시 이동량을 얻어오는 것이다 .SetPageSize Slider control 의 페이지 크기를 결정한다 .GetPos Slider control 의 슬라이더 위치를 얻어온다 .SetPos Slider control 의 슬라이더 위치를 새로 설정한다 .

Page 433: Windows Programming

MFC Tutorial 433

ISLab ICE HUFSISLab ICE HUFS

CSliderCtrlCSliderCtrl 의 멤버 함수의 멤버 함수 (2)(2)

GetTic 주어진 눈금의 위치를 얻어온다 .GetTicPos 주어진 눈금이 위치한 좌표를 얻어온다 .SetTic 눈금이 생길 위치를 지정한다 .SetTicFreq 눈금이 생길 위치를 위치 단위로 지정한다 . 예로 들면 2 로

지정하면 0, 2, 4... 의 위치에 눈금이 생긴다 .ClearTics Slider control 에서 모든 눈금을 제거한다 .

Page 434: Windows Programming

MFC Tutorial 434

ISLab ICE HUFSISLab ICE HUFS

Slider ControlSlider Control 의 의 Notification CodeNotification Code

TB_TOP HOME 키를 눌렀을 때TB_BOTTOM END 키를 눌렀을 때TB_LINEDOWN VK_RIGHT 이나 VK_DOWN 키를 눌렀을 때TB_LINEUP VK_LEFT 나 VK_UP 키를 눌렀을 때TB_PAGEDOWN 마우스로 슬라이더의 오른쪽을 누르거나 PgDn

키를 눌렀을 때

TB_PAGEUP 마우스로 슬라이더의 왼쪽을 누르거나 PgUp 키를눌렀을 때

TB_THUMBPOSITION TB_THUMBTRACK 의 끝에 따라와 슬라이더의드래깅이 끝났음을 알린다 .

TB_THUMBTRACK 사용자가 슬라이더를 드래그하면 그 때 계속적으로

발생한다 .TB_ENDTRACK 각 notification code 에 뒤이어 항상 발생한다 .

Page 435: Windows Programming

MFC Tutorial 435

ISLab ICE HUFSISLab ICE HUFS

Slider ControlSlider Control 의 의 WM_HSCROLL WM_HSCROLL 처리처리

BEGIN_MESSAGE_MAP(CCmmCtrlView, CView)//{{AFX_MSG_MAP(CCmmCtrlView)

....//}}AFX_MSG_MAP

ON_CONTROL(ACN_STOP, IDC_ANIMATE, OnAnimateStop) ON_WM_HSCROLL()END_MESSAGE_MAP()

void CCmmCtrlView::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { int nCurPos = ((CSliderCtrl *)pScrollBar)->GetPos();

if (nCurPos==((CSliderCtrl *)pScrollBar)->GetRangeMax() && nSBCode==TB_ENDTRACK)

{ AfxMessageBox("Slider 의 끝에 도달했군요 ."); m_wndSliderCtrl.DestroyWindow(); InvalidateRect(NULL); }}

Page 436: Windows Programming

MFC Tutorial 436

ISLab ICE HUFSISLab ICE HUFS

List View ControlList View Control

• 리스트의 한 아이템이 여러 항목으로 구성될 수 있다 .• 항목의 일부로 비트맵이 들어갈 수 있다 .• 각 항목의 제목을 나타내기 위해 헤더 (Header) 컨트롤이라는 것을 내부적으로 사용할 수 있다 .

• 항목마다 사용되는 아이콘을 따로 리스트로 유지하는데 앞서 살펴 본 image list 를 사용하는 것이다 .

Page 437: Windows Programming

MFC Tutorial 437

ISLab ICE HUFSISLab ICE HUFS

List View ControlList View Control 의 타입의 타입

아이콘뷰 LVS_ICON 스타일을 지정하면 된다 . 각 항목은 아이콘과 그 밑의 레이블로 구성된다 . 각 항목은 드래깅으로 다른 위치에 갖다놓을 수 있다 .

스몰아이콘뷰 LVS_SMALLICON 스타일을 지정하면 된다 . 각 항목은16X16 아이콘과 그 오른쪽의 레이블로 구성된다 . 각

항목은 드래깅으로 다른 위치에 갖다 놓을 수 있다 .

리스트뷰 LVS_LIST 스타일을 지정하면 된다 . 각 항목은 서브 항목별로 정렬되어 디스플레이된다 .

리포트뷰 LVS_REPORT 스타일을 지정하면 된다 . LVS_NOCOLUMNHEADER 스타일이 명시되지 않으면헤더 컨트롤이 사용되어 레이블과 각 서브 항목의

타이틀을표시할 수 있다 . 리스트뷰에서와 마찬가지로 각 항목들은서브 항목별로 정렬되어 디스플레이된다 .

Page 438: Windows Programming

MFC Tutorial 438

ISLab ICE HUFSISLab ICE HUFS

List View ControlList View Control 의 윈도우 스타일의 윈도우 스타일LVS_BUTTON Icon view 에서 아이콘을 버튼처럼 디스플레이 되도록 한다 .LVS_EDITLABELS 각 항목의 레이블이 편집 가능하도록 한다 .

부모 윈도우는 LVN_ENDLABELEDIT 알림코드를처리할 수 있어야 한다 .

LVS_ICON List control 을 아이콘뷰로 생성할 것을 지정한다LVS_LIST List control 을 리스트뷰로 생성할 것을 지정한다LVS_REPORT List control 을 리포트뷰로 생성할 것을 지정한다LVS_SMALLICON List control 을 스몰아이콘뷰로 생성할 것을 지정LVS_NOCOLUMNHEADER List control 을 리포트뷰로 만들 때 header control 을 사용하지

말것을 지정LVS_SORTASCENDING List control 의 항목을 오름차순으로 정렬LVS_SORTDESCENDING List control 의 항목을 내림차순으로 정렬LVS_SINGLESEL 단지 하나의 항목만이 선택가능 하도록 한다 . 원래

디폴트는 여러 항목이 선택 가능하다 .LVS_NOSCROLL 항목들이 윈도우 영역의 크기를 넘어가도 스크롤이

안되도록 한다 .

Page 439: Windows Programming

MFC Tutorial 439

ISLab ICE HUFSISLab ICE HUFS

CListCtrl CListCtrl 클래스의 주요 멤버 함수클래스의 주요 멤버 함수 (1)(1)

InsertColumn 새로운 컬럼을 삽입한다 .DeleteColumn 컬럼을 하나 삭제한다 .InsertItem 새로운 항목을 하나 삽입한다 .GetItem 항목의 속성을 얻어온다 .SelItem 항목에 부항목을 붙이는 등의 속성변경 작업을 한다 .DeleteItem 항목 하나를 삭제한다 .DeleteAllItems 모든 항목을 삭제한다 .HitTest 주어진 위치에 어떤 항목이 있는지 알아낸다 .EnsureVisible 주어진 항목이 보이도록 만든다 .Scroll 내용을 스크롤시킨다 .EditLabel 항목 텍스트의 편집이 가능하도록 한다 .GetBkColor 배경색을 얻어온다 .SetBkColor 배경색을 설정한다 .GetImageList 사용되는 아이콘리스트를 얻어온다 .

Page 440: Windows Programming

MFC Tutorial 440

ISLab ICE HUFSISLab ICE HUFS

CListCtrl CListCtrl 클래스의 주요 멤버 함수클래스의 주요 멤버 함수 (2)(2)

SetImageList 사용되는 icon list 를 지정한다 .GetItemCount 항목수를 얻어온다 .GetStringWidth 주어진 문자열을 표시하는데 필요한 최소한의 컬럼폭을

돌려준다 .GetColumnWidth 리스트뷰와 리포트뷰의 컬럼폭을 얻어온다 .SetColumnWidth 리스트뷰와 리포트뷰의 컬럼폭을 설정한다 .GetItemText 리스트뷰의 특정항목의 레이블이나 부항목의 텍스트를

얻어온다 .SetItemText 리스트뷰의 특정항목의 레이블이나 부항목의 텍스트를

설정한다 .

Page 441: Windows Programming

MFC Tutorial 441

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_LIST(1)ID_COMM_LIST(1)

void CCmmCtrlView::OnCommList() { CheckWnd(); CRect rect;

GetClientRect(&rect); // 리스트 컨트롤을 리포트뷰로 생성한다 . m_wndListCtrl.Create(LVS_REPORT| WS_VISIBLE | WS_CHILD, rect, this, IDC_LISTCTRL);

// 16X16 이미지리스트를 만든다 . m_wndSmallImageList.Create(16,16, FALSE, 1, 2); m_wndSmallImageList.Add(((CCmmCtrlApp *)AfxGetApp())->LoadIcon(IDI_ICON1)); m_wndSmallImageList.Add(((CCmmCtrlApp *)AfxGetApp())->LoadIcon(IDI_ICON2)); m_wndListCtrl.SetImageList(&m_wndSmallImageList, LVSIL_SMALL);

Page 442: Windows Programming

MFC Tutorial 442

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_LIST(2)ID_COMM_LIST(2)

// 리스트 컨트롤의 헤더를 초기화한다 . LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_CENTER;

// 첫 번째 칼럼을 만든다 . lvc.pszText = (LPTSTR)_T("회사이름 "); lvc.cx = m_wndListCtrl.GetStringWidth(lvc.pszText) + 15; lvc.iSubItem = 0; m_wndListCtrl.InsertColumn(0, &lvc);

// 두 번째 칼럼을 만든다 . lvc.pszText = (LPTSTR)_T(" 제품이름 "); lvc.cx = m_wndListCtrl.GetStringWidth(lvc.pszText) + 15; lvc.iSubItem = 1; m_wndListCtrl.InsertColumn(1, &lvc);

Page 443: Windows Programming

MFC Tutorial 443

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_LIST(3)ID_COMM_LIST(3)

// 세 번째 칼럼을 만든다 . lvc.pszText = (LPTSTR)_T(" 가격 "); lvc.cx = m_wndListCtrl.GetStringWidth(lvc.pszText) + 15; lvc.iSubItem = 2; m_wndListCtrl.InsertColumn(2, &lvc); // 네 번째 칼럼을 만든다 . lvc.pszText = (LPTSTR)_T(" 수량 "); lvc.cx = m_wndListCtrl.GetStringWidth(lvc.pszText) + 15; lvc.iSubItem = 3; m_wndListCtrl.InsertColumn(3, &lvc);

// 첫 번째 항목을 리스트컨트롤에 붙인다 . int nActualIndex; LV_ITEM lvItem;

lvItem.mask = LVIF_TEXT | LVIF_IMAGE; lvItem.state = lvItem.stateMask = 0; lvItem.iImage = lvItem.lParam = 0;

Page 444: Windows Programming

MFC Tutorial 444

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_LIST(4)ID_COMM_LIST(4)

lvItem.iItem = m_wndListCtrl.GetItemCount() + 1; lvItem.iSubItem = 0; lvItem.pszText = _T("삼성 "); nActualIndex = m_wndListCtrl.InsertItem(&lvItem);

lvItem.mask = LVIF_TEXT; lvItem.iImage = -1; lvItem.iItem = nActualIndex; lvItem.iSubItem = 1; lvItem.pszText = _T("매직 스테이션 "); m_wndListCtrl.SetItem(&lvItem);

lvItem.iItem = nActualIndex; lvItem.iSubItem = 2; lvItem.pszText = _T("2,500,000"); m_wndListCtrl.SetItem(&lvItem);

Page 445: Windows Programming

MFC Tutorial 445

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_LIST(5)ID_COMM_LIST(5)

lvItem.iItem = nActualIndex; lvItem.iSubItem = 3; lvItem.pszText = _T("3,000"); m_wndListCtrl.SetItem(&lvItem);

// 두 번째 항목을 리스트컨트롤에 붙인다 . lvItem.mask = LVIF_TEXT | LVIF_IMAGE; lvItem.state = lvItem.stateMask = 0; lvItem.iImage = lvItem.lParam = 0; lvItem.iItem = m_wndListCtrl.GetItemCount() + 1; lvItem.iSubItem = 0; lvItem.pszText = _T(" 끝내기 "); nActualIndex = m_wndListCtrl.InsertItem(&lvItem); m_bListCtrl = TRUE;}

Page 446: Windows Programming

MFC Tutorial 446

ISLab ICE HUFSISLab ICE HUFS

SetImageListSetImageList

• 두번째 인자– LVSIL_NORMAL 큰 아이콘을 갖는 image list– LVSIL_SMALL 작은 아이콘을 갖는 image list– LVSIL_STATE 상태를 나타내는 아이콘을 갖는 image list

Page 447: Windows Programming

MFC Tutorial 447

ISLab ICE HUFSISLab ICE HUFS

헤더헤더

• LV_COLUMN 을 초기화해서 InsertColumn 함수를 호출typedef struct _LV_COLUMN { UINT mask; int fmt; // 정렬방식 : LVCFMT_LEFT, LVCFMT_RIGHT,

// LVCFMT_CENTER int cx; LPSTR pszText; int cchTextMax; int iSubItem;} LV_COLUMN

• maskLVCF_FMT fmt 필드를 사용할 것이다LVCF_SUBITEM iSubItem 필드를 사용할 것이다 .LVCF_TEXT pszText 필드를 사용할 것이다 .LVCF_WIDTH cx 필드를 사용할 것이다 .

Page 448: Windows Programming

MFC Tutorial 448

ISLab ICE HUFSISLab ICE HUFS

항목항목

• LV_ITEM 스트럭처를 초기화 한 다음 InsertItem 함수 호출

• 부항목은 InsertItem 함수의 리턴값 (nActualIndex) 을 갖고 LV_ITEM 스트럭처를 초기화한 다음에 SetItem 함수 호출

• 원하는 부항목 수만큼 반복

Page 449: Windows Programming

MFC Tutorial 449

ISLab ICE HUFSISLab ICE HUFS

LV_ITEM(1)LV_ITEM(1)

typedef struct _LV_ITEM { UINT mask; int iItem; int iSubItem; UINT state; UINT stateMask; LPTSTR pszText; int cchTextMax; int iImage; // index of the list view item’s icon LPARAM lParam; // 32-bit value to associate with item} LV_ITEM;

Page 450: Windows Programming

MFC Tutorial 450

ISLab ICE HUFSISLab ICE HUFS

LV_ITEM(2)LV_ITEM(2)

• maskLVIF_TEXT pszText 필드를 사용할 것이다 .LVIF_IMAGE iImage 필드를 사용할 것이다 .LVIF_PARAM lParam 필드를 사용할 것이다 .LVIF_STATE state 필드를 사용할 것이다 .

• iItem : list view control 의 몇번째 항목인가• iSubItem : 몇번째 부항목인가 (0부터 시작 )• state : stateMask 필드와 같이 사용

– LVIS_CUT, LVIS_DROPHILITED, LVIS_FOCUSED, LVIS_SELECTED– 항목의 외양을 나타냄

Page 451: Windows Programming

MFC Tutorial 451

ISLab ICE HUFSISLab ICE HUFS

LV_ITEM(3)LV_ITEM(3)

• pszText : 항목의 텍스트• cchTextMax : pszText 필드의 버퍼 크기• iImage : image list 의 아이콘의 인덱스 (-1 이면 사용안

함 )– 만일 이 값이 I_IMAGECALLBACK 이면 디스플레이 할 순간에

부모 윈도우로 LVN_GETDISPINFO notification message 가 보내진다 .

Page 452: Windows Programming

MFC Tutorial 452

ISLab ICE HUFSISLab ICE HUFS

실행 모습실행 모습

Page 453: Windows Programming

MFC Tutorial 453

ISLab ICE HUFSISLab ICE HUFS

List ViewList View 의 의 Notification CodeNotification Code

LVN_BEGINDRAG 왼쪽 마우스버튼을 이용해 드래그 작업이 시작할 때 발생한다 .

LVN_BEGINRDRAG 오른쪽 마우스버튼을 이용해 드래그 작업이 시작할 때 발생

LVN_BEGINLABELEDIT 레이블 편집이 시작될 때 발생LVN_ENDLABELEDIT 레이블 편집이 끝날 때 발생LVN_DELETEITEM 항목이 삭제될 때 발생LVN_KEYDOWN 키가 눌렸을 때 발생 . 이는 리스트뷰 컨트롤이

입력 포커스를 갖고 있을 때만 발생LVN_COLUMNCLICK 리스트뷰 컨트롤의 헤더가 클릭되었을 때 발생LVN_DELETEALLITEMS 모든 항목이 삭제되었을 때 발생LVN_INSERTITEM 새로운 항목이 삽입되었을 때 발생LVN_ITEMCHANGING 현재 선택된 항목이 다른 항목으로 변경될 때LVN_ITEMCHANGED 현재 선택 항목이 다른 항목으로 변경된 다음

발생

Page 454: Windows Programming

MFC Tutorial 454

ISLab ICE HUFSISLab ICE HUFS

LVN_ITEMCHANGED LVN_ITEMCHANGED 처리처리BEGIN_MESSAGE_MAP(CCmmCtrlView, CView)

//{{AFX_MSG_MAP(CCmmCtrlView) ....

//}}AFX_MSG_MAP ON_CONTROL(ACN_STOP, IDC_ANIMATE, OnAnimateStop) ON_WM_HSCROLL() ON_NOTIFY(LVN_ITEMCHANGED, IDC_LISTCTRL, OnListCtrlClick)END_MESSAGE_MAP()

void CCmmCtrlView::OnListCtrlClick(NMHDR * pNotifyStruct, LRESULT * result) { NM_LISTVIEW* pListView = (NM_LISTVIEW *)pNotifyStruct; if (pListView->iItem == 1) { AfxMessageBox(" 끝이 눌렸습니다 ."); } *result = 0;}

Page 455: Windows Programming

MFC Tutorial 455

ISLab ICE HUFSISLab ICE HUFS

Tree View ControlTree View Control

• 윈도우 스타일TVS_HASLINES 각 항목간 ( 부모 자식간 ) 을 선으로 이어준다 .TVS_LINESATROOT 루트를 만들어 최상위 레벨의 항목들과 연결

시켜준다 .TVS_HASBUTTONS 각 항목의 좌측에 버튼을 붙여준다 .TVS_EdITLABELS Tree view control 의 레이블을 편집 가능하게 만듦

Page 456: Windows Programming

MFC Tutorial 456

ISLab ICE HUFSISLab ICE HUFS

CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (1)(1)

InsertItem 새로운 항목을 삽입한다 .DeleteItem 항목 하나를 삭제한다 .DeleteAllItems 모든 항목을 삭제한다 .Expand 주어진 항목의 자식 항목들을 모두 펼친다 .SelectItem 주어진 항목을 현재 선택 항목으로 만든다 .EditLabel 주어진 항목의 레이블을 편집 가능하게 만든다 .HitTest 주어진 위치에 있는 항목의 핸들을 얻어온다 .SortChildren주어진 항목의 자식 항목들을 정렬한다 .SortChildrenCB 주어진 항목의 자식 항목들을 정렬한다 . 따로 정렬함수를

제공해 주어야 한다 .EnsureVisible 지정된 항목이 트리뷰 컨트롤 내에서 보이도록 만든다 .GetCount 항목의 총수를 얻어온다 .GetIndent 부모 항목과 자식 항목 간의 거리를 픽셀단위로 얻어온다 .SetIndent 부모 항목과 자식 항목 간의 거리를 픽셀단위로 설정한다 .

Page 457: Windows Programming

MFC Tutorial 457

ISLab ICE HUFSISLab ICE HUFS

CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (2)(2)

GetImageList 트리뷰 컨트롤과 관련된 이미지리스트를 얻어온다 .SetImageList 트리뷰 컨트롤과 관련된 이미지리스트를 설정한다 .ItemHasChildren 주어진 항목이 자식 노드를 갖고 있는지 여부를

알려준다 .GetNextSiblingItem 트리구조에서 주어진 항목과 같은 레벨의 다음 항

목을 얻어준다 .GetPrevSiblingItem 트리구조에서 주어진 항목과 같은 레벨의 이전 항

목을 얻어준다 .GetParentItem 트리구조에서 주어진 항목의 부모 항목을 얻음GetSelectedItem 현재 선택된 항목이 무엇인지 알려준다 .GetRootItem 루트항목이 무엇인지 알려준다 .GetItem 주어진 트리뷰 항목의 속성을 돌려준다 .SetItem 주어진 트리뷰 항목의 여타 속성을 설정한다 .GetItemText 주어진 트리뷰 항목의 텍스트를 돌려준다 .

Page 458: Windows Programming

MFC Tutorial 458

ISLab ICE HUFSISLab ICE HUFS

CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (3)(3)

SetItemText 주어진 트리뷰 항목의 텍스트를 설정한다 .GetVisibleCount 현재 트리뷰 컨트롤에서 보이는 항목의 수를 돌려

준다 .GetItemImage 주어진 항목의 이미지가 무엇인지 알려준다 .SetItemImage 주어진 항목의 이미지를 변경한다 .GetItemRect 주어진 항목을 둘러싸는 사각형이 무엇인지 얻음

Page 459: Windows Programming

MFC Tutorial 459

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_TREE(1)ID_COMM_TREE(1)

void CCmmCtrlView::OnCommTree() { CheckWnd(); InvalidateRect(NULL);

CRect rect;

GetClientRect(&rect); m_wndTreeCtrl.Create(TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_VISIBLE | WS_CHILD, rect, this, IDC_TREECTRL);

m_wndImageList.Create(32, 32, FALSE, 1, 2); m_wndImageList.Add(((CCmmCtrlApp*)AfxGetApp())->LoadIcon(IDI_ICON1)); m_wndImageList.Add(((CCmmCtrlApp*)AfxGetApp())->LoadIcon(IDI_ICON2)); m_wndImageList.Add(((CCmmCtrlApp*)AfxGetApp())->LoadIcon(IDI_ICON3)); m_wndTreeCtrl.SetImageList(&m_wndImageList, TVSIL_NORMAL);

TV_INSERTSTRUCT tvs;

Page 460: Windows Programming

MFC Tutorial 460

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_TREE(2)ID_COMM_TREE(2)

memset(&tvs, 0, sizeof(TV_INSERTSTRUCT)); tvs.hParent = 0; tvs.hInsertAfter = TVI_SORT; tvs.item.iImage = 0; tvs.item.iSelectedImage = 2; tvs.item.pszText = _T("Tree Parent"); tvs.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; m_treeRoot = m_wndTreeCtrl.InsertItem(&tvs);

tvs.hParent = m_treeRoot; tvs.hInsertAfter = TVI_SORT; tvs.item.iImage = 1; tvs.item.iSelectedImage = 2; tvs.item.pszText = _T("Tree Child1"); tvs.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; m_wndTreeCtrl.InsertItem(&tvs);

Page 461: Windows Programming

MFC Tutorial 461

ISLab ICE HUFSISLab ICE HUFS

ID_COMM_TREE(3)ID_COMM_TREE(3)

tvs.hParent = m_treeRoot; tvs.hInsertAfter = TVI_SORT; tvs.item.iImage = 1; tvs.item.iSelectedImage = 2; tvs.item.pszText = _T("Tree Child2"); tvs.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; m_wndTreeCtrl.InsertItem(&tvs);

m_bTreeCtrl = TRUE;}

Page 462: Windows Programming

MFC Tutorial 462

ISLab ICE HUFSISLab ICE HUFS

SetImageListSetImageList

• 두번째 인자– TVSIL_NORMAL 항목의 선택시와 보통 때의 모습만을 담고 있은 경우– TVSIL_STATE 선택 유무 말고 사용자 나름대로의 기준으로 항목 상태

를 지정하려는 경우

IDI_ICON1

IDI_ICON2

IDI_ICON3

Page 463: Windows Programming

MFC Tutorial 463

ISLab ICE HUFSISLab ICE HUFS

실행모습실행모습

Page 464: Windows Programming

MFC Tutorial 464

ISLab ICE HUFSISLab ICE HUFS

TV_INSERTSTRUCTTV_INSERTSTRUCT

typedef struct _TV_INSERTSTRUCT { HTREEITEM hParent; // 지금 삽입되는 항목의 부모 항목이 무엇인가 // 나타내는 핸들이 들어가는 곳 // InsertItem 함수를 이용해 항목을 하나 추가 // 하면 그 항목의 핸들이 리턴되는데 그 값이 // hParent 와 hInsertAfter 필드에서 사용된다 // 값이 0 이거나 TVI_ROOT 이면 루트 항목이 됨 HTREEITEM hInsertAfter; // 어느 항목 뒤에 삽입될 것인지 그 항목을 지정 // 여기서 위치는 hParent 필드가 가리키는 항목 // 의 자식 항목에서의 위치를 말함 // TVI_FIRST 첫번째 항목으로 삽입 // TVI_LAST 마지막 항목으로 삽입 // TVI_SORT 삽입되는 항목을 알파벳 순으로 // 정렬하여 삽입한다 . TV_ITEM item;} TV_INSERTSTUCT, FAR *LPTV_INSERTSTRUCT;

Page 465: Windows Programming

MFC Tutorial 465

ISLab ICE HUFSISLab ICE HUFS

TV_ITEM(1)TV_ITEM(1)

typedef struct _TV_ITEM { UINT mask; HTREEITEM hItem; UINT state; UINT stateMask; LPSTR pszText; int cchTextMax; int iImage; int iSelectedImage; int cChildren; LPARAM lParam;} TV_ITEM, FAR *LPTV_ITEM;

Page 466: Windows Programming

MFC Tutorial 466

ISLab ICE HUFSISLab ICE HUFS

TV_ITEM(2)TV_ITEM(2)

• mask– TVIF_CHILDREN cChildren 필드를 사용한다 .– TVIF_HANDLE hItem 필드를 사용한다 .– TVIF_IMAGE iImage 필드를 사용한다 .– TVIF_PARAM lParam 필드를 사용한다 .– TVIF_SELECTEDIMAGE iSelectedImage 필드를 사용한다 .– TVIF_STATE state, stateMask 필드를 사용한다 .– TVIF_TEXT pszText, cchTextMax 필드를 사용한다 .

• hItem : 이 스트럭처가 나타내고 있는 항목– 새로운 항목의 삽입 시에는 0을 지정해야

Page 467: Windows Programming

MFC Tutorial 467

ISLab ICE HUFSISLab ICE HUFS

TV_ITEM(3)TV_ITEM(3)

• pszText : 항목에 들어갈 텍스트– LPSTR_TEXTCALLBACK 이면 항목의 디스플레이 책임은 부모

윈도우가 진다 . 이때 부모 윈도우에게 TVN_SETDISPINFO 메시지가 넘어간다 .

• cchTextMax : pszText 필드가 가리키는 버퍼의 크기

Page 468: Windows Programming

MFC Tutorial 468

ISLab ICE HUFSISLab ICE HUFS

TV_ITEM(4)TV_ITEM(4)

• iImage : 정상상태에 있을 때에 해당하는 이미지 (이미지리스트에서의 인덱스 )

• iSelectedImage : 선택상태에 있을 때에 해당하는 이미지• cChildren : 자식 항목을 가질 것인지 여부를 지정

– 0 : 자식 항목이 없음– 1 : 자식 항목이 있음

• lParam : 이 항목과 관련해서 따로 저장하고 싶은 32비트 값을 지정할 때 사용

Page 469: Windows Programming

MFC Tutorial 469

ISLab ICE HUFSISLab ICE HUFS

트리뷰의 알림 메시지트리뷰의 알림 메시지

TVN_BEGINDRAG 왼쪽 마우스버튼을 이용해 드래그 작업이 시작할때 발생한다 .

TVN_BEGINRDRAG 오른쪽 마우스 버튼을 이용해 드래그 작업이 시작할 때 발생한다 .

TVN_BEGINLABELEDIT 레이블 편집이 시작될 때 발생TVN_ENDLABELEDIT 레이블 편집이 끝날 때 발생TVN_DELETEITEM 항목이 삭제될 때 발생TVN_ITEMEXPANDING 항목 하나가 펼쳐져야 함을 알리기 위해 발생TVN_ITEMEXPANDED 항목 하나가 펼쳐졌음을 알리기 위해 발생TVN_KEYDOWN 키가 눌렸을 때 발생 . 이는 트리뷰 컨트롤이

입력포커스를 갖고 있을 때 발생한다 .

TVN_SELCHANGING 현재 선택된 항목이 다른 항목으로 변경될 때 발생TVN_SELECTED 현재 선택된 항목이 다른 항목으로 변경된 다음

발생

Page 470: Windows Programming

MFC Tutorial 470

ISLab ICE HUFSISLab ICE HUFS

NM_DBLCLKNM_DBLCLK

BEGIN_MESSAGE_MAP(CCmmCtrlView, CView)//{{AFX_MSG_MAP(CCmmCtrlView)

....//}}AFX_MSG_MAP

ON_CONTROL(ACN_STOP, IDC_ANIMATE, OnAnimateStop) ON_WM_HSCROLL() ON_NOTIFY(LVN_ITEMCHANGED, IDC_LISTCTRL, OnListCtrlClick) ON_NOTIFY(NM_DBLCLK, IDC_TREECTRL, OnTreeCtrlDblClick)END_MESSAGE_MAP()

void CCmmCtrlView::OnTreeCtrlDblClick(NMHDR * pNotifyStruct, LRESULT * result) { HTREEITEM hItem = m_wndTreeCtrl.GetSelectedItem();

if (m_treeRoot == hItem) AfxMessageBox(" 루트가 더블 클릭되었군요 ."); *result = 0;}


Recommended