Upload
medge-moore
View
182
Download
0
Embed Size (px)
DESCRIPTION
Windows Programming. 박 상 원 [email protected] 한국외국어대학교 정보통신공학과. 서론. 목차. 객체지향이란 ? MFC 의 역사 MFC 를 위한 C++ 의 기초. 객체지향 개념의 등장 배경. 프로그래밍 언어의 발전 기계어 -> 어셈블리어 -> 고급언어 함수 기반 프로그래밍 1970 년대 - 1980 년대 소프트웨어의 위기 생산성 향상의 한계 객체지향 개념의 등장 1980 년대. 객체지향이란 ?. 객체 메쏘드 호출. 메시지. 이벤트. - PowerPoint PPT Presentation
Citation preview
ISLab ICE HUFSISLab ICE HUFS
Windows ProgrammingWindows Programming
박 상 원[email protected]
한국외국어대학교 정보통신공학과
ISLab ICE HUFSISLab ICE HUFS
서론서론
MFC Tutorial 3
ISLab ICE HUFSISLab ICE HUFS
목차목차
• 객체지향이란 ? • MFC 의 역사• MFC 를 위한 C++ 의 기초
MFC Tutorial 4
ISLab ICE HUFSISLab ICE HUFS
객체지향 개념의 등장 배경객체지향 개념의 등장 배경
• 프로그래밍 언어의 발전– 기계어 -> 어셈블리어 -> 고급언어
• 함수 기반 프로그래밍– 1970 년대 - 1980 년대
• 소프트웨어의 위기– 생산성 향상의 한계
• 객체지향 개념의 등장– 1980 년대
MFC Tutorial 5
ISLab ICE HUFSISLab ICE HUFS
객체지향이란객체지향이란 ??
객체메쏘드 호출메시지메시지
이벤트
MFC Tutorial 6
ISLab ICE HUFSISLab ICE HUFS
객체지향의 핵심 내용객체지향의 핵심 내용 (1)(1)• 객체란
– 데이타 ( 자료구조 ; 상태변수 ) 와 오퍼레이터 ( 함수 ) 가 하나로 묶여있는 형태
• 추상 데이타 타입 (ADT;abstract data type)– 클래스를 이용하여 표현
• 계승 (inheritance)– 동적 바인딩 (dynamic binding)– cf) Static binding
• 다형성 (polymorphism)– Overloading : 동일한 함수의 이름 사용 가능– Overriding : 상위 클래스에서 정의된 함수를 하위 클래스에서 재 정의– Template : 타입을 인자로 하여 새로운 타입을 생성
MFC Tutorial 7
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 를 위한 를 위한 C++C++ 의 기초의 기초
• 클래스• 계승• 생성자 및 소멸자• Virtual Function 을 이용한 동적 바인딩
MFC Tutorial 8
ISLab ICE HUFSISLab ICE HUFS
클래스란클래스란 ??
• 객체를 기술할 수 있는 수단을 제공– 자료 구조 (member data)– 오퍼레이션 (member function)
실세계 컴퓨터세계
모델링
MFC Tutorial 9
ISLab ICE HUFSISLab ICE HUFS
클래스의 계승클래스의 계승 (1)(1)
• 계승을 통한 코드의 재 사용 가능– 생산성 향상
• 이름 충돌 (name conflict) 발생• 다중 계승의 문제점
– virtual base class 로 계승
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;
MFC Tutorial 11
ISLab ICE HUFSISLab ICE HUFS
생성자생성자 (1)(1)
• 생성자 (constructor) 호출– 메모리 할당과 생성자는 별개– 메모리 할당
• new : 힙 (heap) 에 객체 생성• 지역변수 : 스택 (stack) 에 객체 생성• 전역변수 : 프로그램 코드 영역에 객체 생성
– 생성자는 메모리 할당이 끝난 객체의 각 데이타 부분을 초기화하는 역할
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) 영역
힙 / 스택 / 코드 영역
MFC Tutorial 13
ISLab ICE HUFSISLab ICE HUFS
소멸자소멸자 (1)(1)
• 소멸자 (destructor) 의 virtual 함수화– 소멸자는 객체 자체의 메모리 영역을 없애는 것이 아님– 그 객체가 new 등을 이용하여 실행중에 만든 객체를 메모리에서
없애는 역할을 한다 .
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)
MFC Tutorial 15
ISLab ICE HUFSISLab ICE HUFS
Virtual Function(1)Virtual Function(1)
• 동적 바인딩 (dynamic binding)– 프로그램의 수행 중에 실제 수행할 함수를 결정– vitual function table(hidden pointer)
• 정적 바인딩 (static binding)
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
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
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
ISLab ICE HUFSISLab ICE HUFS
MFC MFC 기초기초
MFC Tutorial 20
ISLab ICE HUFSISLab ICE HUFS
목차목차
• SDK 와 MFC 의 비교• MFC 클래스 종류• AppWizard 를 이용한 프로젝트 생성• Develop Studio 사용법• Hungarian 표기법
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 라이브러리
MFC Tutorial 22
ISLab ICE HUFSISLab ICE HUFS
SDK SDK 프로그래밍프로그래밍
• SDK(Software Development Kit)– 윈도우 프로그래밍을 위한 여러 가지 툴과 라이브러리로
구성되어 있는 마이크로소프트에 의해 발표된 소프트웨어 패키지
– 윈도우 프로그래밍시 호출하여 사용할 수 있는 함수들이 포함 ( 윈도우 API)
– C 라이브러리
MFC Tutorial 23
ISLab ICE HUFSISLab ICE HUFS
메시지와 메시지 큐메시지와 메시지 큐
• 메시지 (message)?– 윈도우에서 발생하는 사건들의 표현– 숫자 (winuser.h)
• 메시지 큐 (queue)– 하나의 프로그램에 하나씩 할당
윈도우에 사건이 발생하면운영체제는 이를 메시지로 만들어
발생 순서대로 메시지 큐에넣는다 .
MFC Tutorial 24
ISLab ICE HUFSISLab ICE HUFS
메시지 루프메시지 루프 , , 윈도우 프로시저윈도우 프로시저
• 메시지 루프– 메시지 큐에서 메시지를 하나씩 꺼내어 거기에 맞게 처리
• 윈도우 프로시저– 메시지의 실제 처리
운영체제 응용 프로그랭
메시지를 하나씩 읽어다가이를 처리할 윈도우의 윈도우프로시저를 호출한다 .
MFC Tutorial 25
ISLab ICE HUFSISLab ICE HUFS
메시지에 의한 동작메시지에 의한 동작
• Message-driven operationsint WinMain(HINSTANCE ......)
{
. . .
InitApplication(hInstance);
InitInstance(hInstance);
. . .
. . .
while(GetMessage(....))
{
. . .
DispatchMessage(. . .);
}
. . .
}
메시지 큐
윈도우에 사건이 발생하면운영체제는 이를 메시지로만들어 발생 순서대로메시지 큐에 넣는다 .
msg
함수
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;
MFC Tutorial 27
ISLab ICE HUFSISLab ICE HUFS
// 메시지 루프에 진입한다 .
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
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); // 이 윈도우 클래스를 등록한다 .
}
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;
}
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 윈도우에 수직 스크롤바를 붙여 생성한다 .
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)
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; }
MFC Tutorial 33
ISLab ICE HUFSISLab ICE HUFS
case WM_DESTROY: // 윈도우가 없어지기 직전에 발생하는 메시지 {
PostQuitMessage(0);
break;
}
default: // 처리하지 못한 메시지를 넘긴다 .
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
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
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
MFC Tutorial 36
ISLab ICE HUFSISLab ICE HUFS
핸들핸들 (Handle)(Handle)
• 무엇인가를 구별하기 위해 붙인 번호– 예 ) 윈도우 핸들 (HWND)
• 윈도우가 여러 개 존재할 경우 이를 구별하기 위해 윈도우마다 번호를 하나씩 부여
• 핸들 타입 앞에는 H 가 붙는다 .
• UINT 로부터 재정의– #define UINT HANDLE– #define HANDLE HWND
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으로부터 재정의 . 메시지에 수반되는 부가 정보 표시
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 메시지를 발생
MFC Tutorial 39
ISLab ICE HUFSISLab ICE HUFS
주요 메시지주요 메시지 (2)(2)
WM_DESTROY 윈도우가 없어지기 직전에 발생한다 . 여기서는 앞서 윈도우 프로시저의 실행중에 할당한 자원들이있다면 이를 운영체제에 반환하는 역할을 수행함 .메인 윈도우의 WM_DESTROY 메시지 처리부에서는 끝부분에서 PostQuitMessage 함수를 호출하는것이 일반적이다 .
WM_QUIT PostQuitMessage 함수를 호출하면 이 메시지가 만들어져 메시지 큐에 들어가게 된다 . 메시지 루프에서 이 메시지를 읽어가면 GetMessage 함수의 리턴값이 FALSE가 되기 때문에 메시지 루프가 끝나게되고 프로그램이 종료된다 .
MFC Tutorial 40
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 란란
• 클래스 라이브러리– 클래스의 집합 ( 함수의 집합이 아님 )
• 애플리케이션 프레임워크 (application framework)– AppWizard– ClassWizard– Project Workspace
MFC Tutorial 41
ISLab ICE HUFSISLab ICE HUFS
MFC MFC 구조구조
• MFC 는 SDK API 의 기능을 구분하여 클래스 계층구조를 입힌 것
• 응용 프로그램은 SDK API 를 직접 부를 수 있음
• “Handle” 은 분류의 기준이 됨
응용프로그램
MFC
SDK API
운영체제
MFC Tutorial 42
ISLab ICE HUFSISLab ICE HUFS
왜 왜 MFC MFC 인가인가 ??
• 이해가 쉬움 – 연관된 함수와 데이타를 “클래스”를 이용하여 그룹화하였음
• 코드의 재사용성 향상• 소프트웨어 개발의 용이성
– 애플리케이션 프레임워크 (application framework) 제공– 멤버 함수 나열– 코드 삽입의 용이성
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);
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);}
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);
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);}
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); // 반드시 자원을 반환해야 한다 .
}
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 를 해제한다 .}
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);
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;
MFC Tutorial 51
ISLab ICE HUFSISLab ICE HUFS
MFC MFC 클래스 종류클래스 종류
• 일반 목적의 클래스• 윈도우 API 클래스• 애플리케이션 프레임워크 클래스• 고 수준 추상화 클래스• 운영체제 확장 클래스
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 등
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 등 )
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
MFC Tutorial 55
ISLab ICE HUFSISLab ICE HUFS
애플리케이션 프레임워크 클래스애플리케이션 프레임워크 클래스
• 문서 /뷰 관련 클래스– CDocTemplate, CSingleDocTemplate, CMultiDocTemplate– CDocument, Cview
• 문맥 지원 도움말 (context-sensitive help)
MFC Tutorial 56
ISLab ICE HUFSISLab ICE HUFS
고 수준 추상화 클래스고 수준 추상화 클래스
• 확장된 뷰 (enhanced view)– CScrollView, CFormView– 콘트롤 뷰 : CEditView, CListView, CRichEditView, CTreeView
• 분리 윈도우– CSplitterWnd
• 콘트롤 바– CControlBar– CToolBar, CStatusBar, CDialogBar
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
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 비트 환경
MFC Tutorial 59
ISLab ICE HUFSISLab ICE HUFS
코드 재 사용 방법코드 재 사용 방법
Component Gallery
응용프로그램
MFCCustomAppWizard
MFC 확장AppWizard
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 선택
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 선택
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
MFC Tutorial 63
ISLab ICE HUFSISLab ICE HUFS
클래스 뷰클래스 뷰 // 파일 뷰파일 뷰 // 리소스 뷰리소스 뷰
MFC Tutorial 64
ISLab ICE HUFSISLab ICE HUFS
클래스 뷰클래스 뷰 (class view)(class view)
• 클래스에 함수 및 멤버 추가– 클래스 이름에 마우스 커서를
위치시킨 후 오른쪽 버튼을 클릭– 멤버 함수 추가– 멤버 변수 추가
• 특정 위치로 커서 이동
• 계승 관계 표시
MFC Tutorial 65
ISLab ICE HUFSISLab ICE HUFS
파일 뷰파일 뷰 (file view)(file view)
• 프로젝트에 있는 화일들을 열거• 프로젝트에서 화일 삭제
• (.net) 솔루션 탐색기
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 함수 포인터
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
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
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 기본 구조 이해의 기본 구조 이해
MFC Tutorial 70
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 철학의 철학 (1)(1)
• 예제 프로그램 컴파일 후 수행– Open 메뉴 선택
• 화일 선택시 일반적인 절차에 대한 코딩1 화일 오픈 다이얼로그 박스를 띄운다 .2 사용자의 입력을 받아 해당 화일을 연다 . 만일 MDI 프로그램이면 자식
윈도우를 하나 연다 . SDI 프로그램이라면 전에 갖고 있던 자료 구조를 해제한다 .
3 화일을 프로그램의 정의에 맞게 해석하여 읽어들인다화일을 프로그램의 정의에 맞게 해석하여 읽어들인다 . . 즉 화일의 즉 화일의 내용을 메모리 상의 자료구조로 변환한다내용을 메모리 상의 자료구조로 변환한다 .
4 읽어들인 내용을 윈도에 그린다 . 이 부분의 구현은 대개 윈도를 무효화(invalidate) 하여 이루어진다 .
MFC Tutorial 71
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 철학의 철학 (2)(2)
• 실제 사용자가 해야 할 일 (3 번 )– 장점
• 에러의 가능성 감소• 프로그래밍 시간 및 노력 감소
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(); // 현재 문서의 내용을 보여주는 윈도우 포인터를 리턴 ...
}
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 메시지 // 발생}
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
};
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;
}
MFC Tutorial 76
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 의 WinMainWinMain
• MFC\SRC\winmain.cpp
• CWinApp 클래스에 존재CWinApp::InitApplicationCWinApp::InitInstanceCWinApp::RunCWinApp::ExitInstance
• InitInstance, ExitInstance 만 override 하여 사용 가능
• 가상 함수의 중요성
MFC Tutorial 77
ISLab ICE HUFSISLab ICE HUFS
SDISDI
• CObeditApp -> CWinApp• CMainFrame -> CMDIFrameWnd• CObeditDoc -> CDocument• CObeditView -> CView
MFC Tutorial 78
ISLab ICE HUFSISLab ICE HUFS
MDIMDI
CObeditApp -> CWinAppCMainFrame -> CMDIFrameWndCChildFrame -> CMDIChildWndCObeditDoc -> CDocumentCObeditView -> CView
MFC Tutorial 79
ISLab ICE HUFSISLab ICE HUFS
Document/View Document/View 구조구조
뷰클래스뷰클래스
문서클래스문서클래스
1. 사용자의 입력을받는다
2. 그 내용을 반영한다 .
3. 윈도우로출력한다 .
MFC Tutorial 80
ISLab ICE HUFSISLab ICE HUFS
전체 구조전체 구조
• CWinApp– 하나의 응용 프로그램을 가리키는 클래스
• CDocument– 응용 프로그램의 자료구조를 저장하는 클래스
• CView– 응용 프로그램의 모습을 화면에 출력하는 클래스
• 하나의 document 에는 여러 개의 view 가 연관될 수 있음– 예 ) 탐색기 , Visual C++ 에디터 창
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
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;
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;}
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
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 );
MFC Tutorial 86
ISLab ICE HUFSISLab ICE HUFS
레지스트리레지스트리
void CObeditApp::LoadStdProfileSettings()
{
// 나름대로 초기화 값을 읽어다 저장한다 .
// GetProfileInt...
//
CWinApp::LoadStdProfileSettings(); // 선조 함수 호출}
MFC Tutorial 87
ISLab ICE HUFSISLab ICE HUFS
윈도우 생성윈도우 생성
• WM_CREATE– OnCreate 함수 호출
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() // 메시지 맵};
MFC Tutorial 89
ISLab ICE HUFSISLab ICE HUFS
OnCreate OnCreate 함수함수
MFC Tutorial 90
ISLab ICE HUFSISLab ICE HUFS
MFC MDI MFC MDI 프로그램의 윈도우 구조프로그램의 윈도우 구조
타이틀파일 편집
타이틀
MDI 메인 윈도우
MDI 클라이언트윈도우MDI 자식 윈도우
뷰 윈도우
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
....
MFC Tutorial 92
ISLab ICE HUFSISLab ICE HUFS
주요 주요 CView CView 멤버함수멤버함수
GetDocument뷰와 연계된 문서 오브젝트에 대한 포인터를 돌려준다 . AddDocTemplate 함수를 통해 m_pDocument 멤버는MFC 가 뷰를 생성할 때 알아서 초기화
OnInitialUpdate 뷰가 처음 만들어질 때 호출된다 .
OnDraw 뷰와 연계된 문서오브젝트의 내용을 윈도우 위에 그려준다 .
OnPrint 뷰와 연계된 문서오브젝트의 내용을 프린터로 출력
OnUpdate 문서오브젝트의 내용이 변경되었을 때 문서오브젝트쪽에 불러준다 .
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
....
};
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 명령을 수행하면 불린다 .
MFC Tutorial 95
ISLab ICE HUFSISLab ICE HUFS
모든 뷰 수정모든 뷰 수정
• Document class 는 자신과 연관이 있는 view object 를 리스트의 형태로 관리– CPtrList m_viewList
• View 에서 수정
• Document 수정
• UpdateAllViews 호출
MFC Tutorial 96
ISLab ICE HUFSISLab ICE HUFS
UpdateAllViewsUpdateAllViews
View Document
GetDocument 함수로 관련문서 오브젝트를 알아낸다.그 다음 데이터를 갱신한다.
자료구조에 변화가 생긴다.이 변화를 관련된 모든 뷰에반영하기위해 UpdateAllViews함수를 호출한다.
각 뷰별로 화면을 다시 그린다.
UpdateAllViews 함수에서는OnUpdate 함수를 호출한다.
ISLab ICE HUFSISLab ICE HUFS
UI UI 붙이기붙이기
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
MFC Tutorial 99
ISLab ICE HUFSISLab ICE HUFS
메뉴 리소스 작성메뉴 리소스 작성
• 리소스 뷰에서– IDR_MAINFRAME(child window 가 없을 때 ) – IDR_OBEDITTYPE
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
단축키
MFC Tutorial 101
ISLab ICE HUFSISLab ICE HUFS
단축키 작성단축키 작성
• 리소스 뷰의 Accelerator 이용
MFC Tutorial 102
ISLab ICE HUFSISLab ICE HUFS
아이콘 변경아이콘 변경
MFC Tutorial 103
ISLab ICE HUFSISLab ICE HUFS
툴바의 수정툴바의 수정
• 리소스 뷰에서– IDR_MAINFRAME
MFC Tutorial 104
ISLab ICE HUFSISLab ICE HUFS
배율 설정배율 설정
• 새로운 ToolBar 생성
MFC Tutorial 105
ISLab ICE HUFSISLab ICE HUFS
MyToolBar.h MyToolBar.h 수정수정
Class CMyToolBar : public CToolBarCtrl -> CToolBarCToolBar 로 수정(.net 에서는 바로 선택 )
{
// Construction
public:
CMyToolBar();
// Attributes
. . . .
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()
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 로 수정
MFC Tutorial 108
ISLab ICE HUFSISLab ICE HUFS
리소스 파일리소스 파일
• obedit.rc• 텍스트를 리소스 뷰에서 그래픽으로 나타냄
– 리소스 편집의 편리
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
MFC Tutorial 110
ISLab ICE HUFSISLab ICE HUFS
MainFrameMainFrame 에 변수 추가에 변수 추가
• CMainFrame 에 멤버 추가– CScrollBar m_zoomScroll;– CStatic m_zoomStatic
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 로 등록
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 로 등록
MFC Tutorial 113
ISLab ICE HUFSISLab ICE HUFS
리소스 심볼 등록리소스 심볼 등록#define ID_ZOOMSCROLL 101 // 리소스 심볼을 등록하는 것과 왼쪽과 같이 // 정의하는 것은 동일한 효과임
심볼 등록
MFC Tutorial 114
ISLab ICE HUFSISLab ICE HUFS
생성된 모습생성된 모습
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 툴바의 크기를 변경한다 .
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,};
MFC Tutorial 117
ISLab ICE HUFSISLab ICE HUFS
클래스 위저드클래스 위저드
클래스 이름
메시지
가상함수
메뉴
이미 만든 함수들
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 에 출력” );
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,};
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 등록
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);}
• 이벤트 발생시 마다 매번 함수 호출
MFC Tutorial 122
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 주요 전역 함수의 주요 전역 함수AfxGetApp 프로그램을 대표하는 프로그램 오브젝트에 대한
포인터를 돌려준다 .AfxGetAppName 프로그램의 이름을 돌려준다 .AfxGetInstanceHandle 프로그램의 인스턴스 핸들을 돌려준다 .AfxGetMainWnd 메인 프레임 윈도우 오브젝트에 대한 포인터를
돌려준다 .GetCurrentMessage 현재 처리 중인 메시지에 대한 메시지 스트럭처를
돌려준다 . 메시지 핸들러 등에서 메시지 스트럭처를 직접 접근하고 싶을 때 이용한다 .
AfxSocketInit 윈도우 소켓을 초기화하기 위해 부른다 .AfxBeginThread 새로운 스레드를 시작한다 .AfxEndThread 현재의 스레드를 끝낸다 .AfxGetThread 현재 실행 중인 스레드에 대한 포인터
(CWinThread) 를 돌려준다 .
MFC Tutorial 123
ISLab ICE HUFSISLab ICE HUFS
컬러 바 클래스 생성컬러 바 클래스 생성
• 클래스 위저드에서 새로운 클래스 생성– Add Class/New 에서 CMyColorBar 클래스 생성– 상위 클래스로 CToolBarCtrl 을 선택– MyColorBar.cpp, MyColorBar.h 에서 CToolBarCtrl 을 CToolBar 로
수정– 정확한 색 선택 : Image 메뉴의 Adjust Colors... 선택 후 숫자로
색 입력
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)};
MFC Tutorial 125
ISLab ICE HUFSISLab ICE HUFS
색깔 선택색깔 선택
• Image 메뉴– Adjust Colors...
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; ...};
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;}
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();
}
ISLab ICE HUFSISLab ICE HUFS
도형 처리 추가도형 처리 추가
MFC Tutorial 130
ISLab ICE HUFSISLab ICE HUFS
사용자 클래스 디자인사용자 클래스 디자인
CDrawObjectCDrawObject
CLineCLine CEllipseCEllipse CRectangleCRectangle
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 중의 하나가 // 될 수 있다 .
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
};
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
};
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
};
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
};
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);
}
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
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);}
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
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);}
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
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);}
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
MFC Tutorial 144
ISLab ICE HUFSISLab ICE HUFS
윈도우 운영체제에서의 출력윈도우 운영체제에서의 출력
GDI (Graphic Device Interface)GDI (Graphic Device Interface)
디바이스 드라이버디바이스 드라이버
실제 출력 장치실제 출력 장치
WIN32 API
응용 프로그램응용 프로그램
MFC Tutorial 145
ISLab ICE HUFSISLab ICE HUFS
DirectXDirectX
• 윈도우 3.1 의 그래픽 출력 속도 저하 극복을 위해– 게임 (WinG)
• DirectDraw– DirectX 의 그래픽 부분 라이브러리
• DirectPlay– 네트워크 게임을 만드는데 사용할 수 있는 라이브러리
• DirectSound– 사운드 기능을 제공해 주는 라이브러리
• DirectInput– 조이스틱 등의 제어에 사용할 수 있는 라이브러리
MFC Tutorial 146
ISLab ICE HUFSISLab ICE HUFS
디바이스 컨텍스트디바이스 컨텍스트
• Device Context• 윈도우 운영체제에서 출력 대상을 지칭하는 것• 논리적으로 볼 때 붓 , 펜 , 팔레트 , 종이 (비트맵 ), 폰트 등의 그림을 그리기 위한 도구의 집합
• 장치와 문관하게 GDI 함수 호출 가능• 붓과 펜은 DC 내에 하나씩 존재• GetDC & ReleaseDC
MFC Tutorial 147
ISLab ICE HUFSISLab ICE HUFS
DCDC 의 종류의 종류
• CClientDC– 윈도우의 클라이언트 영역
• CWindowDC– 윈도우 전체 디바이스 컨텍스트– 윈도우의 경계선 , 캡션 영역 등에도 그리기 가능
• CPaintDC– WM_PAINT 발생시에 사용
MFC Tutorial 148
ISLab ICE HUFSISLab ICE HUFS
윈도우 운영체제에서의 출력 절차윈도우 운영체제에서의 출력 절차
출력할 장치의 디바이스 컨텍스트의 핸들을 얻는다 .출력할 장치의 디바이스 컨텍스트의 핸들을 얻는다 .
GDI 로 앞에서 얻은 핸들에 출력을 행한다 .GDI 로 앞에서 얻은 핸들에 출력을 행한다 .
디바이스 컨텍스트를 제거한다 .디바이스 컨텍스트를 제거한다 .
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).
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 직선을 연속적으로 그리는데 처은 점과 마지막
점을 잇는다
MFC Tutorial 151
ISLab ICE HUFSISLab ICE HUFS
CDC CDC 클래스의 주요 함수클래스의 주요 함수 (2)(2)
PolyBezier 베이어 스프라인을 연속적으로 그리는데 사용InvertRect 주어진 영역을 반전하는데 사용한다 .DrawIcon 주어진 위치에 주어진 아이콘을 그려준다 .Draw3dRect 입체적인 사각형을 그리는데 사용한다 .Ellipse 타원 ( 원 포함 ) 을 그리는데 사용한다 .Pie 부채꼴을 그리는데 사용한다 .Rectangle 사각형을 그리는데 사용한다 .RountRect 모서리가 둥근 사각형을 그리는데 사용한다 .SetPixel 점을 찍는데 사용한다 .BitBlt 한 디바이스 컨텍스트의 내용을 다른 디바이스 컨텍스트로
복사한다 .TextOut 주어진 위치에 텍스트를 출력한다 .DrawText 주어진 사각형 내에 텍스트를 출력한다 .
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; // 현재 선택된 도형이 무엇인지 나타낸다 .
....
};
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;
}
MFC Tutorial 154
ISLab ICE HUFSISLab ICE HUFS
메뉴 선택 코드 추가메뉴 선택 코드 추가
• 클래스 위저를 통한 메뉴 함수 구현
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;
}
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);
}
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);}
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()
MFC Tutorial 159
ISLab ICE HUFSISLab ICE HUFS
윈도우의 입력 메시지 종류윈도우의 입력 메시지 종류• 하드웨어적인 이유로 발생하는 메시지
– 키보드– 마우스– 타이머
• 키보드 메시지나 마우스 메시지를 해석하여 발생하는 메시지– 캐릭터– 스크롤 바– 메뉴
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 : 눌려지는 것 )
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 에서와 같음
MFC Tutorial 162
ISLab ICE HUFSISLab ICE HUFS
마우스 메시지의 처리마우스 메시지의 처리
• 마우스 이벤트의 종류– WM_LBUTTONDBLCLK– WM_LBUTTONDOWN– WM_LBUTTONUP– WM_MOUSEMOVE– WM_RBUTTONDBLCLK– WM_RBUTTONDOWN– WM_RBUTTONUP
• 넘어오는 좌표 : Pixel 단위
MFC Tutorial 163
ISLab ICE HUFSISLab ICE HUFS
마우스 메시지와 윈도우마우스 메시지와 윈도우
1
2
t1
t2t3
t1 에서 t2 사이에는 1 번 윈도우로마우스 메시지가 발생하고 ,t2 와 t3 사이에는 2 번 윈도우로메시지가 발생한다 .
마우스 커서의 이동 자취
MFC Tutorial 164
ISLab ICE HUFSISLab ICE HUFS
드래그시의 문제점드래그시의 문제점
1. 드래그 시작
2. 윈도우 바깥으로 나가면 마우스 메시지가 이 윈도우에게로 발생하지 않는다 .
• SetCapture, ReleaseCapture
MFC Tutorial 165
ISLab ICE HUFSISLab ICE HUFS
타이머 입력 메시지타이머 입력 메시지
• 종류– WM_TIMER
• 주기적으로 하고 싶은 일이 있을 때 사용되는 메시지– 예 ) 워드프로세서에서 주기 저장 , 테트리스 게임에서 적당 시간 간격으로 블록을 떨어뜨릴 때
• SetTimer, KillTimer
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;}
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(); // 다른 클래스에서 ...}
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){ ...}
MFC Tutorial 169
ISLab ICE HUFSISLab ICE HUFS
타이머 사용시 주의점타이머 사용시 주의점
• PC 타이머 칩이 발생시키는 최소 시간 간격 : 55 밀리초• 메시지 큐에서 약간의 지연 발생• WM_TIMER 메시지 처리가 늦어지면 메시지가 쌓여 큐가 넘칠 수 있으므로 메시지 큐에서는 하나의 WM_TIMER 만 가능 (WM_PAINT 도 마찬가지 )
MFC Tutorial 170
ISLab ICE HUFSISLab ICE HUFS
스크롤 바 입력 메시지스크롤 바 입력 메시지
• 종류– WM_VSCROLL, WM_HSCROLL
SB_PAGEUP SB_PAGEDOWN
SB_LINEUP SB_LINEDOWN
MFC Tutorial 171
ISLab ICE HUFSISLab ICE HUFS
메뉴 입력 메시지메뉴 입력 메시지
• 종류– WM_COMMAND, WM_SYSCOMMAND
• 단축키 사용 가능• ASCII vs. VIRTKEY
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 호출 때까지
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 }}
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(); // 마우스 독점 해제 }}
MFC Tutorial 175
ISLab ICE HUFSISLab ICE HUFS
윈도우에서의 화면 복구윈도우에서의 화면 복구
1
2 2 2
1 1
1 번 윈도우에 의해 가려졌던 2 번 윈도우가 클릭된다 .
가려졌던 영역이 일단WM_ERASEBKGND메시지에 의해 지워진다 .
WM_PAINT 메시지에의해 가려졌던 영역이복구된다 .
MFC Tutorial 176
ISLab ICE HUFSISLab ICE HUFS
WM_PAINTWM_PAINT
• 화면을 복구하는데 사용– 윈도우로 출력하는데 사용되는 메시지가 아니다 .
• 윈도우가 처음 생성될 때도 한번 발생• 새로 그려야 할 영역 고려
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);
MFC Tutorial 178
ISLab ICE HUFSISLab ICE HUFS
WM_PAINTWM_PAINT
• OnDraw 함수 호출
void CView::OnPaint()
{
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
MFC Tutorial 179
ISLab ICE HUFSISLab ICE HUFS
자료 구조 유지자료 구조 유지
• 다시 그리기 위한 자료 구조 유지
class CObeditDoc : public CDocument
{
....
// Attributes
public:
CObList m_objectListCObList m_objectList;
....
}
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); }}
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); }}
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 }
};
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))
....
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() 를 부름
MFC Tutorial 185
ISLab ICE HUFSISLab ICE HUFS
명령 경로 배정명령 경로 배정 (command routing)(command routing)
• WM_COMMAND, WM_UPDATE_COMMAND_UI– CCmdTarget 로부터 계승받은 클래스만 받을 수 있다 .
• 메뉴 처리– CWnd 가 아닌 CDocument, CView 에서 처리하는 것이 자연스러움
• 예 ) 화일 저장 , 색 선택
MFC Tutorial 186
ISLab ICE HUFSISLab ICE HUFS
CCmdTarget CCmdTarget 클래스클래스
CObject
CCmdTarget
CWinApp CDocTemplate CWnd CDocument
CMultiDocTemplate CSingleDocTemplate CFrameWnd CView CDialog
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 오브젝트
MFC Tutorial 188
ISLab ICE HUFSISLab ICE HUFS
CCmdUICCmdUI 의 멤버 함수의 멤버 함수
멤버함수 이름 기능
Enable 메뉴 항목의 상태를 활성화시키거나 그레이
상태로만든다 .
SetCheck 메뉴 항목의 옆에 체크 표시를 만든다 . 툴바 버튼의경우에는 눌려진 상태로 표시한다 .
SetRadio 기능 자체는 SetCheck 와 같은데 체크 표시
대신에 표시를 사용한다 .
SetText 메뉴 항목의 텍스트를 변경한다 . 툴바 버튼에대해서는 별 의미가 없다 .
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);
MFC Tutorial 190
ISLab ICE HUFSISLab ICE HUFS
등록된 메시지등록된 메시지 (2)(2)
• 등록된 메시지– RegisterWindowMessage 함수를 이용해 메시지 값을 만든 경우– ON_REGISTERED_MESSAGE, 함수의 인자는 사용 자 정의
메시지와 동일
• 콘트롤로부터의 알림 (notification) 메시지– ON_CONTROL(알림코드 , 컨트롤 ID, 처리함수 이름 )– void 처리함수이름 (void);
MFC Tutorial 191
ISLab ICE HUFSISLab ICE HUFS
사용자 정의 메시지사용자 정의 메시지
• 종류– WM_USER(0x7fff) 부터
• 메시지 전달 방법– SendMessage
• 메시지를 발생시켜 해당 윈도우에서 그 메시지의 처리가 끝난 다음에야 리턴
– PostMessage• 메시지를 해당 윈도우가 소속된 메시지 큐에 집어넣고 바로 리턴
– 메시지 부가 인자로 다량의 데이타를 보낼 때는 사용자 데이타 타입을 WPARAM이나 LPARAM로 캐스팅해서 보낸다 .
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;
...
}
MFC Tutorial 193
ISLab ICE HUFSISLab ICE HUFS
메시지맵 매크로메시지맵 매크로
• 종류– ON_COMMAND_RANGE– ON_COMMAND_EX– ON_UPDATE_COMMAND_UI_RANGE– ON_CONTROL_RANGE
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()
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);}
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);
}
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));}
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;
}
ISLab ICE HUFSISLab ICE HUFS
스크롤 기능스크롤 기능
MFC Tutorial 200
ISLab ICE HUFSISLab ICE HUFS
목차목차
• 매핑 모드• 좌표계• 스크롤 기능• 스크롤 바• 논리 물리 좌표간 변환
MFC Tutorial 201
ISLab ICE HUFSISLab ICE HUFS
Mapping ModeMapping Mode
• 매핑 모드 (mapping mode)– 윈도우 출력함수 (GDI) 에서 출력좌표를 해석하는 방법– 디바이스 컨텍스트 (device context) 마다 존재– 디폴트 매핑 모드는 MM_TEXT
• MM_TEXT– 출력 원점이 윈도우 클라이언트 영역의 좌측 상단– 출력 원점에서 X 좌표는 오른쪽으로 증가 , Y 좌표는 아래 방향으로 증가
– 단위 : 픽셀 (pixel)– 단점 : 해상도에 따라 출력되는 내용의 크기가 달라진다 .
• 예 ) 프린트
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 을 이용하여 화면 확대 / 축소 가능
MFC Tutorial 203
ISLab ICE HUFSISLab ICE HUFS
MM_TWIPSMM_TWIPS
• 프린터에 가장 많이 사용• 1 twip 은 1/20 포인트에 해당 (1 포인트는 1/72
인치에 해당 )• 예 : 12 포인트 문자
– 12 X 20 = 240 트윕
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
윈도우 밖으로 출력되어 보이지 않는다 .
MFC Tutorial 205
ISLab ICE HUFSISLab ICE HUFS
좌표계좌표계
• 디바이스 (device) 좌표– 실제 출력 장치의 좌표
• 논리 (logical) 좌표– 출력함수에 사용하는 좌표
• 디바이스 좌표와 논리 좌표간의 변환이 필요– DPtoLP– LPtoDP
MFC Tutorial 206
ISLab ICE HUFSISLab ICE HUFS
좌표계의 원점 이동좌표계의 원점 이동
• SetWindowOrg– 논리 좌표의 원점 이동
• SetViewportOrg– 디바이스 좌표의 원점 이동
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)
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)
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
변경된 원점
MFC Tutorial 210
ISLab ICE HUFSISLab ICE HUFS
좌표계 사이의 좌표 변환좌표계 사이의 좌표 변환
• DPtoLP– 디바이스 좌표를 현재 사용중인 매핑모드에 맞춰 논리 좌표로
변환
• LPtoDP– 논리 좌표를 현재 사용중인 매핑모드에 맞춰 디바이스 좌표로
변환– 예 ) 마우스 커서의 위치를 논리 좌표로 변환하는 경우
• 마우스 좌표는 디바이스 좌표와 동일한 특성을 갖는다 . 즉 윈도우 클라이언트 영역의 좌측 상단을 기준으로 픽셀 단위의 좌표가 넘어온다 .
MFC Tutorial 211
ISLab ICE HUFSISLab ICE HUFS
단위 길이 계산단위 길이 계산
• SetWindowExt / GetWindowExt• SetViewportExt / GetViewportExt
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);
}
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
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());}
MFC Tutorial 215
ISLab ICE HUFSISLab ICE HUFS
스크롤 바스크롤 바
• 문서 영역• 엄지 (thumb)
– 현재 뷰가 보여주고 있는 부분이 편집문서에서 어디에 위치한 것인가
– 현재 보이는 부분이 전체적으로 볼 때 어느 정도의 부분을 차지하는지
• 비례 스크롤바 (proportional scrollbar)
MFC Tutorial 216
ISLab ICE HUFSISLab ICE HUFS
출력 원점의 보정출력 원점의 보정
• 스크롤이 일어나면 편집 문서와 출력함수의 원점이 달라짐– SetViewportOrg, SetWindowOrg 을 이용하여 두 원점을 하나로 만듬– 즉 CDC 클래스의 출력함수에서 사용하는 출력원점을 편집 문서의
원점으로 이동시킴– 항상 편집 문서의 원점을 바탕으로 한 좌표를 사용하도록 하면 좌표의
변환없이 문서의 좌표를 그대로 출력에 이용할 수 있음
• 이와 같은 일을 CScrollView 가 알아서 한다 .
MFC Tutorial 217
ISLab ICE HUFSISLab ICE HUFS
편집문서
윈도우
100
100
500
500300
300
MFC Tutorial 218
ISLab ICE HUFSISLab ICE HUFS
마우스 좌표와 논리 좌표의 충돌마우스 좌표와 논리 좌표의 충돌
전체문서
뷰
마우스가 넘겨주는 좌표
편집문서의 좌표
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 : ..........}
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);}
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);}
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);
ISLab ICE HUFSISLab ICE HUFS
화면 확대화면 확대 // 축소 기능축소 기능
MFC Tutorial 224
ISLab ICE HUFSISLab ICE HUFS
목차목차
• 익스텐트 (extent) 란 ?• 배율 설정• 다이얼로그 만들기• DDX/DDV• SDK 와의 비교
MFC Tutorial 225
ISLab ICE HUFSISLab ICE HUFS
익스텐트익스텐트 (extent)(extent) 란란
• 특정 매핑 모드에서의 단위 길이– MM_ISOTROPIC– MM_ANISOTROPIC
• 현재 논리 좌표와 디바이스 좌표의 단위 길이를 구하거나 새로 설정 가능
• 논리 좌표와 디바이스 좌표는 단위 길이가 다를 수 있다 . • 익스텐트 (extent) 조절GetWindowExt 논리 좌표의 단위 길이 구함GetViewportExt 디바이스 좌표의 단위 길이 구함SetWindowExt 논리 좌표의 단위 길이 설정SetViewportExt 디바이스 좌표의 단위 길이 설정
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);
• 단점– 실수 연산 시 발생할 수 있는 값의 오차 문제– 코드의 복잡도 증가
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);
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% 설정}
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);}
• 익스텐트의 값을 음수로 주면 그림의 방향이 반대가 된다 .
MFC Tutorial 230
ISLab ICE HUFSISLab ICE HUFS
다이얼로그 박스 만들기다이얼로그 박스 만들기
• 리소스 뷰에서 새로운 다이얼로그 추가
IDD_ZOOMDLG
IDC_SPINZOOMIDC_EDITZOOM
Spin Control 의 Properties
MFC Tutorial 231
ISLab ICE HUFSISLab ICE HUFS
다이얼로그 클래스 생성다이얼로그 클래스 생성
• 클래스 위저드 이용
MFC Tutorial 232
ISLab ICE HUFSISLab ICE HUFS
DDX/DDVDDX/DDV
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 ......};
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 에서 컨트롤의 값을 읽어온다 .
MFC Tutorial 235
ISLab ICE HUFSISLab ICE HUFS
UpdateDataUpdateData
• UpdateData 함수를 이용하여 DoDataExchange 함수 호출– 인자
• TRUE : 컨트롤의 값을 데이타맵의 변수로 읽어옴• FALSE : 데이타맵의 변수 값을 컨트롤로 설정
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;}
MFC Tutorial 237
ISLab ICE HUFSISLab ICE HUFS
CSpinButtonCtrlCSpinButtonCtrl
SetBuddy 스핀 콘트롤이 증감시킨 값을 표시할 윈도우를 지정이런 윈도우를 버디 (buddy) 윈도우라고 함GetDlgItem 함수를 이용하여 콘트롤 객체의 포인터를
구함
SetRange 스핀 콘트롤로 입력할 수 있는 최대값 , 최소값을 지정
SetBase 스핀 콘트롤이 버디 윈도우에 값을 출력할 때 그 값의 형식16 이면 16 진수 , 10이면 십진수
SetPos 스핀 콘트롤에 표시할 값을 지정
MFC Tutorial 238
ISLab ICE HUFSISLab ICE HUFS
OnOKOnOK
• 클래스 위저드를 이용하여 함수 생성 가능• UpdateData 호출을 해야 한다 .
– 생성시 UpdateDate(TRUE) 를 OK 버튼이 눌려지면 UpdateData(FALSE) 를 호출하여야 하나 이것은 모두 상위 클래스인 CDialog 에 만들어져 있으므로 하위 클래스에서 생성하지 않아도 된다 .
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();}
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);}
MFC Tutorial 241
ISLab ICE HUFSISLab ICE HUFS
Dialog Dialog 생성 방법생성 방법
• 모든 다이얼로그는 CDialog 로 부터 계승• 생성 방법
– Resource view 에서 dialog template 생성– Class Wizard 호출
• Control 로부터의 노티피케이션 (notification) 메시지 처리• 각각의 다이얼로그 박스 컨트롤에서 입력되는 값 저장 및 컨트롤에서의 값을 읽어 오는 데이터 멤버도 만듦 (DDX)
• 데이타 값의 범위 지정 가능 (DDV)
MFC Tutorial 242
ISLab ICE HUFSISLab ICE HUFS
Modal/ModelessModal/Modeless
• Modal– DoModal 함수 호출
• Modeless– Create 함수 호출– Dialog box를 resource view 에서 그릴 때 dialog box의
프로퍼티로 VISIBLE을 반드시 주어야 한다 .
MFC Tutorial 243
ISLab ICE HUFSISLab ICE HUFS
SDKSDK 에서의 다이얼로그 생성 방법에서의 다이얼로그 생성 방법
IDC_NUMBER
IDOK
IDCANCEL
IDD_TESTDIALOG
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()};
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 : 윈도우에 입력 포커스 설정
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) 호출}
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; }}
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);}
MFC Tutorial 249
ISLab ICE HUFSISLab ICE HUFS
모드리스 다이얼로그 생성모드리스 다이얼로그 생성
Visible 세팅
MFC Tutorial 250
ISLab ICE HUFSISLab ICE HUFS
DDX/DDV DDX/DDV 사용시사용시
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
....}
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}
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 에디트 콘트롤 관련
MFC Tutorial 254
ISLab ICE HUFSISLab ICE HUFS
다이얼로그 클래스다이얼로그 클래스
CDialog
CCommonDialog
CFileDialog
CColorDialog
CFontDialog
CFindReplaceDialog
CPrintDialog
CPageSetupDialog
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);}
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());}
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);}
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;
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;}
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();}
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;}
ISLab ICE HUFSISLab ICE HUFS
기타 기타 Dialog Box Dialog Box 구현구현
MFC Tutorial 263
ISLab ICE HUFSISLab ICE HUFS
목차목차
• Owner Draw List Box• Property Sheet
MFC Tutorial 264
ISLab ICE HUFSISLab ICE HUFS
Owner-Draw List BoxOwner-Draw List Box
• 펜 속성을 선택하는 dialog• 각 펜의 모양을 그림으로 list box 에 표현• List box 의 각 항목을 직접 그려야 함• List box 의 각 항목의 순서를 지정할 수 있어야 함• List box 에 그릴 각 항목의 크기를 알 수 있어야 함
MFC Tutorial 265
ISLab ICE HUFSISLab ICE HUFS
펜 속성 지정 다이얼로그펜 속성 지정 다이얼로그
Spin. IDC_SPINWIDTH
List Box. IDC_LISTSTYLE
Edit Box. IDC_EDITWIDTHStatic. IDC_STATIC
비트맵이들어가기
때문
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
MFC Tutorial 267
ISLab ICE HUFSISLab ICE HUFS
CLineStyleListBox CLineStyleListBox 클래스 생성클래스 생성
• CListBox로부터 계승• Owner-Draw List Box를 위하여 다음 함수를 재정의
– CompareItem• 정렬의 대상이 명확하지 않기 때문에 이를 비교하기 위한 함수
– DrawItem• 리스트 박스의 항목을 그릴 때 각 항목마다 호출되는 함수
– MeasureItem• 항목의 높이를 정하기 위해 각 항목마다 호출되는 함수
MFC Tutorial 268
ISLab ICE HUFSISLab ICE HUFS
MeasureItemMeasureItem#define COLOR_ITEM_HEIGHT 20
void CLineStyleListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem){ lpMeasureItem->itemHeight = COLOR_ITEM_HEIGHT;}
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); }
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); }}
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;}
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;
MFC Tutorial 273
ISLab ICE HUFSISLab ICE HUFS
리스트 박스에 항목 추가리스트 박스에 항목 추가
• InsertString– 절렬 순서에 관계없이 항목을 지정한 곳에 넣는다 .
• AddString– 정렬한 다음에 리스트 박스에 추가– CompareItem 함수를 호출하여 정렬하게 된다 .
• 오너드로인 경우 그 항목을 그릴 때 사용할 수 있는 값을 줌– 예제에서는 펜의 스타일을 인자로 사용
• 직접 데이타 맵을 수정해야
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
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;}
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();}
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; }
MFC Tutorial 278
ISLab ICE HUFSISLab ICE HUFS
Property SheetProperty Sheet
• 여러 개의 Property Page 로 하나의 Property Sheet 를 생성
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
MFC Tutorial 280
ISLab ICE HUFSISLab ICE HUFS
Dialog PropertiesDialog Properties
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
MFC Tutorial 282
ISLab ICE HUFSISLab ICE HUFS
파일 통계 다이얼로그파일 통계 다이얼로그IDC_REVNUM IDC_EDITTIME IDC_LASTPRINT
IDC_CREATEDATE IDC_LASTSAVE
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
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; . . .
MFC Tutorial 285
ISLab ICE HUFSISLab ICE HUFS
생성자생성자CObeditDoc::CObeditDoc(){ m_sizeDoc = CSize(500, 500); m_AppName = _T(“ 도형편집기” ); // 유니코드 혹은 ANSI 문자열}
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;}
MFC Tutorial 287
ISLab ICE HUFSISLab ICE HUFS
Property Sheet Property Sheet 생성생성
• CPropertySheet– 하나 이상의 Property Page 로 구성– 각 PropertyPage 객체를 AddPage 함수를 이용하여 등록
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;
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;}
MFC Tutorial 290
ISLab ICE HUFSISLab ICE HUFS
CProperySheet CProperySheet 클래스클래스
• 보통의 윈도우임• 일반적인 다이얼로그처럼 사용
– DoModal– Create
• Style– Child– Thin– More Styles - Disabled
CObject
CCmdTarget
CWnd
CPropertySheet
MFC Tutorial 291
ISLab ICE HUFSISLab ICE HUFS
CProperSheet CProperSheet 클래스 멤버 함수클래스 멤버 함수
• AddPage• RemovePage• GetPageCount• SetActivePage
– 특정 페이지를 전면으로– CPropertyPage* pPropPage = GetPage(0);
• OnCreate– 프라퍼티시트에 다른 콘트롤을 달때– MoveWindow : 프로퍼티시트의 크기 확대시– GetWindowRect : 현재 윈도우의 크기와 위치를 알고자 할때
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()
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) 를 호출해야}
MFC Tutorial 294
ISLab ICE HUFSISLab ICE HUFS
Wizard Wizard 모드모드
• SetWizardMode• SetWizardButton• SetFinishText
– Finish 버튼에 나타나는 타이틀을 변경하고자 할 때
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;
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();}
ISLab ICE HUFSISLab ICE HUFS
파일 파일 I/O I/O 기능의 추가기능의 추가
MFC Tutorial 298
ISLab ICE HUFSISLab ICE HUFS
목차목차
• MFC 의 파일 I/O 구조• 문서 변경 여부• CFile, CArchive• Serialize
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 클래스 내에 정의된 부분을 호출
MFC Tutorial 300
ISLab ICE HUFSISLab ICE HUFS
OnFileNewOnFileNew
• MDI 프로그램의 경우라면 -> MDI 자식윈도우 클래스와 뷰 클래스의 오브젝트를 만든다 .
• SDI 프로그램의 경우라면 -> 이미 만들어져 있는 뷰를 그대로 사용한다 .
• 다음으로 문서클래스의 오브젝트를 생성한다 .• 그리고 나서 문서클래스 (CDocument 클래스 ) 의 OnNew
Document 멤버함수를 호출한다 .• 뷰클래스의 OnInitialUpdate 함수를 호출한다 .
MFC Tutorial 301
ISLab ICE HUFSISLab ICE HUFS
OnFileOpenOnFileOpen
• 읽어 들일 파일 이름을 입력받기 위한 파일 열기 다이얼로그 박스를 띄운다 .
• MDI 프로그램의 경우라면 -> MDI 자식윈도우 클래스의 오브젝트와 뷰클래스의 오브젝트를 만든다 .
• SDI 프로그램의 경우라면 -> 이미 만들어져 있는 뷰를 그대로 사용한다 .
• 다음으로 문서클래스의 오브젝트를 생성한다 .• 파일의 내용을 읽어들이기 위해 문서클래스의 OnOpenD
ocument 멤버함수를 호출한다 .• 뷰클래스의 OnInitialUpdate 함수를 호출한다 .
MFC Tutorial 302
ISLab ICE HUFSISLab ICE HUFS
파일 열기 다이얼로그 박스파일 열기 다이얼로그 박스
MFC Tutorial 303
ISLab ICE HUFSISLab ICE HUFS
OnFileCloseOnFileClose
• 현재 문서가 저장되지 않았으면 (IsModified 함수 호출 ) 저장 여부를 묻는 메시지박스를 띄운다 . 저장하겠다고 하면 파일 이름이 있는 경우 , 문서클래스의 OnSaveDocument 함수를 불러 저장
• 저장하겠다고 했지만 파일 이름이 없는 경우 , 파일 이름을 입력받기 위한 다이얼로그 박스를 띄워 이름을 입력받아 저장한다 ( 역시 OnSaveDocument 호출 )
• 문서 클래스의 OnCloseDocument 함수를 불러 이 문서와 관련된 청소 작업을 한다 .
MFC Tutorial 304
ISLab ICE HUFSISLab ICE HUFS
OnCloseDocumentOnCloseDocument
• 현재 편집중이던 문서와 관련된 자료 구조 등을 정리하는 작업과 윈도우 등을 닫는 작업을 수행한다 .
• 자료 구조를 정리하기 위해 문서클래스의 DeleteContents 함수를 호출한다 .
MFC Tutorial 305
ISLab ICE HUFSISLab ICE HUFS
문서 변경 여부문서 변경 여부
• SetModifiedFlag– 문서가 변경되는 지점에서 SetModifiedFlag() 함수 호출
• IsModified– 문서가 변경되었는지를 알아내는 함수 . 이전에 SetModifiedFlag
함수를 불렀다면 TRUE가 아니면 FALSE가 반환된다 .– 파일을 저장하면 이 플래그는 다시 FALSE로 바뀐다 .
MFC Tutorial 306
ISLab ICE HUFSISLab ICE HUFS
OnFileSaveOnFileSave
• 편집중인 문서의 파일 이름이 있으면 문서클래스의 OnSaveDocument 함수를 불러 저장
• 편집중인 문서의 파일 이름이 없으면 파일 이름을 입력받기 위한 다이얼로그 박스를 띄워 이름을 입력받아 저장 ( 역시 OnSaveDocument 호출 )
MFC Tutorial 307
ISLab ICE HUFSISLab ICE HUFS
OnFileSaveAsOnFileSaveAs
• 파일 이름을 입력받기 위한 다이얼로그 박스를 띄운다 .• 이름이 입력되면 OnSaveDocument 함수를 불러 문서의
내용을 저장한다 .
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(); // 파일을 닫는다 .
MFC Tutorial 309
ISLab ICE HUFSISLab ICE HUFS
CArchiveCArchive
• 저장될 대상과 실제 저장 매체 (storage medium) 사이의 매개체 역할을 수행
• 저장 매체의 특성에 관계없이 CArchive 클래스의 멤버 함수만을 이용하여 입출력– 파일 , 소켓 , OLE
파일
네트웍CArchive클래스
저장대상이 되는자료구조나
전송대상이 되는자료구조
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가 리턴
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 }}
MFC Tutorial 312
ISLab ICE HUFSISLab ICE HUFS
직렬화직렬화 (serialization)(serialization)
• 디스크에 저장하거나 읽는 작업• 디스크에 저장할 때는 순서대로 데이터를 저장해야 하므로
직렬화라는 이름을 붙임• Linked list 의 멤버 함수에도 Serialize 함수가 있음 .
– 이것은 각 노드에 있는 객체의 Serialize 함수를 불러준다 .
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;
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);}
MFC Tutorial 315
ISLab ICE HUFSISLab ICE HUFS
CLine::SerializeCLine::Serialize
void CLine::Serialize(CArchive& ar){ CDrawObject::Serialize(ar); if (ar.IsLoading()) { } else { }}
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; }}
MFC Tutorial 317
ISLab ICE HUFSISLab ICE HUFS
CObject::SerializeCObject::Serialize
• 호출하지 않으면 파일 입출력이 제대로 동작 안함• CObject 클래스에 관한 정보를 저장하고 읽어들이는
기능• 이 정보를 바탕으로 도형클래스를 따로 생성하지 않아도
자동으로 도형클래스를 생성하고 있다 .
MFC Tutorial 318
ISLab ICE HUFSISLab ICE HUFS
Serialize Serialize 함수 호출 순서함수 호출 순서CDocument 의 Serialize 함수
도형리스트의 Serialize 함수호출(m_objectList.Serialize)
도형별로 Serialize 함수를 호출
일단 프로그램전체에 걸친 정보를 입출력 한다
MFC Tutorial 319
ISLab ICE HUFSISLab ICE HUFS
SetModifiedFlagSetModifiedFlag
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);
}}
MFC Tutorial 321
ISLab ICE HUFSISLab ICE HUFS
DeleteContentsDeleteContents
void CObeditDoc::DeleteContents() {
while(!m_objectList.IsEmpty()){
delete m_objectList.RemoveHead();}CDocument::DeleteContents();
}
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 함수를 호출하여 입출력해야 한다 .
ISLab ICE HUFSISLab ICE HUFS
프린터 관련 명령프린터 관련 명령
MFC Tutorial 324
ISLab ICE HUFSISLab ICE HUFS
목차목차
• MFC 의 프린트 구조• MFC 에서의 미리보기 구조
MFC Tutorial 325
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 에서의 프린터에서의 프린터
• 관련 메뉴– Print, Print Setup, Print Preview
• CPrintDialog
MFC Tutorial 326
ISLab ICE HUFSISLab ICE HUFS
프린트 관련 메뉴프린트 관련 메뉴
메뉴메뉴 기능기능 처리함수 이름 및 정의 위치처리함수 이름 및 정의 위치Print 프린터로 인쇄 OnFilePrint(CView)Print Setup프린터의 환경 설정 OnFilePrintSetup(CWinApp)Print Preview 프린터 출력을 화면 OnFilePrintPreview(CView)
으로
MFC Tutorial 327
ISLab ICE HUFSISLab ICE HUFS
화면과 프린터출력의 비교화면과 프린터출력의 비교
• 거의 모든 함수가 표준화되어 있다 .– 화면 출력에도 사용하는 그래픽 디바이스에 관계없이 단일한
하나의 함수 집합 (GDI, Graphic Device Interface) 을 이용할 수 있다 . - CDC 클래스
– 그외• ODBC(Open Database Connectivity)• MCI(Media Control Interface)
– 프린터 출력시에도 CDC 클래스를 이용하여 출력
• 차이점– 여러 장의 종이에 출력– 출력 상태 표시
MFC Tutorial 328
ISLab ICE HUFSISLab ICE HUFS
프린터 작업시 뷰클래스가 해야 하는 일프린터 작업시 뷰클래스가 해야 하는 일
• 최대 몇페이지나 출력할 수 있는지 , 어느 페이지서부터 어느 페이지까지 출력할 것인지를 결정 - 프린터 다이얼로그 박스를 띄워 선택을 입력받는다 .
• 특정 페이지를 출력하도록 요구받았을 때 그 부분을 그릴 수 있어야 한다 . 필요하다면 머리말과 꼬리말을 출력할 수 있어야 한다 .
• 출력에 필요한 폰트와 다른 GDI 자원들을 할당하고 제거할 수 있어야 한다 .
• 프린터 다이얼로그를 띄워 프린터 DC 를 구함• 일반적인 코딩은 가상함수로 제공
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 에서 할당했던 리소스들을 제거한다 .
MFC Tutorial 330
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 의 프린트 기능의 구현의 프린트 기능의 구현
• 뷰클래스의 다음 함수의 구현을 어떻게 만드느냐에 달림– OnPreparePrinting– OnBeginPrinting– OnEndPrinting– OnPrepareDC– OnPrint
• 프린트 다이얼로그를 띄우고 프린트 DC 를 만들고 프린트 취소 다이얼로그를 띄우고 하는 일은 MFC 가 알아서 수행
MFC Tutorial 331
ISLab ICE HUFSISLab ICE HUFS
프린트 제어를 위한 프린트 제어를 위한 CDC CDC 클래스의 함수클래스의 함수
• Escape Sequence 함수• StartDoc
– 새로운 문서의 출력이 나감을 알린다 .
• StartPage– 새로운 페이지의 출력이 나감을 알린다 .
• EndPage– 페이지의 출력이 끝났음을 알린다 .
• EndDoc– 문서의 출력이 종료되었음을 알린다 .
MFC Tutorial 332
ISLab ICE HUFSISLab ICE HUFS
CPrintInfo(1)CPrintInfo(1)
• OnPreparePrinting 함수의 인자로 넘어옴• 프린터와 관련한 사용자의 입력을 저장하거나 프린트 , 미리보기 관련 정보를 보관
• 예– 프린트 할 페이지의 범위– 현재 프린트하고 있는 페이지의 번호– 출력용지의 크기 등
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; // 범위};
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 의 경우 : 스크롤 상황에 맞추어 원점을 이동
MFC Tutorial 335
ISLab ICE HUFSISLab ICE HUFS
View View 클래스 수정클래스 수정
• 출력이 나가는 종이의 높이 지정
class CObeditView : public CScrollView{ ... int m_nPaperHeight; ...};
MFC Tutorial 336
ISLab ICE HUFSISLab ICE HUFS
OnPreparePrintingOnPreparePrinting
BOOL CObeditView::OnPreparePrinting(CPrintInfo* pInfo){ pInfo->m_nNumPreviewPages = 1; // 미리보기 할 페이지 수를 1 로 정함 return DoPreparePrinting(pInfo);}
• 사용자가 출력 용지를 설정하기 전까지는 몇 페이지에 걸쳐 출력이 일어날지 모름
• 워드 프로세서의 경우 미리 출력 용지를 결정하므로 pInfo->SetMaxPage 함수를 호출하여 출력할 페이지를 결정할 수 있음
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);}
MFC Tutorial 338
ISLab ICE HUFSISLab ICE HUFS
OnBeginPrinting(2)OnBeginPrinting(2)
• CDC::SetDeviceCaps 함수를 이용하여 출력 용지의 높이를 구함
• 프린트 중에 사용할 GDI 리소스 (펜 , 폰트 , 브러쉬등 )를 할당해 두는 일을 하는 곳– 페이지 출력시마다 리소스 할당을 하지 않기 위해– 즉 , 프린트 작업에 들어가기에 앞서 전체적으로 필요한 GDI
리소스를 할당– OnEndPrinting 에서 이 리소스들을 제거
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 : 래스터 카메라. . . .
MFC Tutorial 340
ISLab ICE HUFSISLab ICE HUFS
OnEndPrintingOnEndPrinting
• 본 예제에서는 할당한 리소스들이 없으므로 OnEndPrinting 에서 할 일이 없음
void CObeditView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){}
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); }}
MFC Tutorial 342
ISLab ICE HUFSISLab ICE HUFS
OnPrepareDCOnPrepareDC 에서의 주의점에서의 주의점
• 인자로 넘어오는 CDC 클래스의 오브젝트에 대한 포인터에 대하여 출력을 할 경우– 윈도우 출력의 경우 : 출력이 나감– 프린터 출력의 경우 : 출력이 안 나감– 프린터 출력시에는 OnPrepareDC 의 호출이 끝난 다음에야 새 페이지의 출력을 프린터 드라이버에 알리는 CDC::StartPage 를 호출하기 때문 . 그 전에 호출한 것은 아무런 소용이 없다 .
• 두번째 인자 pInfo– NULL : 화면 출력– NULL 이 아님 : 프린트 출력 . 이때 프린트 쪽의 원점을 뒤로
이동하여 다음 페이지 출력– pInfo->m_nCurPage : 현재 출력이 나갈 페이지의 번호를 가리킴
MFC Tutorial 343
ISLab ICE HUFSISLab ICE HUFS
전체 편집문서
출력용지
3. 종이의 출력원점을전체편집문서의 원점과맞추어주기위해 그만큼뒤로 이동하고OnDraw 를 호출한다 .그러면 1페이지부터N-1 페이지까지의출력은 종이밖으로출력되기 때문에무시된다 .
1. N 페이지만프린트로 출력이나가야한다 .
2. 출력원점의보정없이 OnDraw 를호출하면 항상1 페이지가 출력된다 .종이의 원점에 전체편집문서의원점이 바로 대응되기 때문이다 .
1 페이지
N 페이지
SetViewportOrgSetViewportOrg 를 이용한 페이지의 출력를 이용한 페이지의 출력
MFC Tutorial 344
ISLab ICE HUFSISLab ICE HUFS
편집 문서의 수정편집 문서의 수정
• 출력 용지를 늘리기위해
CObeditDoc::CObeditDoc(){ m_sizeDoc = CSize(1500, 5000); m_AppName = _T(“ 도형편집기” );}
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); }}
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 를 이용하여
오차를 없앰
MFC Tutorial 347
ISLab ICE HUFSISLab ICE HUFS
프린터로 아무것도 출력이 안되는 이유프린터로 아무것도 출력이 안되는 이유
출력용지
출력원점
+X-X
+Y
-Y
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); }}
MFC Tutorial 349
ISLab ICE HUFSISLab ICE HUFS
MFCMFC 에서의 미리보기 구조에서의 미리보기 구조
• MFC 에서는 기본적인 프린터 출력루틴만 제대로 만들어졌다면 미리보기는 자연스럽게 구현이 된다 .
• 차이점– 미리보기는 윈도우로 출력되기 때문에 프린터 출력과는 달리 WM_PAINT 를 처리할 수 있어야 한다 .
– 사용자의 입력을 기다렸다가 페이지를 출력한다 .
• CPreviewDC– 두개의 DC 를 사용
• 프린터 DC 를 흉내낸 DC• 출력이 실제로 표시되는 윈도우를 나타내는 DC
MFC Tutorial 350
ISLab ICE HUFSISLab ICE HUFS
CPreviewView CPreviewView 클래스클래스
• CPreviewView 클래스– 메인 프레임의 자식 윈도우로 존재
• CPrintInfo 의 m_bPreview 가 TRUE이면 미리보기 중
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; } 한 페이지 모드일
때 나갈 문자열
두 페이지 모드일 때 나갈 문자열분리자
ISLab ICE HUFSISLab ICE HUFS
분리 윈도우분리 윈도우
MFC Tutorial 353
ISLab ICE HUFSISLab ICE HUFS
목차목차
• 분리 윈도우• 동적 분리 윈도우• 정적 분리 윈도우
MFC Tutorial 354
ISLab ICE HUFSISLab ICE HUFS
정적 동적 분리 윈도우정적 동적 분리 윈도우 (1)(1)
동적 분리 윈도우 정적 분리 윈도우
MFC Tutorial 355
ISLab ICE HUFSISLab ICE HUFS
정적 동적 분리 윈도우정적 동적 분리 윈도우 (2)(2)
MFC Tutorial 356
ISLab ICE HUFSISLab ICE HUFS
분리 윈도우의 구현분리 윈도우의 구현
• CSplitterWnd 클래스를 이용– 다음 클래스의 member data 로 존재
• CFrameWnd• CMDIChildWnd
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); ....
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);}
분리 윈도우의 행갯수
분리 윈도우의 열갯수
동적 분리윈도우의창의
최소 크기
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 );
MFC Tutorial 360
ISLab ICE HUFSISLab ICE HUFS
pContextpContext
struct CCreateContext{ m_pNewViewClass // 생성하고자 하는 새로운 뷰의 CRuntimeClass m_pCurrentDoc // 새로 생성한 뷰가 연관된 이미 존재하는 도큐먼트 객체 m_pNewDocTemplate // 새로운 MDI 프레임 윈도우의 생성과 연관된 // 도큐먼트 템플릿 m_pLastView // 이미 존재하는 뷰 m_pCurrentFrame // 현재 생성하고 있는 프레임 윈도우
MFC Tutorial 361
ISLab ICE HUFSISLab ICE HUFS
다른 윈도우에 갱신이 안 되는 경우다른 윈도우에 갱신이 안 되는 경우
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);
}}
자신의 문서 내용을 출력하고 있는 모든 뷰에게 내용을 다시 그리라고 하는데 사용하는 함수
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 함수 호출
MFC Tutorial 364
ISLab ICE HUFSISLab ICE HUFS
OnUpdateOnUpdate
• UpdateAllView 는 각 뷰 클래스의 OnUpdate 함수 호출– 각각의 OnUpdate 함수는 Invalidate 를 호출하여 윈도우 영역
전체를 다시 그린다 .– 이를 방지하기 위해 수정해야 한다 . 즉 OnUpdate 에 갱신된
정보를 포함하여 이 정보에 따라 그림을 수정해야 함
• 예제에서 OnUpdate 가 불리는 경우– 새로운 객체를 삽입하였을 때 객체 삽입을 알려주어야 할 때– 배율 설정시에 모든 뷰에 배율이 변경되었다는 것을 알려주어야
할 때
MFC Tutorial 365
ISLab ICE HUFSISLab ICE HUFS
분리 윈도우의 배율의 불일치분리 윈도우의 배율의 불일치
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; } } }
새로운 객체 추가
한 뷰에서 다른뷰로 배율을 전파
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);
}}
삽입된 객체
객체 사입
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(); }
배율 변경
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();}
배율 변경
MFC Tutorial 370
ISLab ICE HUFSISLab ICE HUFS
정적 분리 윈도우정적 분리 윈도우
• 프레임 클래스의 OnCreateClient 함수를 오버라이드 해서 구현
• 서로 다른 뷰를 가지도록 만든다 .
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;}
MFC Tutorial 372
ISLab ICE HUFSISLab ICE HUFS
세개의 정적 분리 윈도우 생성세개의 정적 분리 윈도우 생성
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));
ISLab ICE HUFSISLab ICE HUFS
MFC MFC 디버깅 매크로와 디버깅 매크로와 예외 처리예외 처리
MFC Tutorial 375
ISLab ICE HUFSISLab ICE HUFS
목차목차
• 메시지 출력• ASSERT 매크로• 오브젝트의 유효성 검사• 예외 처리
MFC Tutorial 376
ISLab ICE HUFSISLab ICE HUFS
컴파일 옵션컴파일 옵션
• Debug 모드– _DEBUG
• Release 모드– NODEBUG
MFC Tutorial 377
ISLab ICE HUFSISLab ICE HUFS
디버그 모드로 수행디버그 모드로 수행
MFC Tutorial 378
ISLab ICE HUFSISLab ICE HUFS
디버깅 모드로 수행디버깅 모드로 수행
• 한 문장씩 수행• 함수 안으로 들어가 수행• 수행중인 함수밖으로• 커서 위치까지 수행• Call Stack
MFC Tutorial 379
ISLab ICE HUFSISLab ICE HUFS
TRACE TRACE 매크로매크로
• 디버그 창으로 메시지 출력• 디버그 모드로 컴파일할 때만 수행
TRACE(“Sample TRACE Output : %d == 0x%x\n”, i, i);
MFC Tutorial 380
ISLab ICE HUFSISLab ICE HUFS
ASSERT ASSERT 매크로매크로
• 어떤 조건을 검사하여 거짓이면 그 위치 (파일 이름과 행번호 ) 를 출력하는데 사용
• 주로 프로그램 개발 기간 중에 함수의 인자로 들어온 값이 맞게 들어왔는지의 여부를 판단하는데 사용
• 디버그 모드로 컴파일 시에만 수행
ASSERT(prt != NULL);
MFC Tutorial 381
ISLab ICE HUFSISLab ICE HUFS
VERIFY VERIFY 매크로매크로
• ASSERT 매크로와 동일• 단 , 디버그 모드가 아닌 Release 모드로 컴파일 시에도
수행
VERIFY(LoadAccelTable(hWnd, “MainWnd”));
MFC Tutorial 382
ISLab ICE HUFSISLab ICE HUFS
오브젝트의 유효성 검사오브젝트의 유효성 검사
• CObject 클래스의 후손에만 적용• AssertValid
– 현재 오브젝트의 데이터멤버가 올바른 값을 갖고 있는지의 여부를 검사
• Dump– 현재 오브젝트의 데이터멤버를 출력하는데 사용
• 디버그 모드에서만 수행– _DEBUG
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);}
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 탭으로 출력
MFC Tutorial 385
ISLab ICE HUFSISLab ICE HUFS
예외처리예외처리
체크 되어야
ISLab ICE HUFSISLab ICE HUFS
공통 컨트롤공통 컨트롤 (Common Control)(Common Control)
MFC Tutorial 387
ISLab ICE HUFSISLab ICE HUFS
목차목차
• Common Control 의 종류• Control Message 처리• Animation Control• Progress Control• Slider Control• List Control• Tree Control
MFC Tutorial 388
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 종류의 종류 (1)(1)
• CAnimateCtrl• CHeaderCtrl
• CHotKeyCtrl• CImageList• CListCtrl
MFC Tutorial 389
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 종류의 종류 (2)(2)
• CProgressCtrl
• CRichEditCtrl– OLE 복합문서 컨테이너
MFC Tutorial 390
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 종류의 종류 (3)(3)
• CSliderCtrl
• CSpinButtonCtrl
• CStatusBarCtrl
• CTabCtrl
MFC Tutorial 391
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 종류의 종류 (4)(4)
• CToolBarCtrl
• CToolTipCtrl
• CDragListBox• CCheckListBox
MFC Tutorial 392
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 종류의 종류 (5)(5)
• CTreeCtrl
MFC Tutorial 393
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control
• Common contorl 의 code 는 윈도우의 system\COMCTL32.DLL 에 있다 .– 각 컨트롤에 대한 윈도우 프로시저– 각 컨트롤을 위한 윈도 클래스를 등록하는 코드가 포함– 등록 코드는 DLL 이 로드될 때 호출– 다이얼로그를 초기화할 때 프로그램에서는 다이얼로그
리소스에서 기호 클래스 이름을 사용해서 DLL 에 있는 윈도 프로시저를 연결
– 이렇게 함으로써 프로그램에서는 컨트롤의 윈도를 소유하게 되지만 , 코드는 DLL 에 존재
• 공통 컨트롤은 Class Wizard 가 멤버 변수를 제공하지 않음
• 공통 컨트롤들로부터 통지 메시지들을 매핑하는 일에는 Class Wizard 를 이용할 수 있다 .
MFC Tutorial 394
ISLab ICE HUFSISLab ICE HUFS
Common ControlCommon Control 의 사용의 사용
• Common control 역시 컨트롤이기 때문에 dialog box에서 사용할 수 있다 .
• 보통 윈도우의 자식 윈도우로 존재할 수 있다 .
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
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 이 된다 .
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(...); ....
MFC Tutorial 398
ISLab ICE HUFSISLab ICE HUFS
Notification Message Notification Message 처리처리
• Control 은 자신에게 무슨 일이 발생하면 부모 윈도우에게 알려준다 .– Control 이 dialog box 에서 사용된 경우라면 이 때 부모윈도우는
dialog box 가 된다 .
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 구조체
포인터이거나 이를 포함하는 더 큰 구조체
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 에 따라 달라지는 것 두 종류가 존재
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 메모리가 부족해서 하던 일을 끝내지 못할 때
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;
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 을 리턴
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 를
처리하고자 할 때– 매번 처리함수를 따로 만들지 않고 하나의 처리함수를 정의해 사용
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;}
적절한 타입으로캐스팅 하여 사용
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)
MFC Tutorial 407
ISLab ICE HUFSISLab ICE HUFS
예제예제
• 프로젝트 이름 : CmmCtrl• SDI• 데이터베이스 옵션은 주지 않음• Toolbar, status bar, 프린트 관련 옵션도 선택 않음
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
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 을 이용해도 됨
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 의 생성여부
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; }}
MFC Tutorial 412
ISLab ICE HUFSISLab ICE HUFS
CCmmCtrlViewCCmmCtrlView 의 생성자의 생성자 // 소멸자 변경소멸자 변경
CCmmCtrlView::CCmmCtrlView(){ m_bListCtrl = FALSE; m_bTreeCtrl = FALSE; m_bSlider = FALSE;}
CCmmCtrlView::~CCmmCtrlView(){ CheckWnd();}
MFC Tutorial 413
ISLab ICE HUFSISLab ICE HUFS
Animation ControlAnimation Control
• AVI 파일을 디스플레이• 오디오가 있는 파일은 지원안 함• 즉 하나의 Video Stream 만 있는 avi file 만 지원• 오디오를 지원하는 클래스 : OLE 컨트롤 중
마이크로소프트 멀티미디어 컨트롤
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); // }
MFC Tutorial 415
ISLab ICE HUFSISLab ICE HUFS
Animation ControlAnimation Control 의 속성의 속성
ACS_CENTER 애니메이션 컨트롤의 중앙에서 AVI 파일을 플레이
한다 . 이 스타일이 주어지지 않으면 AVI 파일의크기에 맞춰 애니메이션 컨트롤의 크기가
변경된다위의 예에서 바로 이 스타일을 사용하였다 .
ACS_TRANSPARENT AVI 파일의 배경색 대신에 원래 애니메이션 컨트롤의 자리에 있던 배경색을 사용한다 .
ACS_AUTOPLAY AVI 파일이 오픈됨과 동시에 플레이되도록 하며플레이가 계속 반복되도록 한다 .
MFC Tutorial 416
ISLab ICE HUFSISLab ICE HUFS
CAnimateCtrlCAnimateCtrl 의 멤버 함수의 멤버 함수
Open AVI 파일이나 리소스를 읽어들여 첫 프레임을 윈도우에 표시한다 .Play AVI 클립을 플레이한다 .
첫번째 인자와 두번째 인자가 플레이할 프레임을 지칭시작 프레임일 경우 0을 마지막 프레임일 경우 -1(0xFFFF)마지막 인자는 반복횟수
Seek AVI 클립의 지정된 프레임을 윈도우에 표시한다 .Stop AVI 클립의 표시를 중단한다 .Close 오픈된 AVI 클립을 닫아 버린다 .
MFC Tutorial 417
ISLab ICE HUFSISLab ICE HUFS
Animation ControlAnimation Control 의 의 Notification CodeNotification Code
ACN_START AVI 클립의 플레이가 시작되었음을 알린다 .ACN_STOP AVI 클립의 플레이가 다 끝났음을 알린다 .
• WM_COMMAND 메시지 발생• ON_CONTROL 매크로 사용
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);}
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 : 이미지 리스트의 크기가 변할 때 쓰이는 단위
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);
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
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 에서 읽어 파일에 추가
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 로 사용할 수 있다 .
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 를 통해 이루어진다 . 연산자를 이용해 이 스타일과 함께
지정해준다 .
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); // 초기위치를 지정한다
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);}
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 에서 지정된 값만큼
진행시킨다 .
MFC Tutorial 428
ISLab ICE HUFSISLab ICE HUFS
Slider ControlSlider Control
• 불연속적인 값이나 어떤 범위의 값을 입력받고자 할 때• WM_HSCROLL(혹은 WM_VSCROLL) 로 특이하게 notifica
tion code 를 발생시킨다 .
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);}
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 스타일과 함께
사용되면 오른쪽 , 왼쪽 모두에 눈금을 붙인다 .
MFC Tutorial 431
ISLab ICE HUFSISLab ICE HUFS
TBS_LEFT 수직 슬라이더의 좌단에 눈금을 붙인다 .TBS_BOTH 수평 슬라이더이면 위아래에 눈금을 붙이고 수직
슬라이더이면 왼쪽 , 오른쪽에 눈금을 붙인다 .TBS_ENABLESELRANGE 이 스타일을 주면 영역을 선택하는 것이
가능하다 . 선택 영역의 시작과 끝 눈금이 삼각형 모양의 눈금으로 변하고 그 사이의영역이 하이라이트된다 .
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 의 슬라이더 위치를 새로 설정한다 .
MFC Tutorial 433
ISLab ICE HUFSISLab ICE HUFS
CSliderCtrlCSliderCtrl 의 멤버 함수의 멤버 함수 (2)(2)
GetTic 주어진 눈금의 위치를 얻어온다 .GetTicPos 주어진 눈금이 위치한 좌표를 얻어온다 .SetTic 눈금이 생길 위치를 지정한다 .SetTicFreq 눈금이 생길 위치를 위치 단위로 지정한다 . 예로 들면 2 로
지정하면 0, 2, 4... 의 위치에 눈금이 생긴다 .ClearTics Slider control 에서 모든 눈금을 제거한다 .
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 에 뒤이어 항상 발생한다 .
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); }}
MFC Tutorial 436
ISLab ICE HUFSISLab ICE HUFS
List View ControlList View Control
• 리스트의 한 아이템이 여러 항목으로 구성될 수 있다 .• 항목의 일부로 비트맵이 들어갈 수 있다 .• 각 항목의 제목을 나타내기 위해 헤더 (Header) 컨트롤이라는 것을 내부적으로 사용할 수 있다 .
• 항목마다 사용되는 아이콘을 따로 리스트로 유지하는데 앞서 살펴 본 image list 를 사용하는 것이다 .
MFC Tutorial 437
ISLab ICE HUFSISLab ICE HUFS
List View ControlList View Control 의 타입의 타입
아이콘뷰 LVS_ICON 스타일을 지정하면 된다 . 각 항목은 아이콘과 그 밑의 레이블로 구성된다 . 각 항목은 드래깅으로 다른 위치에 갖다놓을 수 있다 .
스몰아이콘뷰 LVS_SMALLICON 스타일을 지정하면 된다 . 각 항목은16X16 아이콘과 그 오른쪽의 레이블로 구성된다 . 각
항목은 드래깅으로 다른 위치에 갖다 놓을 수 있다 .
리스트뷰 LVS_LIST 스타일을 지정하면 된다 . 각 항목은 서브 항목별로 정렬되어 디스플레이된다 .
리포트뷰 LVS_REPORT 스타일을 지정하면 된다 . LVS_NOCOLUMNHEADER 스타일이 명시되지 않으면헤더 컨트롤이 사용되어 레이블과 각 서브 항목의
타이틀을표시할 수 있다 . 리스트뷰에서와 마찬가지로 각 항목들은서브 항목별로 정렬되어 디스플레이된다 .
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 항목들이 윈도우 영역의 크기를 넘어가도 스크롤이
안되도록 한다 .
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 사용되는 아이콘리스트를 얻어온다 .
MFC Tutorial 440
ISLab ICE HUFSISLab ICE HUFS
CListCtrl CListCtrl 클래스의 주요 멤버 함수클래스의 주요 멤버 함수 (2)(2)
SetImageList 사용되는 icon list 를 지정한다 .GetItemCount 항목수를 얻어온다 .GetStringWidth 주어진 문자열을 표시하는데 필요한 최소한의 컬럼폭을
돌려준다 .GetColumnWidth 리스트뷰와 리포트뷰의 컬럼폭을 얻어온다 .SetColumnWidth 리스트뷰와 리포트뷰의 컬럼폭을 설정한다 .GetItemText 리스트뷰의 특정항목의 레이블이나 부항목의 텍스트를
얻어온다 .SetItemText 리스트뷰의 특정항목의 레이블이나 부항목의 텍스트를
설정한다 .
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);
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);
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;
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);
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;}
MFC Tutorial 446
ISLab ICE HUFSISLab ICE HUFS
SetImageListSetImageList
• 두번째 인자– LVSIL_NORMAL 큰 아이콘을 갖는 image list– LVSIL_SMALL 작은 아이콘을 갖는 image list– LVSIL_STATE 상태를 나타내는 아이콘을 갖는 image list
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 필드를 사용할 것이다 .
MFC Tutorial 448
ISLab ICE HUFSISLab ICE HUFS
항목항목
• LV_ITEM 스트럭처를 초기화 한 다음 InsertItem 함수 호출
• 부항목은 InsertItem 함수의 리턴값 (nActualIndex) 을 갖고 LV_ITEM 스트럭처를 초기화한 다음에 SetItem 함수 호출
• 원하는 부항목 수만큼 반복
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;
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– 항목의 외양을 나타냄
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 가 보내진다 .
MFC Tutorial 452
ISLab ICE HUFSISLab ICE HUFS
실행 모습실행 모습
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 현재 선택 항목이 다른 항목으로 변경된 다음
발생
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;}
MFC Tutorial 455
ISLab ICE HUFSISLab ICE HUFS
Tree View ControlTree View Control
• 윈도우 스타일TVS_HASLINES 각 항목간 ( 부모 자식간 ) 을 선으로 이어준다 .TVS_LINESATROOT 루트를 만들어 최상위 레벨의 항목들과 연결
시켜준다 .TVS_HASBUTTONS 각 항목의 좌측에 버튼을 붙여준다 .TVS_EdITLABELS Tree view control 의 레이블을 편집 가능하게 만듦
MFC Tutorial 456
ISLab ICE HUFSISLab ICE HUFS
CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (1)(1)
InsertItem 새로운 항목을 삽입한다 .DeleteItem 항목 하나를 삭제한다 .DeleteAllItems 모든 항목을 삭제한다 .Expand 주어진 항목의 자식 항목들을 모두 펼친다 .SelectItem 주어진 항목을 현재 선택 항목으로 만든다 .EditLabel 주어진 항목의 레이블을 편집 가능하게 만든다 .HitTest 주어진 위치에 있는 항목의 핸들을 얻어온다 .SortChildren주어진 항목의 자식 항목들을 정렬한다 .SortChildrenCB 주어진 항목의 자식 항목들을 정렬한다 . 따로 정렬함수를
제공해 주어야 한다 .EnsureVisible 지정된 항목이 트리뷰 컨트롤 내에서 보이도록 만든다 .GetCount 항목의 총수를 얻어온다 .GetIndent 부모 항목과 자식 항목 간의 거리를 픽셀단위로 얻어온다 .SetIndent 부모 항목과 자식 항목 간의 거리를 픽셀단위로 설정한다 .
MFC Tutorial 457
ISLab ICE HUFSISLab ICE HUFS
CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (2)(2)
GetImageList 트리뷰 컨트롤과 관련된 이미지리스트를 얻어온다 .SetImageList 트리뷰 컨트롤과 관련된 이미지리스트를 설정한다 .ItemHasChildren 주어진 항목이 자식 노드를 갖고 있는지 여부를
알려준다 .GetNextSiblingItem 트리구조에서 주어진 항목과 같은 레벨의 다음 항
목을 얻어준다 .GetPrevSiblingItem 트리구조에서 주어진 항목과 같은 레벨의 이전 항
목을 얻어준다 .GetParentItem 트리구조에서 주어진 항목의 부모 항목을 얻음GetSelectedItem 현재 선택된 항목이 무엇인지 알려준다 .GetRootItem 루트항목이 무엇인지 알려준다 .GetItem 주어진 트리뷰 항목의 속성을 돌려준다 .SetItem 주어진 트리뷰 항목의 여타 속성을 설정한다 .GetItemText 주어진 트리뷰 항목의 텍스트를 돌려준다 .
MFC Tutorial 458
ISLab ICE HUFSISLab ICE HUFS
CTreeCtrlCTreeCtrl 의 멤버함수의 멤버함수 (3)(3)
SetItemText 주어진 트리뷰 항목의 텍스트를 설정한다 .GetVisibleCount 현재 트리뷰 컨트롤에서 보이는 항목의 수를 돌려
준다 .GetItemImage 주어진 항목의 이미지가 무엇인지 알려준다 .SetItemImage 주어진 항목의 이미지를 변경한다 .GetItemRect 주어진 항목을 둘러싸는 사각형이 무엇인지 얻음
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;
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);
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;}
MFC Tutorial 462
ISLab ICE HUFSISLab ICE HUFS
SetImageListSetImageList
• 두번째 인자– TVSIL_NORMAL 항목의 선택시와 보통 때의 모습만을 담고 있은 경우– TVSIL_STATE 선택 유무 말고 사용자 나름대로의 기준으로 항목 상태
를 지정하려는 경우
IDI_ICON1
IDI_ICON2
IDI_ICON3
MFC Tutorial 463
ISLab ICE HUFSISLab ICE HUFS
실행모습실행모습
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;
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;
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을 지정해야
MFC Tutorial 467
ISLab ICE HUFSISLab ICE HUFS
TV_ITEM(3)TV_ITEM(3)
• pszText : 항목에 들어갈 텍스트– LPSTR_TEXTCALLBACK 이면 항목의 디스플레이 책임은 부모
윈도우가 진다 . 이때 부모 윈도우에게 TVN_SETDISPINFO 메시지가 넘어간다 .
• cchTextMax : pszText 필드가 가리키는 버퍼의 크기
MFC Tutorial 468
ISLab ICE HUFSISLab ICE HUFS
TV_ITEM(4)TV_ITEM(4)
• iImage : 정상상태에 있을 때에 해당하는 이미지 (이미지리스트에서의 인덱스 )
• iSelectedImage : 선택상태에 있을 때에 해당하는 이미지• cChildren : 자식 항목을 가질 것인지 여부를 지정
– 0 : 자식 항목이 없음– 1 : 자식 항목이 있음
• lParam : 이 항목과 관련해서 따로 저장하고 싶은 32비트 값을 지정할 때 사용
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 현재 선택된 항목이 다른 항목으로 변경된 다음
발생
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;}