Visual C

++
Programming
숭실대학교
정보과학대학원
김상일
(C) 1998 Sang Il Kim

hava@shinbiro.com

Visual C++ Programming

1

C++ 의 특징
? C++은 1980년 미국 벨 연구소의 Bjarne Stroustrup 박사에 의해 개발
? 1980년 발표 당시에는 “C with class” 라는 이름으로 발표
? “C++”라는 이름은 1983년부터 사용되기 시작

C
함수, 포인터
구조체, 공용체

C++
함수 ?연산자의 다중정의
참조자, 클래스?
(C) 1998 Sang Il Kim

풍부한 연산자
◉ 객체지향 프로그래밍 ◉
Visual C++ Programming

2

C++ 의 특징

(C) 1998 Sang Il Kim

? Bjarne Stroustrup

Visual C++ Programming

3

C++ 의 특징
기능

class

클래스를 정의 ?선언

new

메모리 영역을 할당

delete

메모리 영역을 해제

friend
inline

클래스를 다른 클래스 ?함수의 ”친구”로 선언
인라인 함수를 정의 ?선언

operator

연산자를 다중정의

this

해당 클래스 객체 자신을 가리키는 포인터

private

클래스의 비공개 멤버를 선언

protected

클래스의 보호 멤버를 선언

public

클래스의 공개 멤버를 선언

virtual

클래스의 가상 함수를 선언

(C) 1998 Sang Il Kim

예약어

Visual C++ Programming

4

C++ 의 특징
? I/O 스트림
? 기존의 표준 C stream인 stdin, stdout, stderr, stdprn 외에도 C++에서는
cout, cin등의 지정된 stream들이 있어 이 stream과 insertor(<<),
extractor(>>)함수를 이용한 입출력 방식을 주로 사용.
? Insertor(<<)함수를 이용한 출력
? cout stream과 insertor함수를 사용할 경우에는 iostream.h 파일을

C

C++

#include <stdio.h>
void main(void)
{
printf(“Hello World!\n”);
}

#include <iostream.h>
void main(void)
{
cout << “Hello World!\n”;
}
Visual C++ Programming

(C) 1998 Sang Il Kim

include 해야 한다.

5

C++ 의 특징

? 데이터 항목을 하나 이상 표시
#include<iostream.h>
void main(void)
{
int my_int = 5;
float my_float = 5.333;
cout << "The value of my_int is : " << my_int << ”\n";
cout << "The value of my_float is : " << my_float << ”\n";
}

(C) 1998 Sang Il Kim

? 변수선언
? 변수 사용 위치에서 선언하고 선언과 동시에 그 값을 초기화
? #include<iostream.h>
void main()
{
int hap=0;
for(int i=0; i<=100; i++)
hap += i;
cout << hap << “\n”;
}
상수를 알아서 찾아줌

Visual C++ Programming

6

C++ 의 특징
? 전역 식별 연산자(::) (Global Scope Resolution Operator)
:: 변수명칭
해당 변수는 전역변수임을 의미

(C) 1998 Sang Il Kim

#include<iostream.h>
int suja=123;
void main()
{
int suja=10;
cout << suja << ”\n";
cout << ::suja << ”\n";
}

Visual C++ Programming

7

C++ 의 특징

? 키보드로 부터 데이터를 입력
#include<iostream.h>
void main(void)
{
int my_int;
float my_float;
cin >> my_int;
cin >> my_float;
cout << “my_int = “ << my_int << “\nmy_float = “
<< my_float << “\n”;
}
Visual C++ Programming

(C) 1998 Sang Il Kim

? Extractor(>>)함수를 이용한 입력
? cin stream과 extractor함수를 사용할 경우에는
iostream.h 파일을 include 해야 한다.

8

C++ 의 특징
? new와 delete 연산자
C

C++

#include<stdio.h>
void main(void)

#include<iostream.h>
void main(void)

{

{
int *i = new int;

i = malloc(sizeof(int));

//int *i = new int[10];

*i = 10;

i=10; // 10개의 배열을 동적으로 할당

printf(“%d”, *i);

cout << i;

free(i);

delete i;

(C) 1998 Sang Il Kim

}

int *i;

}
Visual C++ Programming

9

Enumerator
? 열거형 정의 및 선언법
? 정의
: 사용자가 정의하는 특별한 명칭을 갖는 정수들의 집합체를 말한다.
? 선언법
enum [태그명] {열거요소, 열거요소,… };
enum color screen;
( 변수 정의 )
enum color { black, blue, green, cyan, red } screen;
enum은 열거형을 나타내는 예약어이다.
color은 열거형의 tag명
black, blue, green, cyan, red는 열거요소
screen이라는 열거형은 black, blue, green, cyan, red로 구성된다.
그 외의 요소를 갖게 되면 에러 발생

Visual C++ Programming

(C) 1998 Sang Il Kim

예) enum color { black, blue, green, cyan, red }; ( 형틀 정의 )

1
0

Enumerator
? 열거형 선언자
? 선언자

변수, 배열, 포인터, 함수 등이 올 수 있다.

? 일반변수

enum color rainbow; /* color형을 가질 수 있는 변수 */

? 배열

enum color rainbow[10]; /* 배열의 요소가 color형 변수 */

? 포인터 변수

enum color rainbow, *rp;
rp = &rainbow;
/* color형 변수의 주소를 가리키는 color형 포인터 변수 rp */

/* color형을 돌려주는 함수 */
(C) 1998 Sang Il Kim

? 열거형을 돌려주는 함수
enum color rain();

Visual C++ Programming

11

Enumerator
? 열거형의 특징
◐ 열거 요소는 내부적으로 정해진 상수로 표현된다.
예) enum color { black, blue, green, cyan, red };
black=0, blue=1, green=2, cyan=3, red=4

◐ 열거형 변수에 열거형에 해당하는 정수를 대입할 수 있다.
예) enum color { black=5, blue, green=15, cyan, red=25 } screen;
screen=6; /* 열거 요소의 정수값으로 치환 가능 */
screen=25;
◐ 열거형 상수는 기억영역을 확보하지 않는다.
예) enum color { black, blue, green, cyan, red };
black++, &blue, --green ( X ) /* 변수가 아니고 상수이기 때문 */
Visual C++ Programming

(C) 1998 Sang Il Kim

◐ 열거 요소에 부여하는 정수는 임의적이어도 된다.
예) enum color { black=5, blue, green=15, cyan, red=25 };
black=5, blue=6 green=15, cyan=16, red=25로 처리된다.

1
2

typedef
? typedef와 #define과의 차이점
◐ typedef는 컴파일러에 의해, #define은 전처리기에 의해 처리된다.
◐ 표현상의 순서에 차이가 있다.
예) #define INTEGER int
typedef int INTEGER;
◐ #define은 구문표현의 변화이지만, typedef는 의미상의 변화이다.

바뀌어서 컴파일된다.
◐ 열거형과 typedef을 이용하여 소스를 작성하면 더욱 보기 쉽고 이해하기
쉬운 프로그램을 작성할 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

#define INTEGER int
위 선언문은 전처리기가 처리하고 나면 없어지고, INTEGER는 모두 int로

1
3

Reference
? 레퍼런스 방식의 함수호출
? C++는 기본적으로 파라미터를 값(value)이 아닌 레퍼런스로 보내도록
함수를 설정해 준다.
? 파라미터의 명칭은 &를 선언하기만 하면 된다.
#include<iostream.h>
void load_a(char &the_char); // C : void load_a(char *the_char);
void main()
{
char my_char='z';
load_a(my_char);
cout << my_char << ”\n";
}

// C : load_a(&my_char);

(C) 1998 Sang Il Kim

void load_a(char &the_char) // C : void load_a(char *the_char)
{
the_char = 'a';
// C : *the_char = 'a';
}
Visual C++ Programming

1
4

C++ 의 특징
void func(int inja1=1, inja2=100)
{

함수의 실제내용;

}
#include <iostream.h>
void func(int a=10, int b=20, int n=5)
{
for(int i=a; i<=b; i+=n) // a ? b 사이의 정수를 n간격으로 표시
cout << i;
cout << “\n”;
}
void main()
{
func();
// func(10, 20, 5)와 동일
func(5);
// func(5, 20, 5)와 동일
func(5, 30);
// func(5, 30, 5)와 동일
func(30, 40, 2);
}
Visual C++ Programming

(C) 1998 Sang Il Kim

? 함수의 내정인자

1
5

객체지향 프로그래밍(Object-Oriented Programming)

? 데이터 추상화 (Data Abstraction)
? OOP에서는 데이터와 그 데이터를 처리하는 함수(Function)들이 하나의 독립된
객체에 캡슐화(Encapsulation)되어있다. 즉, OOP에서는 데이터 추상화를
클래스라 불리우는 코드 단위로 사용하여 표현하는데, 하나의 클래스는 유사한
속성과 기능을 가지는 여러 개의 객체들을 나타낸다.
? 클래스가 단순한 데이터 구조(Data Structure)와 다른 점은 필요한
데이터 구조의 정의뿐 아니라, 이 데이터 구조 위에서 작동하는 프로그램 코드,
즉, 함수들도 함께 가지고 있다는 점이다.
? 데이터 추상화는 여러 장점이 있지만, 무엇보다도 한 객체가 가지고 있는
데이터나 값은 그 객체만이 검색, 수정할 수 있다는 점이다.
? 이를 정보 감춤(Information Hiding)이라고 표현하는데, 이런 식으로 개발된
프로그램은 모듈간의 간섭이 없어 나중에 코드를 수정하거나 추가할 때
유리하다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 객체지향 프로그래밍(OOP)은 구조적 프로그래밍(Structured Programming)의
개발 이래로 소프트웨어 기술 발전 사에서 매우 큰 혁명으로 여겨지고 있다.
OOP에 관한 여러 가지 정의와 해석이 존재하지만, 일반적으로
추상화(Data Abstraction), 상속성(Inheritance) 및 다형성(Polymorphism)등이
그 주요 특성으로 알려져 있다.

1
6

객체지향 프로그래밍(Object-Oriented Programming)
? 상속성 (Inheritance)
? OOP에서는 새로운 클래스를 정의할 때, 이미 만들어 놓은 클래스의
속성(데이터의 구조와 함수들의 정의)을 상속 받고 필요한 부분만 추가할 수
있는데, 이를 클래스의 상속성이라 한다.

? 이때 새로 생긴 클래스는 Sub-Class, 이전의 모태가 된 클래스를
Super-Class라 한다.

? 상속성을 사용하면 유사한 클래스들 간의 공통된 속성을 하나의
Super-Class에 정의하여 Sub-Class가 공유할 수 있으므로 전체 코드
크기도 줄고 프로그램 구성도 간단해진다.

어려움을 겪는데, 이는 주어진 문제를 객체지향적으로 분석
(Object-Oriented Analysis)하는 연습을 통하여 해결할 수 있다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? C프로그래머들이 C++프로그래밍을 접할 때 이 상속성을 설계하는데 종종

1
7

객체지향 프로그래밍(Object-Oriented Programming)
? 다형성(Polymorphism)
? 대부분의 구조적 프로그래밍 언어에서는 하나의 함수가 하나의 기능을
가진다.
? 그러나 OOP에서는 하나의 함수가 사용되는 상황(Context)에 따라서
여러 가지 기능을 가질 수 있다.
? 즉, 클래스의 상속성 구조에서 여러 개의 클래스 사이에 동일한 이름의
함수들이 정의될 수 있고, 각 함수의 기능(Behavior)은 소속된 클래스의
성격과 용도에 맞게 세분화 될 수 있다.
? 예로서 그래픽 어플리케이션에서 원, 사각형, 자유형 등 여러 가지 그림
? 이때 OOP에서는 하나의 MOVE라는 이름의 함수를 종류별로 정의하고,
각 형태의 그림 객체마다 이를 옮기는 최적의 방법으로 각 함수를
정의할 수 있다.

Visual C++ Programming

(C) 1998 Sang Il Kim

객체를 움직이는 MOVE라는 함수를 생각할 수 있다.

1
8

객체 (Object)
? 소프트웨어에 대한 객체지향적 시각
? 객체 + 객체 = 프로그램
? 데이터 + 함수 = 객체
? 정의
? 특정 데이터와 관련된 함수들을 가지는 프로그램 모듈
? 실세계 영역에 있는 정보, 물건, 사물, 개체, 개념 등을 표현함
? 객체 = 속성(Attributes) + 행위(Behaviors)
= 변수(Variables) + 함수(Methods)
? 자동차
(C) 1998 Sang Il Kim

? 객체의 특징
? 캡슐화 (Encapsulation)
? 정보은폐 (Information Hiding)
Visual C++ Programming

1
9

캡슐화 (Encapsulation)
? 특정 데이터와 관련된 함수들을 한 덩어리로 묶는다.
? 문제영역의 개념화 및 추상화를 효과적으로 지원함.

class Point {
int xPosition;
int yPosition;
colorType color;
public:
void move(int x, int y);
void setColor(colorType c);
?
?
?
?

데이터

관련 함수들

(C) 1998 Sang Il Kim

? C++ 의 캡슐화 장치

}
Visual C++ Programming

2
0

정보 은폐 (Information Hiding)
? 캡슐내부의 정보를 외부에 감추는 것을 의미한다.
? 캡슐화는 관련된 것들 주변에 캡슐을 씌우는 것.
? 처리하려는 데이터 구조와 함수에 사용된 알고리즘 등을 외부에서
직접 접근하지 못하도록 한다.
? 캡슐화 그 자체가 캡슐 안의 내용들이 외부에 보이지 않는 것을 의미
하지는 않는다.
? 콘택600

? 외부 객체들이나 프로그램들이 접근할 수 있는 데이터와 함수들을
정의하여
? 외부에서 이 인터페이스를 통해서 정보를 검색하거나 함수를
실행하도록 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 인터페이스

2
1

정보 은폐 (Information Hiding)
? C++ 의 인터페이스 장치

데이터

class Point {

public:
void move(int x, int y);
void setColor(colorType c);
?
?
?
?
}

외부 인터페이스

블랙박스
xPosition: 10
yPosition: 20
color: blue

move (int, int);
setColor (colorType);

?
?
?
?
Visual C++ Programming

(C) 1998 Sang Il Kim

int xPosition;
int yPosition;
colorType color;

관련된 함수들

2
2

객체 (Object)
? 정의
? 객체란 캡슐화와 정보은폐의 개념을 프로그램에서
효과적으로 사용할 수 있도록 한 장치임.
? 객체의 조건
? 상태(State)를 가져야 한다.
? 행위(Behavior) 를 가져야 한다.

(C) 1998 Sang Il Kim

? 고유의 식별자(Identity)를 가져야 한다.

Visual C++ Programming

2
3

복합 객체 (Composite Object)
? 한 객체가 다른 객체들을 포함하고 있는 경우
? Point and Circle
? class Point {
int xPosition, yPosition;
public:
void move(int x, int y);
}
? class Circle {
Point center;
int radius;
public:
void move(int x, int y) {
center.xPosition += x;
center.yPosition += y;
center.move(x, y);
}}

(C) 1998 Sang Il Kim

? 작은 객체를 조합하여 보다 큰 객체로 조립해 가는 과정

// Error
// Error
// Okay
Visual C++ Programming

2
4

메시지 (Message)
? 객체 접근 방법
? 한 객체는 다른 객체에게 메시지를 보내어 교류한다.
? 메시지 교환 (Massage Passing)
? 메시지 교환 (Message Passing)은 객체들 사이에 정보를 교환할 수 있는
유일한 수단이다.
? 한 객체가 다른 객체의 함수를 부르는 과정을 메시지 교환(Message Passing)
이라고 한다.
? 메시지 형태
? 수신객체, 함수명, 함수의 Arguments
(C) 1998 Sang Il Kim

? 수신객체는 이 메시지를 받을 객체를 나타낸다.
? <receiver>.<operation_name> <arguments>
? myPoint.move(10, 5);
myPoint.setcolor (blue);
Visual C++ Programming

2
5

클래스 (Class)
? 개념
? 클래스는 객체의 타입(Object Type)이다.
? 정의
? 클래스는 유사한 객체들이 갖는 공통된 데이터와
함수들을 정의한 객체의 기본 규격(Specification)이다.
? 유사한 객체들의 타입을 정의한다.

? 어떤 클래스에서 생성된 객체 혹은 한 클래스에 속하는 각각의 객체.
? 한 클래스에 속한 모든 객체들은 같은 종류의 데이터와
함수들을 가진다.
? 생성된 각 객체는 클래스에서 정의된 변수들에 대한
메모리를 할당 받는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 인스턴스(Instance)

2
6

클래스 (Class)
? 직원 클래스
class Employee {
char *name;
positionType position;
int salary;
phoneNumberType phoneNumber;
?
?
?
?
public:
void promote(positionType newPosition);
void changeSalary(int newSalary);
?
?
?
?
(C) 1998 Sang Il Kim

}
? Employee YoungHee();
혹은 Employee* YoungHee = new Employee();
Visual C++ Programming

2
7

상속 (Inheritance)
? 개념
? 한 클래스가 여러 종류의 서브 클래스로 세분화된다.
? 그래픽 클래스는 선, 다각형, 원 등으로 세분화
? 학생 클래스는 학부학생과 대학원생등으로 세분화

? 기존의 클래스 위에 필요한 데이터와 함수들을 추가하여
새로운 클래스를 만드는 경제적인 방법.
? 재사용성 증대

? 슈퍼 클래스 (Super class, Base class)
? 서브 클래스 (Subclass, Derived class, Extended class)
? 클래스 상속 구조 (Class Inheritance Hierarchy)
Visual C++ Programming

(C) 1998 Sang Il Kim

? 용어(Terminology)

2
8

상속 (Inheritance)
? 대학 인사관리 시스템
Person

Student

Faculty

Temporary

Staff

? class Student : public Person{… }
Visual C++ Programming

(C) 1998 Sang Il Kim

Employee

2
9

다중 상속 (Multiple Inheritance)
? 다중 상속
? 한 클래스가 여러 개의 슈퍼클래스를 가지는 경우
? 여러 슈퍼 클래스들로부터의 재사용
? class Graduate : public Student, public Faculty{… }
Person
Employee

Faculty

Graduate

Temporary

Visiting Faculty

Staff
(C) 1998 Sang Il Kim

Student

Temp.Staff

UnderGrad
Visual C++ Programming

3
0

추상 클래스 (Abstract Class)
? 서브 클래스들의 공통된 특성을 추출하여 묘사하기 위

클래스
? Printer Software
? 모든 종류의 프린터가 공통으로 가지는 특성을
추상클래스에 정의
? 변수 : 프린터의 상태, 속도

? 프린트마다 인쇄하는 방법이 다르므로 이 추상 클래스
안에서는 Print라는 함수를 완전히 구현할 수 없다.
? 실제 구현은 여러 서브클래스에서 각 프린터 종류에
맞게 하면 된다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 함수 : print();

3
1

추상 클래스 (Abstract Class)
? 추상 클래스 ‘Printer’

도트 매트릭스
프린터

레이저
프린터

잉크젯
프린터

Visual C++ Programming

(C) 1998 Sang Il Kim

(추상클래스)
Printer

3
2

다형성 (Polymorphism, 다양한 형태)
? 복수의 클래스가 하나의 메시지에 대해 각 클래스가
가지고 있는 고유한 방법으로 응답할 수 있는 능력.
? 별개로 정의된 클래스들이 같은 이름의 함수를 별도로
가지고 있어 하나의 메시지를 각기 다른 방법으로 해석
하여 필요한 함수를 수행할 수 있는 것을 말한다.
? 가상함수(Virtual Function)를 사용하여 구현
? Compile time Polymorphism
(C) 1998 Sang Il Kim

? 함수, 연산자의 Overloading
? Run time Polymorphism
? 가상함수를 이용한 함수의 Overriding
Visual C++ Programming

3
3

다형성 (Polymorphism)
? Printer 함수의 다중정의
텍스트 파일

포맷 파일

그래픽 파일

print();

print();

print();

private

protected

public

항상 접근할 수 없다

private로 상속받으면
private
protected로 상속받으면
protected
public로 상속받으면
protected

private로 상속받으면
private
protected로 상속받으면
protected
public로 상속받으면
public
Visual C++ Programming

(C) 1998 Sang Il Kim

? 파생클래스에서의 멤버 접근 권한

3
4

Class Library
? Template (템플릿)
? 템플릿은 임의의 데이터 유형에 재사용할 수 있는 범용 코드를 허용함으로

클래스 계열이 컴파일러에 의해 어떻게 생성되는가를 정의하는 역할을 한다.
? 템플릿은 컴파일할 때에 클래스 그룹들을 컴파일러가 어떻게 구성해야 하는
가를 정의하며, 필요할 때마다 특정 유형을 만드는 데 사용할 수 있는 범용
정의를 컴파일러가 만들도록 한다.
? 템플릿은 여러 개의 데이터 유형에 적용할 수 있는 범용 코드를 작성할 수
있기 때문에 작업을 더 쉽게 수행할 수 있다.
? STL은 뛰어난 융통성과 훌륭한 성능을 바탕으로 많은 곳에 적용할 수 있는
범용 데이터 구조와 알고리즘을 제공함으로써 완전히 재사용이 가능한
범용 프로그래밍을 가능하게 하고 있다.
? 마이크로소프트 비주얼 C++과 볼랜드 C++은 자신의 가장 최신 컴파일러
버전에 STL 버전들을 구현하고 있다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? STL(Standard Template Library, 표준 템플릿 라이브러리)

3
5

(C) 1998 Sang Il Kim

“If you can dream it, you can do it”
꿈꿀 수 있다면, 달성이 가능하다

Visual C++ Programming

3
6

CHAPTER 1

(C) 1998 Sang Il Kim

마이크로소프트 윈도우와
Visual C++

Visual C++ Programming

3
7

CHAPTER 1
? 윈도우 그래픽 디바이스 인터페이스(GDI)
? 장치 독립적인 인터페이스를 제공.
? 사용자는 디바이스 컨텍스트(device context)라는 데이터 구조체를
참조하는 GDI 함수를 호출한다.
? 윈도우는 물리적인 장치에 디바이스 컨텍스트 객체를 맵핑하고,
적합한 입출력 명령을 보낸다.

? 리소스 기반 프로그래밍

(C) 1998 Sang Il Kim

? 리소스 파일에는 Bitmap, Icon, Menu, Dialog Box, String 등이
포함된다.

Visual C++ Programming

3
8

? 윈도우에서 제공되는 리소스 데이터
? Accelerator
사용자가 빠르게 명령을 호출할 수 있도록 해주는 단축키.
? Bitmap
그래픽 이미지를 이진 파일의 형식으로 변환하여 사용되는 이미지.
? Cursor
스크린 상에서 마우스의 현재 위치를 나타내 주는 32?32 Pixel
크기의 비트맵.
? Dialog Box
? Font
? Icon
? Menu
? String Table 스트링은 단순한 문자열들의 집합.
주로 메뉴, 다이얼로그 박스, 에러 메시지를 나타내기 위해 사용된다
? User-defined Resource 프로그래머가 응용 프로그램에 지원하기
위해 자신만의 독특한 데이터를 정의한 것을 말한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 1

3
9

CHAPTER 1
? 프로그램 코드

*.c OR *.cpp

? 리소스 데이터

*.rc

? 리소스 데이터는 응용 프로그램 안에서 공통적으로 사용되는 정적 데이터들의 집합.
? 리소스 편집기(App Studio)를 사용하여 프로그램에 필요한 리소스 데이터를
작성한다.
? *.rc

리소스 컴파일러

Link

*.EXE

? 리소스 데이터는 일반적으로 프로그램의 .EXE 파일에 포함되어 있지만,
보통의 프로그램 데이터 세그먼트에 존재하지 않고 별도의 장소에 보관된다.
? 리소스 데이터는 필요로 할 때만 메모리에 적재된다.
? 대부분의 리소스 데이터는 읽기 전용 데이터이다.
(C) 1998 Sang Il Kim

? Visual C++의 요소(Components)
? 개발시스템
? C스타일의 Win32 프로그램을 작성하는 방법.
? C++과 MFC를 사용하는 방법.
Visual C++ Programming

4
0

CHAPTER 1
Source Code
(Sample.cpp)
C++
Compiler
Object File
(Sample.obj)
Linker

(C) 1998 Sang Il Kim

Executable
Program
(Sample.exe)

◐ 도스상에서의 실행 파일 생성 과정 ◑
Visual C++ Programming

4
1

CHAPTER 1
Developer Studio
Code compilation
Windows header
files

Resource compilation

Source
files

Runtime header
files

Resource
script file(RC)
Resource.h

MFC header
files

Bitmaps, icons, and
other resources
Resource Compiler
Resource file
(RES)

Compiler

Windows, runtime, and
MFC libraries

Linker

Executable
(EXE)

◐ 윈도우 상에서의 실행 파일 생성 과정 ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

OBJ files

4
2

CHAPTER 1
? Microsoft Developer Studio97과 구현과정
? Project
? 서로 연관되어 있는 파일들의 집합
? 이 파일들이 컴파일과, 링크 과정을 거쳐 실행 가능한 프로그램이나
DLL로 만들어진다.
?
?
?
?

컴파일러 옵션, 링크 옵션 저장.
소스 파일간의 상호 연관성을 표현.
Visual C++ 4.0 : (.mak)
Visual C++ 5.0 : (.dsp)

? 기존의 프로젝트에 대한 작업
? Developer Studio에서 워크 스페이스 파일(.dsw)을 열고난 후
작업.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Make file

4
3

CHAPTER 1
설명

APS
BSC
CLW

리소스 뷰 지원
소스 브라우저 정보 파일
클래스 위저드 지원

DSP
DSW
MAK
NCB
OPT
PLG
CPP
H

프로젝트 파일 *
워크 스페이스 파일 *
외부 메이크 파일
클래스 뷰 지원
워크스페이스 환경설정 보유
빌드 로그 파일
소스 파일
헤더 파일
Visual C++ Programming

(C) 1998 Sang Il Kim

파일(확장자)

4
4

CHAPTER 1
? VC++의 CASE(Computer-Aided Software Engineering) 도구
? AppWizard (자동 코드 생성기)
? 프로그램의 틀을 자동적으로 생성해 주는 도구
? AppStudio (Resource Editor, 리소스 편집기)
? 자원(Resource)들을 편집하는 도구
? 사용자 인터페이스 요소들(메뉴, 다이얼로그, 단축키 등)을
시각적으로 디자인할 수 있도록 도와 준다.
? AppStudio에서 시각적으로 디자인된 요소들을 실제 프로그램
코드와 연결시키는 작업을 한다.
? 새로운 클래스를 정의한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? ClassWizard (자동 코드 생성기)

4
5

CHAPTER 1
? C/C++ Compiler
? Visual C++ 컴파일러는 C 소스 코드와 C++ 소스 코드의 확장자에
따라, 프로젝트 파일에 설정된 소스 코드를 어떠한 방식으로 컴파일
할 것인가를 결정하기 때문에 C 구조로 작성된 C 소스 코드와 C++
구조로 작성된 C++ 소스 코드를 모두 컴파일 할 수 있다.
? Resource Compiler

? Linker
? 링커는 컴파일러로 만들어진 .obj 파일과 .res 파일을 읽고,
LIB 파일과 결합하고, DLL 과 연결시켜 EXE 파일을 작성한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? RC파일을 컴파일해서 링커시에 필요한 .res 파일을 생성한다.
?.rc : 텍스트 파일
?.res : 이진파일

4
6

CHAPTER 1
? Debugger
? 중단점(BreakPoint)을 설정하여 해당 부분에 멈추거나, 한 문장씩 코드를
실행하며 값들을 추적해 볼 수 있다.
? 디버깅하기 위해서는 컴파일러, 링커 옵션에서 디버깅 정보를 생성 해내도록
설정해야 한다.
? Debug 모드
프로그램 코드를 생성하고 이것을 실행 파일로 만드는 Build 과정에서
디버깅 정보가 실행 파일에 포함되도록 한다. 그러나 실행 파일에
디버깅 정보가 포함되기 때문에 실행 파일이 원래보다 크게 생성된다.

일반적으로 정상적으로 실행될 수 있는 프로그램을 완성하기 전까지는
디버깅을 해야 하므로 Debug 모드에서 빌드 과정을 수행하고, 완전한
프로그램이 완료되었을때는 Release 모드로 전환하여 실행 파일을 생성한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Release 모드

4
7

CHAPTER 1
? 윈도우 진단 도구 (Windows Diagnostic Tools)
? Spy++ : 윈도우 메시지를 감시
DevStudio\Vc\bin\Spyxx.exe
? MFC Tracer : 응용 프레임워크 진단 매크로
DevStudio\Vc\bin\Tracer.exe

? Source Browser
? 파일 수준이 아닌 클래스나 함수 수준에서 어플리케이션을
분석하거나 편집할 수 있다.
?Call Graph/Caller Graph (함수의 호출관계도)
?Derived Class Graph/Base Class Graph (클래스 계층도)
?File Outline (파일 개요)
Visual C++ Programming

(C) 1998 Sang Il Kim

?Definitions and References (정의와 참조)

4
8

CHAPTER 1
? Online Help
? Developer Studio 97에는 HTML에 기초를 둔 도움말 시스템이
내장되어 있다.
?설명서 방식 : Help - Contents를 선택하면
Workspace window가 InfoView모드로 전환된다.
?Topic별 방식 : Help - Search를 선택하면주제와 항목이 표시된다.
?단어별 방식 : Help - Search - Query tab - 단어입력
?F1이용 : 커서를 원하는 함수, 클래스 이름으로 이동해서 F1키를
(C) 1998 Sang Il Kim

누른다.

Visual C++ Programming

4
9

CHAPTER 1
? 컴포넌트 갤러리(Component Gallery)
? 서로 다른 프로젝트간에 소프트웨어 컴포넌트를 공유할 수 있다.
?ActiveX 컨트롤
Visual C++ 4.0 : OLE Control(OCX)
?C++ 소스 모듈
리소스나 소스파일을 추가할 수 있다.
?Developer Studio 컴포넌트
프로젝트에 특정 기능을 추가할 수 있는 툴을 포함하고 있다.
? Microsoft Foundation Class Library 버전 4.21
(C) 1998 Sang Il Kim

? 어플리케이션 프레임워크를 정의하는 라이브러리.
? ActiveX Template Library(ATL)
? MFC와는 분리된 ActiveX 컨트롤을 생성하기 위한 툴.
Visual C++ Programming

5
0

MFC (Microsoft Foundation Class)
? Microsoft가 자체적으로 개발한 윈도우용 C++ 프로그램 라이브러리

C++ Application

MFC

(C) 1998 Sang Il Kim

Windows API

◐ 윈도우 API를 캡슐화한 MFC ◑
Visual C++ Programming

5
1

MFC (Microsoft Foundation Class)
? 장점
? 효율성(Efficiency)
? 안전성(Safety)
? 확장성(Extensibility)
새로운 기능이나 객체 안에 내용의 추가가 쉽도록 만들자는 개념

? 재사용성(Reusability)
이미 개발된 코드를 다른 필요한 곳에 부품처럼 재사용이 가능하도록 하여
소프트웨어의 생산성을 향상시킴

? 유지보수성(Maintainability)
프로그램에 에러가 발생하거나 새로운 운용 환경에 적응시킬 때, 혹은 시스템의
기능을 개선하고자 하는 등 프로그램에 변경이 가해져야 하는 경우,
프로그램을 수정하기 용이한 정도
서로 다른 기종 간에 호환성이 실현되는 것으로서 그 보다는 좀더 강한 의미.
프로그램 등의 변동 없이 바로 어느 한 기종에서 다른 기종으로 옮겨서 사용하는 것이
가능한 것. 어느 한 컴퓨터 환경에서 다른 컴퓨터 환경으로 옮겨 갈 때 변경의 정도가
적을수록 이식성이 높은 것이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 이식성(Portability)

5
2

MFC
? 윈도우와 관련된 클래스
? Window management : 윈도우 관리
? Graphic Device Interface(GDI) : 그래픽 장치 인터페이스
? Multiple Document Interface(MDI) : 다중 문서 인터페이스
? Menus : 메뉴
? Dialog boxes : 대화상자
? Windows controls : 윈도우 컨트롤
? OLE(Object Linking & Embedding) : 오브젝트 연결과 삽입
? Application services : 어플리케이션 서비스

Visual C++ Programming

(C) 1998 Sang Il Kim

? Windows common dialogs : 윈도우용 일반 다이얼로그

5
3

MFC
? 일반적인 목적의 클래스
? Run-Time Type Information : 실행 타입 정보
? Object Persistence : 객체 보존성
? Collection Classes : 집합체 클래스
? Strings : 문자열
? Files : 파일
? Time and Date : 시간과 날짜
(C) 1998 Sang Il Kim

? Exception Handling : 예외 처리

Visual C++ Programming

5
4

MFC
? 구조적인 클래스
? Commands : 명령 관련 클래스들
? Documents and Views : 도큐먼트와 뷰
? Printing and Print Preview : 프린트와 프린트 미리 보기
? Dialog Data Exchange and Validation(DDX/DDV) :

다이얼로그 데이터 교환, 확인
(C) 1998 Sang Il Kim

? Context-Sensitive Help : 도움말

Visual C++ Programming

5
5

MFC
? 비주얼 클래스
? Form View : 형태 뷰
? Edit View : 편집 뷰
? Scrolling View : 스크롤 뷰
? Splitter Window : 분할 뷰
? Toolbars and Status bar : 툴 바와 상태 바

다이얼로그 바와 다른 컨트롤 바
? VBX Controls : VBX 컨트롤
Visual C++ Programming

(C) 1998 Sang Il Kim

? Dialog Bar and other Control Bars :

5
6

MFC
? 데이터 베이스 클래스
? Database Engine classes : 데이터베이스 엔진 클래스
? Record Field Exchange(RFX) : 레코드 필드 교환
? Record View : 레코드 뷰

? OLE 클래스
? Visual Editing servers : 비주얼 편집 서버
? Drag and Drop Structured Storage : 끌어다 놓기
? OLE Automation servers : OLE 자동화 서버
? OLE Automation clients : OLE 자동화 클라이언트
Visual C++ Programming

(C) 1998 Sang Il Kim

? Visual Editing containers : 비주얼 편집 컨테이너

5
7

MFC
? 유저 인터페이스 클래스
? Enhanced toolbars : 기능이 추가된 툴 바
? Miniframe windows : 미니프레임 윈도우
? Tabbed dialogs : 탭 다이얼로그(탭에 의해 포커스 이동)

? Win32에 대한 지원
? New Win32 APIs : Win32 API 함수들 지원

(C) 1998 Sang Il Kim

? Multithreading : 멀티 Thread 관련된 클래스
? Unicode support : 유니코드 지원
? Shared 32-bit DLLs : 공유된 32비트 DLL
Visual C++ Programming

5
8

MFC
? MFC 3.1과 3.2에서 포함된 내용
? Windows 95 Common Controls : 윈도우 95 컨트롤
? Simple MAPI : 단순한 MAPI
? Windows Sockets : 윈도우 소켓
? Swap-tuned DLL versions : 최적화된 DLL 지원

? Containment of OLE Controls : OLE 컨트롤
? DAO(Data Access Objects) : MFC 자체 데이터베이스 엔진
? Simplified Windows 95 Common Controls :
간단한 윈도우95 공통 컨트롤
? Windows 95 Common Dialogs : 윈도우95 일반 다이얼로그
? Thread synchronization Objects : 스레드 동기화 오브젝트
Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC 4.0에 포함된 내용

5
9

CWinApp
CDocTemplate

CCmdTarget

CFrameWnd

CSingleDocTemplate
CMultiDocTemplate

CWnd
CView
CScrollView

CClientDC

CFormView

CWindowDC

CDC

CPaintDC

CObject

CMetaFileDC

CRecordView
CEditView

GetEditControl
GetPrinterFont
GetSelectedText
SetPrinterFont

CPen
CBrush

CGdiObject

CFont

SetTabStops
?
(C) 1998 Sang Il Kim

CBitmap
CPalette
CRgn

◐ MFC 클래스 라이브러리 마인드 맵(Mind Map) ◑
Visual C++ Programming

6
0

MFC
? 기본 클래스(CObject)
? 거의 대부분의 클래스가 이 클래스로부터 파생되었다.
? 기본 클래스는 데이터를 직렬화(Serialize)하고 Run-time 클래스 정보를
얻어내거나 Debugging시에 출력 진단의 역할을 담당한다.
? 윈도우 어플리케이션 구조 클래스
? MFC에서 중요한 클래스들은 모두 포함되어 있다.
? CWinApp, CWnd, CDocument, CView 등이 있다.
? 윈도우 어플리케이션 프로그램의 뼈대 역할을 하면서 기본적인 기능을
1. 윈도우 어플리케이션 클래스
? CWinApp : 윈도우 어플리케이션 오브젝트를 생성시키는 기본 클래스.
어플리케이션 프로그램을 초기화 시키고, 실행하거나 종료하는
기능을 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

수행한다.

6
1

MFC
? 윈도우 어플리케이션 구조 클래스
2. 명령 관련(Command-Related) 클래스

? CCmdTarget : 윈도우 메시지를 받고, 응답하는 오브젝트 클래스들의 기본클래스
? CCmdUI : 메뉴 또는 컨트롤바와 같은 오브젝트를 업데이트 하는데 쓰인다.
예) 오브젝트의 상태 변경(enable/disable, check/uncheck)
3. 도큐먼트와 뷰 클래스

? CDocTemplate : 도큐먼트 템플릿에 대한 기본 클래스
?CSingleDocTemplate : SDI 도큐먼트 템플릿
?CMultiDocTemplate : MDI 도큐먼트 템플릿
? CDocument : 어플리케이션이 지정한 도큐먼트의 기본(Base) 클래스
? CView : 도큐먼트 안에 있는 데이터를 뷰를 통하여 화면에 보일 수 있도록 하는 클래스
사용자의 View들은 이CView 클래스로부터 상속받아 사용한다.

? CPrintInfo : 프린트 관련 정보들을 저장하고 다루는 구조체
? CCreateContext : CCreateContext는 도큐먼트, 뷰, 프레임 윈도우,
도큐먼트 템플릿에 대한 포인터를 지정하고 있는 구조체
Visual C++ Programming

(C) 1998 Sang Il Kim

사용자의 도큐먼트들은 이CDocument 클래스로부터 상속받아 사용한다.

6
2

MFC
CGdiObject

CDC

CObject

CMenu

CCmdTarget
CFormView
CScrollView
CEditView
CButton
CStatic
CListBox
CComboBox
CSplitterWnd
CVBControl

CDialog

CView
CWnd

CFrameWnd

CEdit

CControlBar

◐ Visual Object Class Mind Map ◑

CFileDialog
CColorDialog
CFontDialog
CPrintDialog
CFindReplaceDialog
CMDIFrameWnd
CMDIChildWnd
CToolBar
CStatusBar
CDialogBar
CScrollBar
Visual C++ Programming

(C) 1998 Sang Il Kim

CClientDC
CWindowDC
CPaintDC
CMetaFileDC

CPen
CBrush
CFont
CBitmap
CPalette
CRgn

6
3

MFC
? Visual Objects 관련 클래스
1. CWnd 클래스
? CWnd : 모든 윈도우에 대한 기본 클래스로서 기본적인 SDK 함수들을
MFC에 맞도록 캡슐화(Encapsulation)시켜 놓았다.
?CFrameWnd : 메인 프레임에 관한 윈도우 클래스
CMDIFrameWnd : MDI 프로그램에서 사용되는 메인 프레임 윈도우 클래스
CMDIChildWnd : MDI 프로그램의 자식(Child) 윈도우 클래스
2. CView 클래스
? CView : 도큐먼트 안에 있는 데이터를 화면에 출력하는 역할을 하는 클래스
?CScrollView : CView의 기본 특성 외에 화면 스크롤이 가능한 뷰이다.
다이얼로그 리소스 안에 출력 형태가 정의되어 있다.
?CEditView : 텍스트 편집,단어 검색,치환 그리고 스크롤을 자체적으로 해결한 뷰
간단한 텍스트 에디터를 만드는데 편리한 클래스이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?CFormView : 다이얼로그 리소스에 기반 하여 쉽고 빠르게 구현할 수 있는 클래스

6
4

MFC
? Visual Objects 관련 클래스
3. 다이얼로그 (Dialog) 클래스
? CDialog : 다이얼로그 클래스들에 대한 기본(Base) 클래스
?모달(Modal) 다이얼로그
?모드리스(Modeless) 다이얼로그
MFC가 제공하는 기본 다이얼로그는 모달 다이얼로그이다.
?CDataExchange : 다이얼로그 박스에 대한 초기화와 타당성(validation)
정보를 제공한다.
?CFileDialog : 파일을 열거나 저장, 디렉토리 찾아가기 등의 일을 하는 표준 다이얼로그 클래스
?CFontDialog : 폰트를 선택, 글자 크기와 속성을 지정하는 표준 다이얼로그 클래스
?CColorDialog : 색상을 선택하기 위한 표준 다이얼로그 클래스
?CFindReplaceDialog : 문자를 검색, 지정한 문자열로 치환하는 표준 다이얼로그 클래스
Visual C++ Programming

(C) 1998 Sang Il Kim

?CPrintDialog : 파일을 프린트하거나 프린트 옵션을 지정하는 표준 다이얼로그 클래스

6
5

MFC
? Visual Objects 관련 클래스
4. 제어 (Control) 클래스
? CStatic : 윈도우나 다이얼로그 박스의 어느 위치에 고정된 텍스트
? CButton : 다이얼로그 박스에서 흔히 볼 수 있는 체크 박스나 라디오 버튼
? CEdit : 편집이 가능한 박스
? CListBox : 여러 아이템을 박스 안에 나열해서 표현, 한 아이템을 선택하는 것이 가능한 박스
? CComboBox : 에디트 컨트롤과 리스트 박스로 구성된 박스
? CControlBar : 제어바에 대한 기본 클래스
?CStatusBar : 윈도우 하단에 있는 상태바에 대한 클래스
?CToolBar : 윈도우 상단에 위치한 작은 비트맵 버튼들과 관련된 클래스
?CDialogBar : 모드리스 다이얼로그 박스에 관련된 클래스
? CVBControl : 비주얼베이직에서 사용되던 VBX를 제어할 수 있는 클래스
? CSplitterWnd : 여러 개의 틀로 나뉘어질 수 있는 윈도우를 제어하는 클래스
Visual C++ Programming

(C) 1998 Sang Il Kim

?CScrollBar : 윈도우 우측이나 좌측에 있는 스크롤바에 대한 클래스

6
6

MFC
? Visual Objects 관련 클래스
5. 메뉴 (Menu) 클래스
? CMenu : 응용 프로그램에서 메뉴와 팝업 메뉴를 쉽게 구현할 수 있도록 작성된 클래스
6. 디바이스 컨텍스트 (Device-Context) 클래스
? CDC : 디바이스 컨텍스트에 대한 기본 클래스
화면 출력과 프린터와 같은 비화면 출력을 다룰 수 있는 함수들이 있다.
?CPaintDC : 윈도우의 화면 출력에 사용된다. 주로 OnPaint()에 의해 사용된다.
이 클래스를 생성할 때 자동적으로 BeginPaint가 실행되고 소멸될 때에 EndPaint가
실행된다.
?CClientDC : 윈도우의 클라이언트 영역에 화면 출력한다.
?CWindowDC : 전체 윈도우에 대한 화면 출력 클래스.
?CMetaFileDC : 윈도우 메타파일에 대한 클래스

◐ 메타파일 : 그래픽 이미지를 생성해 낼 수 있는 GDI명령들이 저장된 파일.
이미지를 BMP나 PCX와 같이 통째로 저장하는 것이 아니고 그래픽
명령으로 저장되어 있기 때문에 크기가 작고, 수정이 쉽다.
Visual C++ Programming

(C) 1998 Sang Il Kim

클라이언트 영역뿐만 아니라 메인 프레임 영역에도 적용 가능하다.

6
7

MFC
? Visual Objects 관련 클래스
7. Drawing(그리기) Object 클래스
? CGdiObject : GDI 객체들의 기본 클래스
?CBitmap : 비트맵을 생성하고, 출력, 변경시키기 위한 클래스
?CBrush : 브러시를 선택하고 속성을 조절할 수 있는 클래스
?CFont : 폰트를 선택하고 속성을 조절할 수 있는 클래스
?CPalette : 출력장치와 응용 프로그램간 팔레트를 조절할 수 있는 클래스
?CPen : 펜을 선택하고 속성을 조절할 수 있는 클래스

(C) 1998 Sang Il Kim

?CRgn : 다각형 또는 타원을 그릴 수 있도록 조절하는 클래스

Visual C++ Programming

6
8

MFC

CPtrList
COblist
CStringList
CMapPtrToWord
CMapPtrToPtr
CMapStringToOb
CMapStringToPtr
CMapStringToString
CMapWordToOb
CMapWordToPtr

CException

CArchiveException
CFileException
CMemoryException
CNotSupportedException
CResourceException
CUserException

CObject
CFile

CStdioFile
CMemFile

독립 클래스들
CArchive
CDumpContext
CRuntimeClass
CMemoryState
CRect

CPoint
CSize
CString
CTime
CTimeSpan

◐ 일반 목적(General Purpose) Class Mind Map ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

CByteArray
CWordArray
CDWordArray
CPtrArray
CObArray
CStringArray
CUIntArray

6
9

MFC
? 일반 목적 클래스와 독립적 클래스
1. 파일 처리와 관련된 클래스
? CFile : 2진 파일들에 대한 프로그램 인터페이스를 제공한다.
?CMemFile : 메모리를 파일처럼 쓸 수 있도록 하는 프로그램 인터페이스 제공
?CStdioFile : 일반적인 텍스트 파일을 다룰 수 있는 프로그램 인터페이스 제공
?CArchive : CFile과 같이 사용되어 데이터 객체에 대한 Serialization을
구현하는데 중요한 인터페이스 제공
2. 진단 (Diagnostics)
? CDumpContext : 메모리의 내용을 통째로 보이도록 하는 클래스
? CRuntimeClass : 런타임 시 어떤 객체의 클래스 관련 정보를 정확하게 아는데 사용

Visual C++ Programming

(C) 1998 Sang Il Kim

? CMemoryState : 메모리 사용에 대한 체크를 할 수 있도록 하는 클래스

7
0

MFC
? 일반 목적 클래스와 독립적 클래스

4. 집합체(Collections) 관련 클래스
? 배열 관련 클래스
?CByteArray : BYTE형태의 원소들을 배열로 저장
?CDWordArray : 더블 워드 형태의 원소들을 배열로 저장
?CObArray : CObject에서 파생된 클래스 또는 CObject 클래스 그 자체에 대한
포인터를 배열로 저장
?CPtrArray : 함수(void) 포인터를 배열로 저장
?CStringArray : CString 객체를 배열로 저장
?CWordArray : WORD 형태의 원소들을 배열로 저장
?CUIntArray : UINT 형태의 원소들을 배열로 저장
Visual C++ Programming

(C) 1998 Sang Il Kim

3. 예외 처리 (Exceptions)
: 치명적인 에러 발생 시에 컴퓨터가 멈추는 일을 막는다.
? CException : 여러 가지 예외 처리들에 대한 기본 클래스
?CArchiveException : 데이터 기록에 대한 예외 처리 클래스
?CFileException : 파일에 관련된 예외 처리 클래스
?CMemoryException : 메모리 고장에 관한 예외 처리 클래스
?CNotSupportedException : 지원되지 않는 특성을 호출하였을 때 발생하는 예외처리
?CResourceException : 윈도우 리소스를 메모리에 로딩 하는 데 실패할 경우
?CUserException : 사용자가 정의할 수 있는 클래스. 예외 처리에 들어가기 전에
문제가 무엇인지를 윈도우에게 알려야 한다.

7
1

MFC
? 일반 목적 클래스와 독립적 클래스
4. 집합체(Collections) 관련 클래스

? 객체간의 맵핑 클래스
?CMapPtrToWord : 함수(void)포인터를 WORD 형태의 데이터로 맵핑시킨다.
?CMapPtrToPtr : 함수(void)포인터를 함수 포인터에 맵핑하는데 사용된다.
?CMapStringToOb : CString객체를 CObject 포인터로 맵핑한다.
?CMapStringToPtr : CString객체를 CObject void 포인터로 맵핑한다.
?CMapStringToString : CString객체를 CString 객체로 맵핑한다.
?CMapWordToOb : WORD 형태의 데이터를 CObject 포인터로 맵핑한다.
?CMapWordToPtr : WORD 형태의 데이터를 함수 포인터에 맵핑한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 링크드 리스트 관련 클래스
?COblist : CObject에서 파생된 클래스 또는 CObject 클래스 그 자체에 대한
포인터를 링크드 리스트 형태로 저장
?CPtrList : 함수(void) 포인터를 링크드 리스트로 저장
?CStringList : CString 객체를 링크드 리스트로 저장

7
2

MFC
? 일반 목적 클래스와 독립적 클래스
5. 기타 독립 클래스
: MFC 전체에 걸쳐 광범위하게 사용되는 클래스이다.
? CPoint : 점에 관한 클래스
? CSize : 크기에 관한 클래스
? CRect : 영역에 관한 클래스
? CString : 문자열에 관한 클래스
? CTime : 절대적 시간을 다루는 클래스

(C) 1998 Sang Il Kim

? CTimeSpan : 상대적 시간을 다루는 클래스

Visual C++ Programming

7
3

MFC
? 매크로와 전역 변수
? 이 부분은 클래스에 관련된 부분은 아니지만 MFC 코드를 이해하는데
필요한 요소이기 때문에 어떤 내용들이 포함되어 있는지 알아야 한다.
? DevStudio\Vc\mfc\include\<afx.h>
1. 데이터 형 (Data Types)
? 윈도우 SDK 시절부터 데이터 형을 새롭게 정의하였는데 일반적으로 많이
쓰는 데이터형에 대해서 알아야 한다.
POSITION : MFC의 Collection 클래스에서 사용되는 원소들의 위치 지정에
사용되는 데이터형
LPCRECT : RECT 구조체에 대한 32비트 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC에 새롭게 정의된 데이터 타입

7
4

데이터 타입

의미

BOOL
BYTE
WORD
UINT
DWORD
LONG
LPVOID
COLORREF
BSTR
LPSTR
LPCSTR
WNDPROC
WPARAM, LPARAM

논리 데이터 형(TRUE또는 FALSE)
8 비트 unsigned형 정수
16 비트 unsigned형 정수
32 비트 unsigned형 정수
32 비트 unsigned형 정수 or 세그먼트:오프셋 주소
32 비트 signed형 정수
32비트 타입 지정이 없는 포인터
색상(color)을 표현하는 32비트 데이터 형
32비트 문자형 포인터
32비트 문자열 포인터
32비트 문자열 상수 포인터
윈도우 함수에 대한 32비트 포인터
윈도우 함수 또는 Callback 함수의 인수로 넘겨주기
위한 32 비트 데이터 형
윈도우 함수 또는 Callback 함수에 결과로 되돌아온
32 비트 데이터 형

LRESULT

? DevStudio\Vc\include\Windef.h
Visual C++ Programming

(C) 1998 Sang Il Kim

Data Types

7
5

핸들의종류

의미

hIcon
hCursor
hBrush
hWnd
hMenu
hInstance
hFont
hBitmap
hPalette
hPen
hTask
hDlg
hDC
hRgn

아이콘을 가리키는 핸들
커서(마우스 포인터)를 가리키는 핸들
브러시를 가리키는 핸들
윈도우를 가리키는 핸들
메뉴 또는 팝업 메뉴를 가리키는 핸들
윈도우 응용 프로그램의 인스턴스를 가리키는 핸들
텍스트 글꼴을 가리키는 핸들
DIB 이미지 정보를 포함하고 있는 메모리 영역을 가리키는 핸들
색 팔레트(테이블)를 가리키는 핸들
선의 종류를 지정하는데 사용하는 펜을 가리키는 핸들
독립적으로 실행하고 있는 작업을 가리키는 핸들
대화 상자를 가리키는 핸들
장치 컨텍스트를 가리키는 핸들
창의 클립(clip) 영역을 가리키는 핸들

? MFC를 사용해서 프로그래밍할 때는 일반적으로 핸들이 필요하지 않다.

이유는 MFC가 응용 프로그램 프레임워크에 포함되어 있는 기본적인 윈도우 객체에
액세스하는 데 사용할 수 있는 다른 방법을 제공하기 때문이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

Data Types

7
6

MFC
? 매크로와 전역 변수
2. Run-Time Object Model Service
? 매크로
DECLARE_DYNAMIC, DECLARE_DYNCREATE, DECLARE_SERIAL,
IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE,
IMPLEMENT_SERIAL, RUNTIME_CLASS
3. 진단 서비스 (Diagnostic Services)
? MFC는 디버깅을 쉽게 할 수 있도록 여러 가지 진단 서비스를 갖추고 있다.
? 전역 변수는 afx로 시작, 전역 함수는 Afx로 시작한다.
? 전역 변수 : afxDump, afxMemDF, afxTraceEnabled, afxTraceFlags
? 전역 함수 : AfxCheckMemory, AfxDump, AfxEnabledMemoryTracking,
AfxlsMemoryBlock, AfxlsValidAddress, AfxlsValidString,
AfxSetAllocHook, AfxDoForAllClasses
Visual C++ Programming

(C) 1998 Sang Il Kim

? 매크로 : ASSERT, ASSERT_VALID, DEBUG_NEW, TRACE, VERIFY

7
7

MFC
? 매크로와 전역 변수
4. 예외 처리 (Exception Processing)
? 프로그램이 실행될 때 예외 상황(시스템이 비정상적이 되거나 치명적인
메모리 에러, 파일검색 에러 등)을 처리하기 위하여 사용한다.
? 매크로
TRY, CATCH, AND_CATCH, END_CATCH, THROW, THROW_LAST
? 전역 함수
AfxThrowArchiveException, AfxThrowFileException,
AfxThrowMemoryException, AfxThrowNotSupportedException,
5. CString 형식지정 및 메시지 박스 출력
? 이 함수들은 보통 메시지 박스에 나타날 문자열을 다루기 위하여 사용된다.
? 전역 함수 : AfxFormatString1, AfxFormatString2, AfxMessageBox
Visual C++ Programming

(C) 1998 Sang Il Kim

AfxThrowResourceException, AfxThrowUserException, AfxAbort(종료)

7
8

MFC
? 매크로와 전역 변수
6. 메시지 맵 (Message Maps)
? 메시지를 내부적으로 처리하기 위하여 MFC는 여러 가지 매크로를 두고 있다.
? 매크로
?메시지 맵 선언과 정의에 관련된 매크로
DECLARE_MESSAGE_MAP // 선언
BEGIN_MESSAGE_MAP, END_MESSAGE_MAP // 정의
?메시지 맵핑과 관련된 매크로
ON_REGISTERED_MESSAGE, ON_UPDATED_COMMAND_UI

Visual C++ Programming

(C) 1998 Sang Il Kim

ON_COMMAND, 0N_CONTROL, ON_MESSAGE, ON_VBXEVENT

7
9

MFC
? 매크로와 전역 변수
7. 어플리케이션 프로그램의 정보 및 관리
? 전역 함수
AfxGetApp, AfxGetAppName, AfxGetInstanceHandle,AfxGetMainWnd,
AfxGetResourceHandle, AfxRegisterWndClass, AfxRegisterVBEvent,
AfxSetResourceHandle
8. 표준 명령어와 윈도우 ID
? 표준 명령어 ID
: ID로 시작하는 매크로
? 윈도우 ID (윈도우의 내부 처리를 위한 표준 명령어에 대한 ID)
: AFX_ID로 시작하는 매크로
? DevStudio\Vc\mfc\include\<afxres.h>
Visual C++ Programming

(C) 1998 Sang Il Kim

예) ID_FILE_OPEN : 메뉴에 있는 파일 열기 명령어에 대한 ID

8
0

MFC
? 매크로와 전역 변수
9. 헝가리언 표기법(Hungarian Notation)
? 변수들을 정의할 때 데이터형을 알아보기 쉽도록 접두어를 붙여 표기하는 것.
의미

a
ai
b
by
c
cb
cr
cx, cy
dw
f
fn
h
i
l

Array
Integer Array
Boolean
Unsigned Char(Byte)
Char
Count of bytes
Color Reference Value
Short(count of x, y length)
Unsigned long(dword)
Flag(On/Off)
Function
Handle
Integer
Long

전치사
lp
lpfn
lpsz
m
n
np
p
psz
s
sz
tm
w
x, y

의미
Long Pointer
Function Pointer
String Pointer
Data member of a class
Short or Int
Near Pointer
Pointer
String Pointer
String
0 terminated String(NULL)
Text Metric
Unsigned Int(Word)
Short(x, y coordinate)

Visual C++ Programming

(C) 1998 Sang Il Kim

전치사

8
1

MFC
? 헝가리언 표기법
설명

hWndMain
alDice
lpszText
cdwPixels

Main이라는 창(Wnd)을 가리키는 핸들(h)
Dice라고 하는 long정수의 배열(a)
Text라고 하는 NULL 종료 문자열(sz)을 가리키는 포인터(lp)
이중 단어(dw) 유형이며, 계수를 위해서 사용하는
Pixels라고 하는 이름의 변수

(C) 1998 Sang Il Kim

변수명

Visual C++ Programming

8
2

CObject로 부터 파생되지 않은 MFC 하위 시스템들
? OLE 클래스
? 단순 데이터 유형 클래스
? 지원 클래스
? 동기화 클래스
? 유형이 있는 템플릿 클래스
? OLE클래스
? OLE는 응용 프로그램이 훌륭한 일을 할 수 있도록 하는 강력한 새로운 기술이다.
? OLE를 사용하면, 편집할 수 있는 다중 응용 프로그램 OLE 문서와 OLE 개체를
만들 수 있다.
(C) 1998 Sang Il Kim

? OLE를 사용하여 응용 프로그램간에 마우스로 끌어다 떨어뜨리는 복사 기능을 제공
하거나 OLE 자동화를 통해 또 다른 응용프로그램을 제어할 수도 있다.
? OLE 데이터 유형을 캡슐화한 COle로 시작하는 OLE클래스들도 있다.

Visual C++ Programming

8
3

CObject로 부터 파생되지 않은 MFC 하위 시스템들

클래스

의미

CImageList

일련의 비트맵을 저장하고 쌓아두는 데 사용한다.
리스트 컨트롤과 트리 컨트롤에서도 사용하고 있다.

COleCurrency

CURRENCY는 고정 소수점 산술 유형으로 소수점 전에 15자리가 있고,
그 뒤에 4자리가 있다.

COleDateTime

날짜와 시간 값을 나타내는 OLE 자동화 유형 DATE에 대한 포장기이다.

COleDateTimeSpan

두 개의 COleDateTime 값 사이의 시간차와 같이 일수로 측정된 시간 간격을
나타낸다.

COleVariant

데이터를 여러 유형으로 저장할 수 있는 OLE 자동화 유형이다.

CPoint

표준 SDK POINT 구조에서 발견할 수 있는 (x,y)좌표 쌍을 포장한다.

CRect

표준 SDK RECT 구조에서 찾을 수 있는 사각형 영역의 좌표를 포장한다.

CSize

거리와 상대적 위치, 또는 순서쌍 등을 포장한다.

CString

문자 문자열을 포장하고 있으며, 문자열을 처리하는데 사용하는 많은 유용한
메소드와 연산자를 제공하고 있다.

CTime

절대적 시간과 날짜 값을 포장하고 있다.

CTimeSpan

상대적 시간과 날짜 값을 포장하고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC가 지원하는 단순 데이터 유형 클래스
? point나 rect같은 공통 Win32 API 데이터 유형을 캡슐화 한다.

8
4

CObject로 부터 파생되지 않은 MFC 하위 시스템들
? 지원 클래스
? 사용자 인터페이스 개체를 갱신하고 메뉴와 명령 단추를 활성화하고 비활성화하는
등과 같은 동작들을 수행하는 데 사용하는 CCmdUI를 포함하고 있다.
? CWaitCursor 클래스는 단순히 커서를 모래 시계 모양으로 변경하는 역할을 한다.
? CRectTracker 클래스는 크기 조정 핸들을 사용하여 화면의 항목들을 움직이고 크기를
변경할 수 있게 한다.

? 유형이 있는 템플릿 클래스들
? 유형이 있는 템플릿 클래스는 공통으로 사용하는 프로그래밍 상황에서 많이 유용하게
사용하고 있으며, CObject로부터 파생된 콜렉션 유형보다 더 낫다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 동기화 클래스
? 스레드 행동의 동기를 맞추어 주는 Win32 객체들을 C++ 객체로 포장하기 위한
네 개의 MFC 클래스가 있다.
?CSemaphore
?CMutex
?CCriticalSection
?CEvent

8
5

MFC
? MFC 프로그램 작성 방법
① 프로그램이 필요로 하는 기능을 명시화해야 한다.
② 그 사양을 바탕으로 기능에 맞는 클래스들이 무엇인지를 찾아내야 한다.
③ 코딩에 들어간다.
④ 디버깅과 테스팅

(C) 1998 Sang Il Kim

⑤ 문서화와 도움말 작업

Visual C++ Programming

8
6

CHAPTER 2

(C) 1998 Sang Il Kim

MFC 라이브러리
어플리케이션 프레임워크

Visual C++ Programming

8
7

CHAPTER 2
? 어플리케이션 프레임워크 (Application Framework)
? 어플리케이션 생성을 위해서 필요한 모든 것을 제공해 주는
객체지향 소프트웨어 요소들의 집합.
? 어플리케이션 프레임워크와 클래스 라이브러리
? 클래스 라이브러리
?어플리케이션에서 사용될 수 있는 관련 C++ 클래스들의 집합.
? 어플리케이션 프레임워크 (Application Framework)
?클래스 라이브러리를 모아 놓은 특수한 집합체

? 응용 프로그램 틀(Application Framework)을 AFX라고 불렀다.
? AFX란 이름은 1994년 초반에 마이크로소프트에서 사용이 중단되었다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC 이전의 AFX

8
8

CHAPTER 2
? 메시지 처리(Message Processing)
? 도스용 프로그램 : 사용자의 입력을 받기 위해서 운영체제를 호출.
? 윈도우용 프로그램 : 운영체제가 보내 주는 메시지를 처리.
? 프로그램을 실행시키면, 윈도우는 WinMain() 함수를 호출한다.
? MFC에서는 WinMain()을 감추고, 메시지 처리를 구조화 시킬 수 있는
CWinApp를 제공한다.
? WM_의 접두어로 시작하는 식별자를 사용한다.
? WM_LBUTTONDOWN (마우스의 왼쪽 버튼이 눌려졌다는 것을 의미)

(C) 1998 Sang Il Kim

? 메시지들을 다루기 위한 대부분의 코딩은 어플리케이션 프레임
워크가 알아서 한다.

Visual C++ Programming

8
9

CHAPTER 2

typedef struct tagPOINT
{
LONG x; // 화면 좌표
LONG y; // 화면 좌표
} POINT;
// 중첩 구조

? 메시지 구조
? typedef struct tagMSG
{
hwnd;

// 메시지를 꺼낼 창의 핸들

UINT

message; // 메시지 값

WPARAM

wParam;

// 메시지에 대한 추가적인 정보

LPARAM

lParam;

// 메시지에 대한 추가적인 정보

DWORD

time;

// 메시지가 대기열에 들어온 시간

POINT

pt;

// 메시지가 전달되었을 때 커서의 화면 좌표

}MSG;
? hwnd - 이 인수가 0(NULL)이면, 메시지 대기열에 있는 모든 메시지들을 꺼내게 된다.
? message - 각 윈도 메시지는 WINDOWS.H에 매크로로 정의되어 있는 특정 값을
갖고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

HWND

9
0

CHAPTER 2
? 시스템 정의 메시지
? 윈도우는 시스템 정의 메시지를 해당 중심 창 프로시저에 보냄으로써 응용 프로그램과
통신한다.

BM

단추 컨트롤 메시지

CB

콤보 박스 컨트롤 메시지

DM

기본 누름 단추 컨트롤 메시지

EM

편집 컨트롤 메시지

LB

목록 상자 컨트롤 메시지

SBM

이동 표시줄 컨트롤 메시지

WM

일반 창 메시지

(C) 1998 Sang Il Kim

? 각 시스템 정의 메시지는 고유의 번호로된 식별자를 갖고 있으며, 이에 해당되는 식별

매크로 정의를 갖고 있다.
메시지 분류
접두사

Visual C++ Programming

9
1

CHAPTER 2
? 사용자 정의 메시지
메시지 유형

값의 범위

시스템 정의 메시지(제1부)

0x0000-0x03FF

사용자 정의 내부 메시지

0x0400-0x7FFF

시스템 정의 메시지(제2부)

0x8000-0xBFFF

사용자 정의 외부 메시지

0xC000-0xFFFF

함수

의미

AfxGetApp

CWinApp 객체에 대한 포인터를 반환한다.

AfxGetAppName

응용 프로그램의 이름을 담고 있는 문자열에 대한 포인터를
반환한다.

현재의 응용 프로그램 인스턴스에 대한 핸들을 반환한다.
AfxGetInstanceHandle 이 핸들은 AfxWinInit()내에서 주 스레드를 초기화할 때
설정된다.
AfxGetResourceHandle

응용 프로그램 자원에 대한 핸들을 반환한다. 이 핸들은
AfxWinInit()내에서 주 스레드를 초기화할 때 설정된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 응용 프로그램 객체 데이터를 얻기 위한 전역 MFC 함수

9
2

CHAPTER 2
? 메시지 전달 방식
? 윈도우의 모든 동작은 마우스의 왼쪽 버튼이 눌려졌다거나,
키보드가 눌려졌다거나 하는 등의 어떤 특정 사건에 대해서
응답하는 방식으로 이루어져 있다.
? Message Event 방식 또는 Message Driven 방식
? 이벤트들을 보관하는 큐
? Hardware Event Queue
? System Queue
(C) 1998 Sang Il Kim

? 응용 큐
? 메시지
? 어떤 특정 이벤트에 의해서 발생된 관련 정보.
Visual C++ Programming

9
3

CHAPTER 2

메시지 발생

하드웨어
이벤트 큐

프로그램
이벤트 큐

메시지
루프

◐ 메시지 전달과정 ◑
? 핸들 (Handle) 방식
? 윈도우는 각각의 객체들을 식별하기 위해서 핸들을 사용한다.
? HWND (윈도우에 대한 핸들)
(C) 1998 Sang Il Kim

? HICON (아이콘에 대한 핸들)
? HMENU (메뉴에 대한 핸들)

Visual C++ Programming

9
4

CHAPTER 2
? 인스턴스 (Instance) 방식
? 인스턴스란? 프로그램의 복사본을 말하며, 각각의 복사본을
구별하기 위해 인스턴스 핸들을 이용한다.
? 각각의 다른 프로그램이 여러 개 실행되었거나, 동일한 프로
그램이 여러 개 실행되었을 경우, 윈도우는 여러 개의
프로그램을 실행시키기 위해 각각의 프로그램에 인스턴스
라는 핸들을 부여한다.

? 윈도우는 거의 대부분이 하드웨어 장치와 독립적으로
작동한다.
? 하드웨어와 독립적인 장치를 지원해 줄 수 있는 디바이스
드라이버를 내장하고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 하드웨어 장치와 독립된 처리 방식

9
5

CHAPTER 2
하드웨어 장치

Windows

Windows 응용 프로그램

키보드에서
A키 입력

시스템 큐

NOTEPAD 메시지 루프

NOTEPAD 응용 큐
PBRUSH 응용 큐

PBRUSH 메시지 루프
입력에 대한 처리
WRITE 메시지 루프
(C) 1998 Sang Il Kim

WRITE 응용 큐

◐ 메시지 처리 방식 ◑
Visual C++ Programming

9
6

CHAPTER 2
? 메시지 식별자
? 메시지가 프로그램에서 사용될 때는 부호 없는 정수형의 값에 불과하다. 윈도우는
이러한 부호 없는 정수형의 값을 특정 사건(사용자 입력)에 대한 기호로서 인식한다.
? 프로그램에서 이러한 메시지에 대한 부호 없는 정수형의 값들을 이용할 때, 일반적으로
통일성을 갖기 위해 WM_의 접두어로 시작하는 식별자를 사용한다.
? WM_LBUTTONDOWN ( 마우스의 왼쪽 버튼이 눌려졌다는 것을 의미)
? WM_DESTROY ( 윈도우를 파괴한다는 것을 의미)
? 메시지 식별자는 WINDOWS.H 에 정의되어 있다.
? 메시지 핸들러

? 전달된 메시지가 올바른 종류이고, 해당 작업에 맞는 것일 경우에만 메시지 핸들러가
구동된다.
? 메시지 핸들러에서 처리되는 메시지 유형
? 윈도우 메시지

? 컨트롤 통지 메시지

? 명령 메시지
Visual C++ Programming

(C) 1998 Sang Il Kim

? 메시지 핸들러는 특정 이벤트가 발생했을 때 프로그램 객체로부터
통지(notification)를 받아들이는 역할을 한다.

9
7

CHAPTER 2
? 윈도우 메시지
? 윈도우에 의해 응용 프로그램에 전달된다.
? 보통 WM_ 접두사로 시작하는 메시지들이다.
? 예외, WM_COMMAND - MFC에서 특별한 상태를 갖는다.
? 컨트롤 통지 메시지
? 자식 윈도우가 부모 윈도우에 보내는 WM_COMMAND 메시지들을 포함하고 있다.
? 컨트롤은 특정 통지 코드가 내장되어 있는 WM_COMMAND메시지를 종종 발생시킨다.
? 통지 코드는 때때로 미리 정의되어 있는 MFC 메시지 처리 메커니즘에 맵핑될 수 있다.
? 그러면 통지를 위한 윈도우의 메시지 핸들러가 이에 맞게 동작하게 된다.
? 표준 윈도우 컨트롤은 보통 명령과 통지 메시지를 둘다 전송하지만, MFC가 보통 명령
메시지는 클래스 메소드로 싸기 때문에 응용 프로그램에서는 통지 메시지만 처리하면

? 명령 메시지
? 명령 메시지는 메뉴나 도구모음 단추와 같은 사용자 인터페이스로부터의
WM_COMMAND 통지 메시지를 포함하고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

된다.

9
8

CHAPTER 2

Windows
application
program

USER.EXE

KERNEL.EXE

Display(Crt Monitor)

PRINTER.DRV

Printer

KEYBOARD.DRV

Keyboard

MOUSE.DRV

Mouse

SOUND.DRV

Sound HardWare

SYSTEM.DRV

Timer HardWare

COMM.DRV

RS-232 HardWare
(C) 1998 Sang Il Kim

GDI.EXE

DISPLAY.DRV

MS-DOS file I/O
Memory management

◐ 윈도우의 하드웨어 장치 운영방식 ◑
Visual C++ Programming

9
9

CHAPTER 2
? 객체 구성 요소들
? 동적 연결 라이브러리 (DLL)
? 비주얼 베이직 확장 (VBX)
? OLE 컨트롤 확장 (OCX)

? 프로그램의 모듈성을 향상시킬 수 있다.
? DLLs 테스트를 분리해서 수행한다.
? 사용자가 직접 DLLs을 만들 수 있다.
? 윈도우도 USER32.DLL, GDI32.DLL, KERNEL32.DLL과 같은 DLL들의
집합으로 이루어져 있다.
? 이들 세 DLL은 Win32 응용 프로그램 인터페이스(API)의 핵심을 이루고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 동적 연결 라이브러리
? 실행시(Run-time)에 로드되는 라이브러리를 말한다.
? 여러 개의 프로세스가 사용할 수 있는 함수들의 라이브러리를 갖고 있는
실행 파일이다.
? 코드 내의 함수 호출이 실행될 때에 동적으로 DLL내의 실제 코드와
연결되기 때문에 동적 연결이라고 부른다.

1
0

CHAPTER 2
? 비주얼 베이직 확장 (VBX)
? VBX는 프로그램 개발 동안 시각적으로 처리할 수 있도록 연결된 추가
함수들을 가진 특수 구조의 DLL이다.
? VBX는 임의의 윈도우 프로그램이나 여러 언어에서 사용할 수 있다.
? 16비트 윈도우 프로그램에서만 사용할 수 있다.
? OLE 컨트롤 확장 (OCX)
? VBX 구조의 기능과 OLE2.0의 강력한 기능을 조합한 혼성체이다.
? 윈도우 개발 도구에 통합된 인터페이스를 제공하고 있다.
? 하나의 원본 파일로부터 16비트 버전과 32비트 버전을 둘 다 컴파일할 수
있다.
(C) 1998 Sang Il Kim

? 윈도우 응용 프로그래밍 인터페이스(API)
? 프로그래머가 다른 프로그램을 만들 때 사용할, 한 프로그램(또는 관련 있는
일련의 프로그램들) 내의 함수 호출들을 모아 놓은 것이다.
? 함수의 내부 구조는 알 필요가 없으며, 함수의 프로토타입과 반환 값만 알면 된다.
Visual C++ Programming

1
0

CHAPTER 2
? Win16 어플리케이션 프로그래밍 인터페이스(API)
? Win16 버전들은 (.EXE) 확장명을 갖고 있지만, 이들은 모두 실제로 DLL이며
스스로 실행될 수는 없다.

Win16 API
USER.EXE

GDI.EXE

Win32 API

의미

USER32.DLL

USER 구성 요소는 메시지와 메뉴, 커서, 통신,
타이머를 포함한 윈도우 관리에 책임을 지고 있으며,
윈도우를 나타내는 것이 아닌 이를 제어하는 것과
관련된 대부분의 다른 함수들을 갖고 있다.

GDI32.DLL

GDI 구성 요소는 그래픽 장치 인터페이스이다. 이는
윈도우 메타파일과 비트맵, 장치 컨텍스트, 그리고
글꼴을 포함한 사용자 인터페이스와 그래픽을
그리는 것을 처리한다.

KRNL386.EXE KERNEL32.DLL

KERNEL 구성 요소는 윈도우의 심장부 역할을 하는
메모리와 작업, 자원 관리의 저차원 기능을 처리한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Win32 어플리케이션 프로그래밍 인터페이스(API)
? 16비트 인자들이 상당수 32비트로 바뀌었다.
? Win32 API 에는 새로운 함수들이 추가되었다.

1
0

CHAPTER 2
? 윈도우 메시징
? 클래스 요약
설명

메시지맵 매크로
CCmdTarget
CCmdUI

윈도우 메시지를 C++ 멤버함수에 연결(map)시켜주는 매크로
커맨드 메시지를 받는 모든 객체에 대한 기초 클래스
사용자 인터페이스 객체를 갱신하는 것을 도와준다.
(예, 사용 가능하게 하거나 사용할 수 없게 한다.)

(C) 1998 Sang Il Kim

클래스 이름

Visual C++ Programming

1
0

CHAPTER 2
? MFC 커맨드 메시지 전달
CMDIFrameWnd
1. Active CMDIChild
2. {itself}
3. CWinApp

Command
Message

CDialog
1. {itself}
2. Owner CWnd
3. CWinApp

1. Active CView
2. {itself}
3. CWinApp

CView

CDocument

1. {itself}
2. CDocument

1. {itself}
2. CDocTemplate

Visual C++ Programming

(C) 1998 Sang Il Kim

CMDIChildWnd

1
0

CHAPTER 2
? 메시지 맵(Message Map)
? 메시지 맵이란? 윈도우 메시지를 C++ 멤버함수에 연결(map)시켜
주는 매크로이다.
? 메시지 맵을 사용하게 되면, 부피가 커지는 vtable을 피할 수 있다.
? 메시지 맵 메커니즘

자기 자신의 클래스

? BEGIN_MESSAGE_MAP(CMyFrame, CMyFrameWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()

해당클래스의
기초클래스를 지정

END_MESSAGE_MAP()

메시지를 보낸 쪽의
식별자

(C) 1998 Sang Il Kim

? ON_MessageName(ID, ClassMethod)
메시지를 처리할
클래스 메소드의 이름
Visual C++ Programming

1
0

CHAPTER 2
? 메시지 맵 항목
? 명령 메시지 핸들러
? 차일드 윈도우 통지 메시지 핸들러
? 윈도우 메시지 핸들러
? 명령 메시지 핸들러
? 메뉴를 선택하거나 키보드 가속기를 사용하는 것과 같은 사용자의 행동에
의해 발생된 WM_COMMAND 메시지들을 처리한다.
? WM_COMMAND 메시지는 ON_COMMAND 메시지 맵 항목들을 가진 여러
응용 프로그램 구성 요소에 의해 처리된다.

? ON_COMMAND(ID, ClassMethod)
메시지를 처리할
클래스 메소드의 이름

(C) 1998 Sang Il Kim

메시지를 보낸 쪽의
식별자

? 해당 메시지 핸들러 메소드는 클래스 선언에 놓이게 된다.
afx_msg void ClassMethod();
Visual C++ Programming

1
0

CHAPTER 2
? 차일드 윈도우 통지 메시지 핸들러
? 차일드 윈도우의 통지 메시지를 처리하는 역할을 한다.
? 차일드 윈도우 통지 메시지 다섯 가지 유형
?범용 컨트롤 핸들러
?단추(Button) 핸들러
?콤보(Combo) 박스 핸들러
?편집(Edit) 컨트롤 핸들러
?목록(List) 상자 핸들러
? 범용 컨트롤 통지 핸들러

처리할 메시지나 명령

컨트롤의 식별자

클래스에 정의된
메시지 핸들러 메소드

Visual C++ Programming

(C) 1998 Sang Il Kim

ON_CONTROL (wNotifyCode, ID, ClassMethod)

1
0

CHAPTER 2
? 차일드 윈도우 통지 메시지 핸들러
? 단추 컨트롤 통지 핸들러
ON_BN_*EVENT* (ID, ClassMethod)
단추 컨트롤의 식별자

클래스에 대한
메시지 핸들러 메소드

? ON_BN_*EVENT*는 미리 정의된 BN_*(단추 통지) 메시지 매크로 중
어느 하나를 나타낸다.
ON_BN_CLICKED
ON_BN_DISABLE
(C) 1998 Sang Il Kim

ON_BN_DOUBLECLICKED
ON_BN_HILITE
ON_BN_PAINT
ON_BN_UNHILITE
Visual C++ Programming

1
0

CHAPTER 2
? 차일드 윈도우 통지 메시지 핸들러
? 콤보 상자 컨트롤 통지 핸들러
ON_CBN_*EVENT* (ID, ClassMethod)
콤보 상자 컨트롤의
식별자

클래스에 대한
메시지 핸들러 메소드

? ON_CBN_*EVENT*는 미리 정의된 CBN_*(콤보 상자 통지) 메시지
ON_CBN_CLOSEUP

ON_CBN_KILLFOCUS

ON_CBN_DBLCLK

ON_CBN_SELCHANGE

ON_CBN_DROPDOWN

ON_CBN_SELENDCANCEL

ON_CBN_EDITCHANGE

ON_CBN_SELENDOK

ON_CBN_EDITUPDATE

ON_CBN_SETFOCUS

(C) 1998 Sang Il Kim

매크로 중 어느 하나를 나타낸다.

ON_CBN_ERRSPACE
Visual C++ Programming

1
0

CHAPTER 2
? 차일드 윈도우 통지 메시지 핸들러
? 편집 컨트롤 통지 핸들러
ON_EN_*EVENT* (ID, ClassMethod)
편집 상자 컨트롤의
식별자

클래스에 대한
메시지 핸들러 메소드

? ON_EN_*EVENT*는 미리 정의된 EN_*(편집 통지) 메시지 매크로 중
ON_EN_CHANGE

ON_EN_MAXTEXT

ON_EN_ERRSPACE

ON_EN_SETFOCUS

ON_EN_HSCROLL

ON_EN_UPDATE

ON_EN_KILLFOCUS

ON_EN_VSCROLL

(C) 1998 Sang Il Kim

어느 하나를 나타낸다.

Visual C++ Programming

11
0

CHAPTER 2
? 차일드 윈도우 통지 메시지 핸들러
? 목록 상자 컨트롤 통지 핸들러
ON_LBN_*EVENT* (ID, ClassMethod)
목록 상자 컨트롤의
식별자

클래스에 대한
메시지 핸들러 메소드

? ON_LBN_*EVENT*는 미리 정의된 LBN_*(목록 상자 통지) 메시지
매크로 중 어느 하나를 나타낸다.
ON_LBN_DBLCLK
ON_LBN_ERRSPACE
(C) 1998 Sang Il Kim

ON_LBN_KILLFOCUS
ON_LBN_SELCANCEL
ON_LBN_SELCHANGE
ON_LBN_SETFOCUS
Visual C++ Programming

11
1

CHAPTER 2
? MFC가 제공하지 않는 윈도우 메시지 핸들러 정의하기
? Win32가 제공하는 윈도우 메시지는 모두 ON_MESSAGE() 매크로를
사용하여 핸들러를 정의할 수 있다.
? 예를 들어, WM_SETREDRAW 메시지에 대한 미리 정의된 MFC 메시지
핸들러는 존재하지 않는다.
? 이 메시지에 대한 핸들러를 만들려면, ON_MESSAGE() 메시지 맵 항목을
다음과 같이 정의한다.
ON_MESSAGE(WM_SETREDRAW, OnSetReDraw)
? 클래스 선언에 OnSetReDraw() 메시지 핸들러를 선언한다.
? wParam과 lParam인수는 MSG 구조의 멤버들과 동일한데, 이들의 값은
처리중인 메시지에 따라 달라진다.

Visual C++ Programming

(C) 1998 Sang Il Kim

afx_msg LRESULT OnSetReDraw(WPARAM wParam, LPARAM lParam);

11
2

CHAPTER 2
? 사용자 정의 메시지 핸들러
? 사용자가 정의한 메시지 맵 항목은 다음 둘 중의 하나의 부류에 속한다.
?사용자 정의 내부 항목
?사용자 정의 외부 항목
? 사용자 정의 내부 메시지 맵 항목
ON_MESSAGE (MessageMacro, ClassMethod)
처리할 메시지의
매크로 값

클래스를 위해 정의된
메시지 핸들러 메소드

(C) 1998 Sang Il Kim

? 클래스 선언에 ClassMethod() 메시지 핸들러를 선언한다.
afx_msg LONG ClassMethod (UINT, LONG);

Visual C++ Programming

11
3

CHAPTER 2
? 사용자 정의 메시지 핸들러
? 사용자 정의 외부 메시지 맵 항목
ON_REGISTERED_MESSAGE (MessageMacro, ClassMethod)
처리할 메시지의
매크로 값

클래스를 위해 정의된
메시지 핸들러 메소드

? 클래스 선언에 ClassMethod() 메시지 핸들러를 선언한다.
afx_msg LONG ClassMethod (UINT, LONG);

메시지

메시지 맵

메시지 핸들러

WM_PAINT
WM_LBUTTONDOWN
WM_CHAR

ON_WM_PAINT()
void OnPaint()
ON_WM_LBUTTONDOWN() void OnLButtonDown(UINT nFlags, CPoint point)
ON_WM_CHAR()
void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

Visual C++ Programming

(C) 1998 Sang Il Kim

? 메시지와 메시지 핸들러의 대응 예

11
4

CHAPTER 2

클래스들은 MFC에서 사용하고
있는 코드 관례를 따르기 위해
항상 대문자 C로 시작한다.

// 프레임 윈도우 클래스
class CMyFrame: public CMainFrame
{
클래스 선언에서 메시지
public:
핸들러를 구별하기 위한 표시
CMyFrame();
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnPaint();
“afx_msg”로 표시된 두 함수는
DECLARE_MESSAGE_MAP()
MFC 라이브러리 메시지
};
전달 체계를 통해 전달되는
메시지를 처리한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 어플리케이션 프레임워크 예제
? 헤더파일(.h)
// 어플리케이션 클래스
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};

11
5

CHAPTER 2
? 어플리케이션 구현파일(.cpp)
#include <afxwin.h> // 기초 클래스가 선언된 MFC 라이브러리 헤더 파일
#include “myapp.h”
CMyApp theApp; // 단 하나만 존재하는 CMyApp 객체
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMyFrame();
m_pMainWnd -> ShowWindow(m_nCmdShow);
m_pMainWnd -> UpdateWindow();
return TRUE;
}
(C) 1998 Sang Il Kim

BEGIN_MESSAGE_MAP (CMyFrame, CFrameWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
Visual C++ Programming

11
6

CHAPTER 2
? 어플리케이션 구현파일
CMyFrame::CMyFrame()
{
Create(NULL, “MYAPP Application”);
}

void CMyFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
TRACE(“Entering CMyFrame::OnLButtonDown %lx, %d, %d\n”, (long)nFlags, point.x, point.y);
}
Visual C++ Programming

(C) 1998 Sang Il Kim

void CMyFrame::OnPaint()
{
CPaintDC dc(this);
dc.TextOut(0, 0, “Hello, world!”);
}

11
7

CHAPTER 2
? WinMain() 함수
? 어플리케이션 내부에 숨겨져 있다.
? CMyAPP 클래스
? CMyAPP의 객체는 어플리케이션을 나타낸다.
? CMyApp::InitInstance() 멤버 함수
? 어플리케이션의 메인 프레임 윈도우를 구성하고, 출력하는데 필요한
함수를 호출
? CWinAPP에 상속된 함수
? 메시지 루프를 만든다.
? CMyFrame 클래스
? 이 클래스의 객체는 어플리케이션의 메인 프레임 윈도우를 나타낸다.
? CFrameWnd의 Create() 멤버 함수를 호출하면 실제 윈도우가 만들어진다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWinApp::Run() 멤버 함수

11
8

CHAPTER 2
? CMyFrame::OnLButtonDown() 함수
? WM_LBUTTONDOWN() 메시지를 처리하는 함수
? CMyFrame::Onpaint() 함수
? WM_PAINT() 메시지를 처리하는 함수
? 어플리케이션 실행 순서
? 어플리케이션 실행

WinMain() 함수 호출

CWinApp로 부터

파생된 클래스의 어플리케이션 전역 객체를 찾는다.
InitInstance() 멤버 함수를 호출

Run() 멤버 함수를 호출

? CMyFrame 객체 소멸

Run() 에서 메시지 루프를 빠져 나온다

WinMain() 함수를 끝낸다

CMyApp 객체 소멸

Visual C++ Programming

(C) 1998 Sang Il Kim

? 어플리케이션 종료(Shutdown)

11
9

CHAPTER 2
? Sequence of Execution
? 응용 프로그램 초기화 과정에서 WinMain()이 응용 프로그램 객체의
InitApplication()과 InitInstance() 메소드를 호출한다.
? WinMain()이 Run() 메소드를 호출할 때, 응용 프로그램의 메시지 펌프가 시작되고,
응용 프로그램의 실행이 끝나면 WinMain()이 응용 프로그램 객체의 ExitInstance()
메소드를 호출한다.
? CWinApp is derived from CWinThread.
? Represents the main thread of execution for your application.
? In recent versions of MFC, the InitInstance, Run, ExitInstance, and OnIdle
member functions are actually in class CWinThread.
WinMain
calls

Standard function supplied by framework
InitInstance

Initializes current instance of the application
(C) 1998 Sang Il Kim

calls
Runs the message loop and OnIdle

Run
calls
ExitInstance

Cleans up after the application

Visual C++ Programming

1
2

CHAPTER 3

(C) 1998 Sang Il Kim

AppWizard 사용하기
“Hello, World!”

Visual C++ Programming

1
2

CHAPTER 3
? 도큐먼트와 뷰(Documents and Views)
? 도큐먼트 기초 클래스
?도큐먼트 기초 클래스 코드는 File메뉴의 Open및 Save메뉴
아이템과 상호작용한다.
?파생된 도큐먼트 클래스는 도큐먼트 객체의 데이터를 실질적으로
읽고 쓰는 일을 한다.

?프레임 윈도우 내에 포함된 클라이언트 영역의 윈도우를 나타낸다.
?파생된 뷰 클래스는 자신과 연결된 도큐먼트 클래스와 밀접하게
작용하며 어플리케이션의 화면 출력과 프린터 I/O을 수행한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 뷰 기초 클래스

1
2

CHAPTER 3
? 도큐먼트/뷰 구조

View

Document

(C) 1998 Sang Il Kim

Part of document
currently visible

Visual C++ Programming

1
2

CHAPTER 3
? 뷰(View)
? 사용자 관점
? 사용자가 크기를 변경하고 이동하고 닫을 수 있는 정상적인 윈도우.
? 프로그래머 관점
? MFC 라이브러리 CView 클래스에서 파생된 C++ 객체.
? MFC 라이브러리 뷰 클래스 코드
? 헤더파일(H) ? 구현파일(CPP)
? 단일 도큐먼트 인터페이스(SDI) 와 다중 도큐먼트 인터페이스(MDI)

(C) 1998 Sang Il Kim

? SDI 어플리케이션
? 하나의 윈도우만 가지고 있다.
? 한 번에 하나의 도큐먼트만이 로드된다.
? Notepad
? MDI 어플리케이션
? 다수의 차일드(child) 윈도우를 가지고 있다.
? 각 차일드 윈도우는 별도의 도큐먼트를 갖는다.
? Word, 아래아한글(Hangul)
Visual C++ Programming

1
2

CHAPTER 3
? OnDraw() 멤버 함수
? CView 클래스의 가상 멤버 함수
? 뷰 윈도우가 다시 그려질 때마다 어플리케이션 프레임워크에 의해서 호출.
? 프로그램 내의 함수가 윈도우의 데이터를 변경시키는 경우
? 뷰에 상속된 멤버 함수 Invalidate() (또는 InvalidateRect())를 호출하여
윈도우에 변경된 사실을 알려주어야 한다.
? Invalidate()가 호출된 후에 OnDraw() 함수가 호출된다.
? CView::OnDraw
? virtual void OnDraw( CDC* pDC ) = 0;
(C) 1998 Sang Il Kim

? Parameters
? pDC 디바이스 컨텍스트에 대한 포인터

Visual C++ Programming

1
2

BOOL / TextOut

? CDC::TextOut
? virtual BOOL TextOut( int x, int y, LPCTSTR lpszString, int nCount );
? BOOL TextOut( int x, int y, const CString& str );
? Parameters
?x 텍스트가 시작하는 x좌표(논리 단위).
?y 텍스트가 시작하는 y좌표(논리 단위).
?lpszString 출력하는 텍스트 문자열에 대한 포인터.
?nCount lpszString 파라미터에 의해 가리키는 문자열에 있는 문자의 수.
?str 출력하는 텍스트 문자열을 포함하는 CString 오브젝트에 대한 참조.
Visual C++ Programming

(C) 1998 Sang Il Kim

? bool declarators;
? This keyword is an integral type.
? A variable of this type can have values true and false.
? !false == true
!true == false
? if (expres1) statement1;
If expres1 is true, statement1 is always executed; if expres1 is false,
statement1 is never executed.

1
2

SelectStockObject(내장객체 중의 하나를 디바이스 컨텍스트에 선택)

종류

의미

BLACK_BRUSH
DKGRAY_BRUSH
GRAY_BRUSH
HOLLOW_BRUSH
LTGRAY_BRUSH
NULL_BRUSH
WHITE_BRUSH
BLACK_PEN
NULL_PEN
WHITE_PEN
ANSI_FIXED_FONT
ANSI_VAR_FONR
DEVICE_DEFAULT_FONT
OEM_FIXED_FONT
SYSTEM_FONT
SYSTEM_FIXED_FONT
DEFAULT_PALETTE

검정색 브러시
검정 회색 브러시
회색 브러시
투명한 브러시
밝은 회색 브러시
널 브러시
흰색 브러시
검정색 펜
널펜
흰색 펜
ANSI 고정 시스템 폰트
ANSI 가변 시스템 폰트
디바이스 의존(Device-dependent) 폰트
OEM 의존 고정 폰트
시스템 폰트 (메뉴, 다이얼로그박스 컨트롤, 텍스트)
고정폭(Fixed-width) 시스템 폰트 (Win3.0 이전 버전)
기본 색상 팔레트(Default color palette)
Visual C++ Programming

(C) 1998 Sang Il Kim

? virtual CGdiObject* SelectStockObject(int nIndex);
? Parameters

1
2

Ellipse
? About Ellipses - 현재의 펜과 현재의 브러쉬로 타원 내부를 채운다.
An ellipse is a closed curve defined by two fixed points (f1 and f2) such that the
sum of the distances (d1 + d2) from any point on the curve to the two fixed points
is constant.
Ellipse
d1

d2

?

f1

?

f2

? BOOL Ellipse(int x1, int y1, int x2, int y2);
? BOOL Ellipse( LPCRECT lpRect);
? Parameters
? lpRect 타원의 경계 사각형의 좌표를 포함하는 RECT 구조체나 CRect 객체에 대한
포인터
? 사각형의 높이 : y2 - y1
? 사각형의 폭 : x2 - x1.
Visual C++ Programming

(C) 1998 Sang Il Kim

Bounding rectangle

1
2

CHAPTER 3
? Visual C++를 이용한 프로그램 작업 순서
? The visual design step
? The code-writing step

? 프로젝트의 설계
? 기본 골격의 작성
? 리소스 편집
? 프로그램 코드 기술
? 컴파일(Debug)
? 실행, 디버깅
? 컴파일(Release)

내용
프로그램 동작과 윈도의 외관을 결정한다.
AppWizard를 이용한다.
ResourceView를 이용한다.
ClassWizard를 이용한다.
디버그 정보가 있는 실행 파일을 만든다.
문제가 생긴 부분을 디버거로 알아낸다.
완성된 버전의 실행 파일을 만든다.

Visual C++ Programming

(C) 1998 Sang Il Kim

항목

1
2

CHAPTER 3
? 진단 매크로(Diagnostic Macros)를 가능한 상태로 만들기
? TRACE 매크로 - 프로그램 상태를 모니터링 한다.
? 이 매크로를 사용하기 위해서는 트레이싱이 가능한 상태로 설정되
어야 한다(디폴트로 설정되어 있다).
? TRACER 유틸리티(… \Vc\bin\Tracer.exe)를 실행하여 Enable
tracing을 체크한다.
?TraceEnabled = 1
? 프리컴파일 헤더(Precompiled Headers) 이해하기
? AppWizard는 프로젝트를 생성할 때에 스위치 설정과 프리컴파일 헤더를
위한 파일들을 만들어 준다.
? 자동 프리컴파일 헤더
(C) 1998 Sang Il Kim

?/Yx 스위치를 사용해서 활성화 된다.
?데이터 베이스 파일에 컴파일 결과를 저장한다.
? 수동 프리컴파일 헤더
?/Yc, /Yu 스위치에 의해서 활성화 된다.
Visual C++ Programming

1
3

CHAPTER 3
? 프리컴파일 헤더(Precompiled Headers) 이해하기
? 소스 파일 StdAfx.cpp에는 한 문장만이 포함된다.
// 다른 헤더 파일을 포함시키는 역할을 한다.

? #include문
?#include <afxwin.h>
?#include <afxext.h>
?#include <afxole.h>
?#include <afxdisp.h>
?#include <afxtempl.h>
?#include <afxcmn.h>
?#include <afxdlgs.h>
?#include <afxres.h>

// MFC 핵심 표준 구성요소들
// MFC 확장 클래스
// MFC OLE compound document를 사용
// Automation 또는 ActiveX 컨트롤을 사용
// 템플릿 기반 콜렉션 클래스를 사용(p519)
// MFC 공통 컨트롤
// MFC 대화 상자
// MFC 자원
(C) 1998 Sang Il Kim

?#include “StdAfx.h”

? 프로그램을 실행시키는 두 가지 방법
? Developer Studio에서 직접 실행 : Ctrl + F5
? Debugger 에서 실행 : F5
Visual C++ Programming

1
3

CHAPTER 3
StdAfx.h
#include “afxwin.h”
#include “afxext.h”

StdAfx.cpp

myprog.cpp

#include “stdafx.h”

#include “stdafx.h”
#include “myprog.h”

StdAfx.pch

/Yu “stdafx.h”
(C) 1998 Sang Il Kim

/Yc “stdafx.h”

/Fp “path” sets path for this file

◐ Visual C++ 프리컴파일 헤더 처리과정 ◑
Visual C++ Programming

1
3

CHAPTER 3
프레임워크의 처리
CWinApp::CWinApp
여러가지 초기화
WinMain

개발자와 AppWizard가 기술한 코드
CHelloApp theApp;
어플리케이션의 객체정의
CHelloApp::CHelloApp

InitApplication

Run
메시지루프

CView::OnPaint
시간의 흐름

CHelloApp::InitInstance
도큐먼트 템플릿의 작성
윈도우 생성
CMainFrame::OnCreate
(C) 1998 Sang Il Kim

InitInstance

CHelloView::OnDraw

이후 메시지 루프를 계속한다

◐ Hello World의 흐름 ◑

Visual C++ Programming

1
3

성공의 A B C
Ability(능력)
Brain(두뇌)

(C) 1998 Sang Il Kim

Challenge(도전)

Visual C++ Programming

1
3

CHAPTER 4

(C) 1998 Sang Il Kim

기본적인 이벤트 처리,
맵핑 모드, 스크롤 뷰

Visual C++ Programming

1
3

CHAPTER 4
? 윈도우 이벤트가 발생할 때 어플리케이션 프레임워크가 호출하는 멤버 함수
? 이름이 On으로 시작되는 함수

?OnKeyDown(), OnLButtonDown()

? 어플리케이션 프레임워크에 의해서 호출되는 함수들은 대부분 가상 함수가
아니기 때문에 프로그래밍 단계가 더 필요하다.

? 어플리케이션 프레임워크에 자신의 메시지 핸들러 함수의 코드를 연결하기
위해서는 메시지 맵 구조가 필요하다.

? 헤더 파일
? 함수 원형을 선언
? 구현 파일
? 함수를 어플리케이션 프레임워크와 연결해 주는 메시지 맵 매크로를 작성
Visual C++ Programming

(C) 1998 Sang Il Kim

? 메시지 맵
CHAPTER 2 참조
? 사용자가 마우스 왼쪽 버튼을 누른다.
윈도우는 WM_LBUTTONDOWN
메시지를 해당 윈도우에 보낸다.
프로그램이 WM_LBUTTONDOWN
메시지를 처리한다.

1
3

CHAPTER 4
마우스 버튼 + 다른 키

? <함수의 원형 선언부분, 헤더파일>
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
? afx_msg는 이 함수가 메시지 맵 함수의 원형임을 알려준다.
? <멤버함수 구현부분, 소스파일>
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
프로그램 윈도우의 작업
// 이벤트 처리코드…
영역에서 마우스의 x, y
}
위치를 전달(상대좌표)

? OnLButtonDown() 함수를 어플리케이션 프레임워크와 연결해 주는 메시지 맵
? <클래스 선언부분, 헤더파일>
DECLARE_MESSAGE_MAP()
(C) 1998 Sang Il Kim

? <코드구현 부분, 소스파일>
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN
END_MESSAGE_MAP()
Visual C++ Programming

1
3

CHAPTER 4
? WM_XXX 메시지와 대응하는 MFC 함수 프로토타입

WM_CHAR
WM_CREATE
WM_LBUTTONDOWN
WM_DESTROY
WM_LBUTTONUP
WM_MOUSEMOVE
WM_PAINT
WM_SIZE

함수 프로토타입
afx_msg void OnChar(UINT, UINT. UINT)
afx_msg int OnCreate(LPCREATESTRUCT)
afx_msg void OnLButtonDown(UINT, CPoint)
afx_msg void OnDestroy()
afx_msg void OnLButtonUp(UINT, CPoint)
afx_msg void OnMouseMove(UINT, CPoint)
afx_msg void OnPaint()
afx_msg void OnSize(UINT, int, int)
(C) 1998 Sang Il Kim

메시지

Visual C++ Programming

1
3

CHAPTER 4
? 뷰 상태 저장하기 - 클래스 데이터 멤버가 필요하다.
? rectEllipse
?CRect 클래스 객체로 타원의 주변 사각형을 저장.
? m_nColor
?타원의 색상값을 저장하는 정수.
? 뷰 클래스 데이터 멤버 초기화
?CMyView::CMyView() : m_rectEllipse(0, 0, 200, 200) {… }
? MFC 라이브러리의 클래스 데이터 멤버의 이름은 m_ 으로 시작한다.
? 다시 그려져야 할 영역들을 포함하고 있는 최소한의 사각형
? OnLButtonDown()
OnDraw() 호출

InvalidateRect()

WM_PAINT 메시지를 생성

Invalidate Rectangle 파라 미터를 접근
Visual C++ Programming

(C) 1998 Sang Il Kim

? 무효화 사각형(Invalidate Rectangle)

1
3

CHAPTER 4
? 윈도우 클라이언트 영역(Client Area)
? 윈도우에서 경계선, 캡션바, 메뉴바, 툴바 등이 차지하는 부분을 제외한 영역.
? GetClientRect() : 클라이언트 영역의 크기를 알 수 있다.
? 클라이언트 영역 외부에서는 그리기를 수행할 수 없다.
? CRect, CPoint, CSize
? DevStudio\Vc\mfc\include\<afxwin.h>에 정의 (60, 137, 171, 212 line)
? 상속받는 데이터 멤버
?CRect

left, top, right, bottom

?CPoint

x, y

?CSize

cx, cy
(C) 1998 Sang Il Kim

? 포인트가 사각형 내에 존재하는지 검사하는 방법
? if(m_rectEllipse.PtInRect(point)) {
//포인트가 사각형 내에 있을 때 처리할 부분
}
Visual C++ Programming

1
4

CHAPTER 4
? 포인트가 타원 내에 존재하는지 검사하는 방법
? 타원에 대응하는 CRgn 클래스의 객체를 생성한 후, PtInRegion() 함수 사용
? CRgn rgn;
윈도우 내부의 타원이나
rgn.CreateEllipticRgnIndirect(m_rectEllipse); 다각형 영역을 나타내는
특수한 영역 구조체를 생성한 후
if(rgn.PtInRegion(point)) {
이 구조체를 프로그램에 있는
//포인트가 타원 내에 있을 때 처리할 부분
C++ CRgn 객체에 연결한다.
}
? CRect 클래스의 LPRECT 연산자
? CWnd::InvalidateRect()
CRect에 LPRECT() 연산자가 중복정의 되어 있기 때문에 인자가 CRect 객체
가 되더라도 실제 LPRECT 변수를 써놓은 것과 동일하게 사용할 수 있다.
?CRect rectClient;
GetClientRect(rectClient); // 윈도우의 클라이언트 영역을 얻는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );

1
4

CHAPTER 4

? CWnd::InvalidateRect - 특정 사각형을 무효화한다.
? void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );
? Parameters
?lpRect
사용자 좌표로 무효화되는 사각형을 갖는 RECT 구조체나
CRect객체에 대한 포인터.
NULL이면, 윈도우는 윈도우의 전체 사용자 영역을 무효화한다.
?bErase 칠하기 전에 갱신 영역을 지워야 한다면 TRUE.
갱신 영역의 어떤 부분을 지우기 위해 마크되면 전체 갱신 영역이
지워진다.
영역은 윈도우에 WM_ERASEBKGND 메시지를 보내 지운다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::Invalidate - 윈도우의 사용자 영역을 무효화한다.
? NULL 사각형 포인터가 함수를 호출한다.
? 윈도우의 무효화 영역은 현재 갱신영역에 모인다.
? 갱신 영역은 윈도우가 WM_PAINT 메시지를 보내는 다음 번에 칠하는 윈도우의
영역이다.
? 윈도우는 갱신 영역이 비어 있지 않고 어플리케이션에 대해 대기한 그 이상의
메시지가 없을 때에만 윈도우에 칠하기 명령을 보낸다.
? void Invalidate( BOOL bErase = TRUE );

1
4

CHAPTER 4

(C) 1998 Sang Il Kim

? Size
? CSize Size() const;
? 사각형의 폭과 높이를 계산하고 CSize 객체로 리턴 한다.
? 폭(width)은 오른쪽 x 좌표에서 왼쪽 x 좌표를 뺀 것.
? 높이(height)는 하단의 y 좌표에서 상단의 y좌표를 뺀 것.
? 이 값들의 어느 것이나 사각형이 일반화되어 있지 않으면 음수가 된다.
?예
?CRect rect(1,1,5,7);
CSize size;
size = rect.Size(); // size는 4,6으로 설정된다.

Visual C++ Programming

1
4

CHAPTER 4
? Rectangle
? BOOL Rectangle(int x1, int y1, int x2, int y2);
? BOOL Rectangle(LPCRECT lpRect);
? Parameters
?x1
사각형의 왼쪽 상단의 x좌표(논리단위)
?y1

사각형의 왼쪽 상단의 y좌표(논리단위)

?x2

사각형의 오른쪽 하단의 x좌표(논리단위)

?y2

사각형의 오른쪽 하단의 y좌표(논리단위)

?lpRect

사각형의 좌표(논리단위)를 포함하는 RECT 구조체나
(C) 1998 Sang Il Kim

CRect 객체에 대한 포인터

Visual C++ Programming

1
4

CHAPTER 4
? WM_PAINT 메시지가 발생되는 경우
? 사용자가 윈도우를 옮기거나, 윈도우를 제거했을 때 발생한다.
? 사용자가 윈도우의 크기를 바꿀 때 발생한다.
? 응용 프로그램이 SendMessage() 함수를 호출하여 WM_PAINT 메시지를
발생시킬 수 있다.
? 응용 프로그램이 그것의 작업 영역의 일부를 스크롤하기 위하여
ScrollWindow()나, ScrollDC() 함수를 호출할 때 발생한다.
? 응용 프로그램이 강제적으로 WM_PAINT 메시지를 발생시키기 위해서
InvalidateRect()나, InvalidateRgn() 함수를 호출할 때 발생한다.
? 윈도우가 윈도우의 겹친 다이얼로그 박스나 메시지 박스를 제거할 때
(C) 1998 Sang Il Kim

발생한다.
? 메뉴가 나타났다가 없어질 때 발생한다.
? 커서가 작업 영역을 지나서 이동할 때 발생한다.
? 아이콘이 작업 영역을 지나서 드래그(Drag)될 때 발생한다.
Visual C++ Programming

1
4

CHAPTER 4
? 마우스 처리
? 클라이언트 영역 마우스 메시지
? 비 클라이언트 영역 마우스 메시지
? 클라이언트 영역 마우스 메시지
? 커서가 윈도우의 클라이언트 영역 내에 있을 때 시스템에 의해 계속 발생된다.

메시지 맵 매크로
ON_WM_MOUSEMOVE()

의미
사용자가 마우스를 움직임

ON_WM_LBUTTONDBLCLK()

사용자가 왼쪽 마우스 버튼을 두 번 클릭함

ON_WM_LBUTTONDOWN()

사용자가 왼쪽 마우스 버튼을 클릭함

ON_WM_LBUTTONUP()

사용자가 왼쪽 마우스 버튼을 놓음

ON_WM_MBUTTONDBLCLK()

사용자가 가운데 마우스 버튼을 두 번 클릭함

ON_WM_MBUTTONDOWN()

사용자가 가운데 마우스 버튼을 클릭함

ON_WM_MBUTTONUP()
ON_WM_RBUTTONDBLCLK()

사용자가 가운데 마우스 버튼을 놓음
사용자가 오른쪽 마우스 버튼을 두 번 클릭함

ON_WM_RBUTTONDOWN()

사용자가 오른쪽 마우스 버튼을 클릭함

ON_WM_RBUTTONUP()

사용자가 오른쪽 마우스 버튼을 놓음
Visual C++ Programming

(C) 1998 Sang Il Kim

? 클라이언트 영역 마우스 메시지를 위해 MFC가 미리 정의한 메시지 맵 매크로

1
4

CHAPTER 4
? 마우스 처리
? 마우스는 하나 또는 그 이상의 버튼을 가진 포인팅 디바이스(Pointing Device)
이다. 윈도우는 마우스가 어떤 동작을 할 때 그 동작에 해당하는 메시지를 발생
시킨다. 프로그램은 이 메시지를 받아서 그 메시지에 대한 처리만 해주면 된다.

class CWnd : public CCmdTarget
{
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
:
}
? CWnd 클래스에 protected 액세스 권한을 갖는 멤버 함수로 되어있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? WM_MOUSEMOVE 메시지
윈도우는 마우스가 특정 윈도우를 가지거나 움직일 때, 발생되는 메시지를
전달한다. 이때 윈도우는 이 메시지와 함께 마우스와 관련된 정보를 현재 입력
포커스(마우스 커서가 위치한 윈도우)를 가지고 있는 프로그램에 전달한다.
이러한 정보에는 프로그램 윈도우의 작업 영역에서의 마우스 커서 위치와
눌려진 마우스 버튼에 대한 것들이 포함된다.

1
4

CHAPTER 4
? OnMouseMove() 메시지 처리 함수의 nFlags 매개 변수에 전달되는 값
nFlags 값
MK_CONTROL
MK_LBUTTON
MK_MBUTTON
MK_RBUTTON
MK_SHIFT

의미
Ctrl 키와 함께 마우스 버튼이 눌려졌다.
마우스의 왼쪽 버튼이 눌려졌다.
마우스의 가운데 버튼이 눌려졌다.
마우스의 오른쪽 버튼이 눌려졌다.
Shift 키와 함께 마우스 버튼이 눌려졌다.

? windows.h 에 #define으로 정의
? void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
if(nFlags & MK_SHIFT) // Shift 키에 대한 처리
else if(nFlags & MK_LBUTTON) // 마우스의 왼쪽 버튼에 대한 처리
}
Visual C++ Programming

(C) 1998 Sang Il Kim

{

1
4

CHAPTER 4
? 마우스 버튼 메시지
Button

Button Down

왼쪽
가운데
오른쪽

WM_LBUTTONDOWN
WM_MBUTTONDOWN
WM_RBUTTONDOWN

Button Up

Button DoubleClick

WM_LBUTTONUP WM_LBUTTONDBLCLK
WM_MBUTTONUP WM_MBUTTONDBLCLK
WM_RBUTTONUP WM_RBUTTONDBLCLK

(C) 1998 Sang Il Kim

class CWnd : public CCmdTarget
{
protected: // 메시지 핸들러 메소드 프로토타입
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
}
? CWnd 클래스에 protected 액세스 권한을 갖는 멤버 함수로 되어있다.
Visual C++ Programming

1
4

CHAPTER 4
? 마우스 캡쳐
? 응용 프로그램 창에서 사용자가 마우스 버튼을 누르게 되면, 윈도우 시스템은
그 창에 WM_*BUTTONDOWN 메시지 중의 하나를 보내게 된다 .
? 이와 같은 플래그를 설정하는 버튼 누름 메시지는 응용 프로그램이 동기를
벗어나지 않도록 이에 대응하는 버튼 놓음 메시지를 갖고 있어야 한다.
? 윈도우에서 사용자가 마우스 버튼을 누른 상태에서 윈도우 바깥쪽으로
마우스를 움직이고, 그 때 마우스 버튼을 놓게 되면, 윈도우의 동기가 맞지
않게 된다.
WM_*BUTTONUP 메시지는 전혀 수신되지 않는다.
? 이유는, 마우스 버튼을 놓았을 때 커서가 윈도우 안에 존재하지 않기
때문이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? WM_*BUTTONDOWN 메시지가 윈도우 안에 있을 때 수신되었다 하더라도

1
5

CHAPTER 4
? 마우스 캡쳐
? 클래스 CMainFrame이 CFrameWnd로부터 파생된 프레임 윈도우 클래스라고
가정하면, 클라이언트 영역 마우스 버튼 클릭을 처리하기 위한 메시지 맵은
다음과 같이 만들 수 있다.
BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
(C) 1998 Sang Il Kim

ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

Visual C++ Programming

1
5

CHAPTER 4
? 마우스 캡쳐
? 파생된 CMainFrame::OnLButtonDown() 메소드가 왼쪽 마우스 버튼을
눌렀을 때 BOOL 플래그를 설정한다면(m_bLMouseDown), 핸들러의 코드는
다음과 같은 형태가 된다.
? void CMainWnd::OnLButtonDown (UINT nFlags, CPoint point)
{
m_bLMouseDown = TRUE; // 클래스 멤버 마우스 버튼 누름 플래그를 설정
CFrameWnd::OnLButtonDown (nFlags, point); // 상속된 핸들러를 호출
}
{
m_bLMouseDown = FALSE;// 클래스 멤버 마우스 버튼 누름 플래그를 재설정
CFrameWnd::OnLButtonUp (nFlags, point); // 상속된 핸들러를 호출
}
Visual C++ Programming

(C) 1998 Sang Il Kim

? void CMainWnd::OnLButtonUp (UINT nFlags, CPoint point)

1
5

CHAPTER 4
? 마우스 캡쳐
? 파생된 CMainFrame::OnLButtonDown() 메소드가 왼쪽 마우스 버튼을
눌렀을 때 BOOL 플래그를 설정한다면(m_bLMouseDown), 핸들러의 코드는
다음과 같은 형태가 된다.
? void CMainWnd::OnLButtonDown (UINT nFlags, CPoint point)
{
m_bLMouseDown = TRUE; // 클래스 멤버 마우스 버튼 누름 플래그를 설정
CFrameWnd::OnLButtonDown (nFlags, point); // 상속된 핸들러를 호출
}
{
m_bLMouseDown = FALSE;// 클래스 멤버 마우스 버튼 누름 플래그를 재설정
CFrameWnd::OnLButtonUp (nFlags, point); // 상속된 핸들러를 호출
}
Visual C++ Programming

(C) 1998 Sang Il Kim

? void CMainWnd::OnLButtonUp (UINT nFlags, CPoint point)

1
5

CHAPTER 4
CMainWnd::OnLButtonDown()
CMainWnd::OnLButtonDown()

? 마우스 이벤트의 흐름이 윈도우의
클라이언트 영역 내에서만 발생하게

Set
Set m_bLMouseDown
m_bLMouseDown == TRUE
TRUE

되면, 마우스 버튼 상태 플래그가
기본적으로 동기를 유지하게 된다.
CMainWnd::OnMouseMove()
CMainWnd::OnMouseMove()

CMainWnd::OnLButtonUp()
CMainWnd::OnLButtonUp()
Set
Set m_bLMouseDown
m_bLMouseDown == FALSE
FALSE

Visual C++ Programming

(C) 1998 Sang Il Kim

클라이언트
클라이언트 영역
영역 내에서
내에서
마우스를
마우스를 움직인다.
움직인다.

1
5

CHAPTER 4
? 마우스 캡처하기
? 버튼 누름 메시지 핸들러 내에서 마우스를 캡처하고 버튼 놓음 메시지 핸들러에서
풀게 되면, 윈도우가 항상 동기를 유지함을 보장할 수 있다.
? SetCapture()
아무런 인수도 받아들이지 않으며 현재의 SetCapture()를 호출하기 전에 모든 마우스
입력을 받아들인 CWnd 객체에 대한 포인터를 반환한다.

? void CMainWnd::OnLButtonUp (UINT nFlags, CPoint point)
{
m_bLMouseButton = FALSE; // 클래스 멤버 마우스 누름 플래그
ReleaseCapture();
// 마우스 캡처를 푼다
CFrameWnd::OnLButtonUp(nFlags, point); // 상속된 핸들러를 호출
}
Visual C++ Programming

(C) 1998 Sang Il Kim

? void CMainWnd::OnLButtonDown (UINT nFlags, CPoint point)
{
m_bLMouseButton = TRUE; // 클래스 멤버 마우스 누름 플래그
SetCapture();
// 마우스를 캡처
CFrameWnd::OnLButtonDown(nFlags, point); // 상속된 핸들러를 호출
}

1
5

CHAPTER 4
? 비 클라이언트 영역 마우스 메시지
? 커서가 윈도우의 비 클라이언트 영역 내에 있을 때 계속해서 시스템에 의해 생성된다.
? 윈도우의 비 클라이언트 영역은 캡션 표시줄과 축소와 확대 단추, 닫기 단추,
시스템 메뉴 아이콘, 윈도우 틀 등으로 이루어져 있다.
? 비 클라이언트 영역 마우스 메시지를 위해 MFC가 미리 정의한 메시지 맵 매크로
ON_WM_NCMOUSEMOVE()

의미
사용자가 비 클라이언트 영역에서 마우스를 움직임

ON_WM_NCLBUTTONDBLCLK()

왼쪽 마우스 버튼을 두 번 클릭함

ON_WM_NCLBUTTONDOWN()

왼쪽 마우스 버튼을 클릭함

ON_WM_NCLBUTTONUP()
ON_WM_NCMBUTTONDBLCLK()


왼쪽 마우스 버튼을 놓음
가운데 마우스 버튼을 두 번 클릭함

ON_WM_NCMBUTTONDOWN()

가운데 마우스 버튼을 클릭함

ON_WM_NCMBUTTONUP()

가운데 마우스 버튼을 놓음

ON_WM_NCRBUTTONDBLCLK()

오른쪽 마우스 버튼을 두 번 클릭함

ON_WM_NCRBUTTONDOWN()

오른쪽 마우스 버튼을 클릭함

ON_WM_NCRBUTTONUP()

오른쪽 마우스 버튼을 놓음
Visual C++ Programming

(C) 1998 Sang Il Kim

메시지 맵 매크로

1
5

CHAPTER 4

? nHitTest 매개 변수는 메시지가 전송되었을 때의 커서가 비 클라이언트
영역내의 어느 부분에 있었는지를 나타내는 히트-테스트 코드이다.
? 비 클라이언트 영역 마우스 메시지 핸들러에서 윈도우가 nHitTest 매개 변수
를 제공하기 때문에 자신의 프로그램에서 OnNcHitTest() 메소드를
재정의할 필요는 거의 없다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 메시지 핸들러 메소드 프로토타입
afx_msg UINT OnNcHitTest (CPoint point);
afx_msg void OnNcLButtonDown (UINT nHitTest, CPoint point);
afx_msg void OnNcLButtonUp (UINT nHitTest, CPoint point);
afx_msg void OnNcLButtonDblClk (UINT nHitTest, CPoint point);
afx_msg void OnNcMButtonDown (UINT nHitTest, CPoint point);
afx_msg void OnNcMButtonUp (UINT nHitTest, CPoint point);
afx_msg void OnNcMButtonDblClk (UINT nHitTest, CPoint point);
afx_msg void OnNcRButtonDown (UINT nHitTest, CPoint point);
afx_msg void OnNcRButtonUp (UINT nHitTest, CPoint point);
afx_msg void OnNcRButtonDblClk (UINT nHitTest, CPoint point);
afx_msg void OnNcMouseMove (UINT nHitTest, CPoint point);

1
5

CHAPTER 4
? GDI 좌표 시스템
? 물리적 좌표 시스템(장치좌표), 논리적 좌표 시스템(논리좌표)
? 물리적 좌표 시스템
?비디오 화면과 같은 물리적 장치의 좌표계
?화면의 창은 원점(0,0)이 화면 왼쪽 위에서 시작하며,
오른쪽으로 갈수록 x축의 값이 증가하고, 아래로 내려갈수록 y축의 값이 증가한다.
?창의 오른쪽 아래는 화면의 오른쪽 아래에 해당된다.
?비디오 화면의 실제 수는 현재의 비디오 해상도에 좌우된다.
?일반적인 해상도 (640, 480), (800, 600), (1024, 768)
원점 (0,0)

+X축

+Y축

(C) 1998 Sang Il Kim

◐ 물리적 좌표 시스템
장치좌표

Visual C++ Programming

1
5

CHAPTER 4
? GDI 좌표 시스템
? 윈도우는 그래픽 출력을 내보내기 전에 현재의 논리적 화면의 좌표를
물리적 장치에 맵핑한다.
? GDI 함수들 각각은 논리적 좌표를 사용하고 있다.
? 맵핑 모드를 이용하여, 응용 프로그램이 GDI 그래픽 출력을 논리적 창에
보내면 GDI는 출력을 물리적 창이나 몇몇 다른 장치(프린터 등)에 맵핑한다.
? 실제 화면 크기를 픽셀 단위로 구하고자 할 때
GetSystemMetrics() 를 사용한다.
? 화면 너비를 구하고자 할 때
GetSystemMetrics(SM_CXSCREEN) 을 사용한다.
(C) 1998 Sang Il Kim

? 화면 높이를 구하고자 할 때
GetSystemMetrics(SM_CYSCREEN) 을 사용한다.

Visual C++ Programming

1
5

CHAPTER 4
? 맵핑 모드(Mapping Mode)
? MM_TEXT 맵핑 모드
? Fixed-Scale(고정 비율) 맵핑 모드
? Variable-Scale (가변 비율) 맵핑 모드

CDC 클래스의 멤버 함수는 논리 좌표를
사용하므로 Rectangle() 함수는
논리 좌표의 원점을 기준으로
사각형을 그린다.(p118-119)

? MM_TEXT 맵핑 모드 ( 장치좌표 )
? 드로잉 단위 : Pixel
? 디바이스 좌표계와 거의 비슷하지만 CDC 클래스의 멤버 함수인
SetViewportOrg 와 SetWindowOrg 함수를 사용하여 원점을 바꿀
수 있다.

(C) 1998 Sang Il Kim

void CMyView::OnDraw(CDC* pDC)
{
pDC -> SetMapMode(MM_TEXT);
pDC -> SetWindowOrg(CPoint(100, 100));
pDC -> Rectangle(CRect(100, 100, 300, 300));
}
? 논리 좌표(100, 100) 은 장치 좌표(0, 0) 에 맵핑된다.
Visual C++ Programming

1
6

CHAPTER 4
(0, 0)

(100, 100) origin in logical coordinate space...

...maps to (0, 0) origin in
device coordinate space

This is the visible part of
logical coordinate space

◐ 원점이 (100, 100) 으로 이동된 다음에 그려진 사각형 ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

This is what you would
see on screen

1
6

CHAPTER 4
? 고정 비율(Fixed-Scale) 맵핑 모드
? CDC::SetMapMode
?virtual int SetMapMode(int nMapMode);
Mapping Mode
Logical Unit
MM_HIENGLISH
MM_LOENGLISH
MM_HIMETRIC
MM_LOMETRIC
MM_TEXT(장치좌표)
MM_TWIPS

0.001 inch
0.01 inch
0.01 mm
0.1 mm
1 device pixel(+X: 오른쪽 , +Y: 아래)
a twip is 1/1440 inch, 1/20 of a point(a point is 1/72 inch)

?Positive x is to the right; positive y is up.(p119)
? 가변 비율(Variable-Scale) 맵핑 모드
MM_ISOTROPIC
MM_ANISOTROPIC

설명
xy 축이 항상 1:1로 유지됨.
xy 축의 scale factor 가 독립적으로 설정될 수 있다.

? MM_ISOTROPIC, MM_ANISOTROPIC 는 현재의 창이나 뷰포트 설정을 변경하지

않는다. 단위나 방향, 비율을 변경하고자 할 때는 CDC::SetWindowExt() 와
CDC:: SetViewportExt() 메소드를 사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

맵핑 모드

1
6

CHAPTER 4
? 맵핑 모드를 처리할 때 유용한 CDC 클래스 메소드
설명

GetViewportExt()

장치 컨텍스트의 뷰포트의 크기를 구한다.

GetViewportOrg()

장치 좌표계에서 뷰포트의 원점을 구한다.

GetWindowExt()

장치 컨텍스트와 연관된 창의 크기를 구한다.

GetWindowOrg()

장치 컨텍스트와 연관된 창의 원점 좌표를 구한다.

ScaleWindowExt()

장치 컨텍스트와 연관된 창의 확장 배율을 정한다.

ScaleViewportExt()

뷰포트의 현재 확장 값들에 상대적으로 뷰포트 확장을 수정한다.

SetViewportExt()

장치 컨텍스트의 확장을 설정한다.

SetViewportOrg()

장치 컨텍스트의 뷰포트 원점을 설정한다.

SetWindowExt()

장치 컨텍스트와 연관된 창의 크기를 설정한다.

SetWindowOrg()

장치 컨텍스트와 연관된 창의 원점을 설정한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

1
6

CHAPTER 4
? 윈도우의 크기에 맞는 타원을 출력하는 OnDraw 함수
? void CMyView::OnDraw(CDC* pDC)
{
CRect rectClient;
GetClientRect(rectClient);
pDC -> SetMapMode(MM_ANISOTROPIC);
pDC -> SetWindowExt(1000, 1000);
pDC -> SetViewportExt(rectClient.right, -rectClient.bottom);
pDC -> SetViewportOrg(rectClient.right / 2, rectClient.bottom / 2);
pDC -> Ellipse(CRect(-500, -500, 500, 500));
? SetWindowExt, SetViewportExt 는 고정 비율 맵핑 모드인 경우, 인자값
들은 무시된다. 그러나, MM_ISOTROPIC 인 경우에는 그림을 그리기 전에
반드시 두 함수가 호출되어야 한다.
? 맵핑 모드는 OnDraw() 함수보다는 CView 클래스의 가상 함수
OnPrepareDC() 에서 설정하는 것이 낫다.
Visual C++ Programming

(C) 1998 Sang Il Kim

}

1
6

CHAPTER 4
Y축
Client rectangle

? MM_ANISOTROPIC
맵핑 모드에서 중앙에
그려진 타원

(0, 500)

(0, 0)

(-500, 0)

(500, 0)
x축

(0, -500)

맵핑 모드에서 중앙에
그려진 타원

Y축
Client rectangle

(-500, 0)

(0, 500)

(0, 0)

(500, 0)

x축
(C) 1998 Sang Il Kim

? MM_ISOTROPIC

(0, -500)

Visual C++ Programming

1
6

CHAPTER 4
? CDC::SetWindowExt - 윈도우의 수평과 수직 범위를 설정한다.
? virtual CSize SetWindowExt(int cx, int cy);
virtual CSize SetWindowExt(SIZE size);
? Parameters
?cx
윈도우의 수평범위 (logical units)
?cy
윈도우의 수직범위 (logical units)
?size 새로운 윈도우의 범위 (logical units) 를 포함하는 SIZE 구조체나
CSize 객체
? CDC::SetViewportExt - 뷰포트의 수평과 수직 범위를 설정한다.

? Parameters
?cx
뷰포트의 수평범위 (device units)
?cy
뷰포트의 수직범위(device units)
?size 새로운 뷰포트 원점(device units)을 포함하는 SIZE 구조체나
CSize 객체
Visual C++ Programming

(C) 1998 Sang Il Kim

? virtual CSize SetViewportExt(int cx, int cy);
virtual CSize SetViewportExt(SIZE size);

1
6

CHAPTER 4
? CDC::SetWindowOrg - 윈도우의 원점을 설정한다.
? CPoint SetWindowOrg(int x, int y);
CPoint SetWindowOrg(POINT point);

? CDC::SetViewportOrg - 뷰포트의 원점을 설정한다.
? virtual CPoint SetViewportOrg(int x, int y);
virtual CPoint SetViewportOrg(POINT point);
? Parameters
?x
새로운 뷰포트 원점의 x 좌표 (장치단위)
?y
새로운 뷰포트 원점의 y 좌표 (장치단위)
?point 새로운 뷰포트 원점(장치단위)을 포함하는 POINT 구조체나
CPoint 객체
Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?x
새로운 윈도우 원점의 x 좌표 ( 논리단위)
?y
새로운 윈도우 원점의 y 좌표 (논리단위)
?point 새로운 윈도우 원점(논리단위)을 포함하는 POINT 구조체나
CPoint 객체

1
6

CHAPTER 4
? 좌표계(Coordinate) 변환
? 좌표 시스템을 언제 사용할 것인가 결정할 수 있는 규칙
?CDC 멤버 함수는 논리 좌표의 파라미터를 사용한다.
?CWnd 멤버 함수는 장치 좌표의 파라미터를 사용한다.
?Hit-Test는 장치 좌표에서 작동한다.
?영역(Region)은 장치 좌표로 정의한다.
?CRect::PtInRect() 등과 같은 함수들은 장치 좌표를 사용하여 작업한다.
?장기간 유지될 값들은 논리 좌표 또는 물리 좌표에 저장한다.

(C) 1998 Sang Il Kim

? 좌표변환 함수들의 프로토타입
void LPtoDP(LPPOINT lpPoints, int nCount = 1) const;
void LPtoDP(LPRECT lpRect) const;
void LPtoDP(LPSIZE lpSize) const;
void DPtoLP(LPPOINT lpPoints, int nCount = 1) const;
void DPtoLP(LPRECT lpRect) const;
void DPtoLP(LPSIZE lpSize) const;
Visual C++ Programming

1
6

CHAPTER 4
? LPtoDP - 논리 좌표를 장치 좌표로 변환
? Parameters
?lpPoints - 변환되는 POINT 구조체나 CPoint 객체에 대한 포인터
?nCount - 변환되는 위치의 수
?lpRect - 변환되는 RECT 구조체나 CRect 객체에 대한 포인터
?lpSize - 변환되는 SIZE 구조체나 CSize 객체에 대한 포인터
? 논리 좌표를 장치 좌표로 변환하는 공식
? x비율인자 = x뷰포트 범위 / x윈도우 범위
? y비율인자 = y뷰포트 범위 / y윈도우 범위
? 장치단위 x = 논리단위 x * x비율인자 + x원점 옵셋
(C) 1998 Sang Il Kim

? 장치단위 y = 논리단위 y * y비율인자 + y원점 옵셋
? DPtoLP - 장치 좌표를 논리 좌표로 변환

Visual C++ Programming

1
6

CHAPTER 4
? 뷰 윈도우 스크롤 하기
? CScrollView 클래스는 CView 클래스에서 파생되었으며, 스크롤바를 가지고 있다.
키보드에 의한 스크롤 기능은 제공되지 않으므로 직접 코드를 작성해야 한다.
? 윈도우는 실제 보이는 크기보다 훨씬 더 크다.
? 실제 보이는 부분을 뷰포트(Viewport)라고 한다.
? 뷰포트의 크기는 클라이언트 영역의 크기에 따라 달라진다.
? 스크롤바를 사용하여 뷰포트의 영역을 옮길 수 있다.

? 또 다른 스크롤 방식
? 라인수가 너무 많아 윈도우에 모두 포함시킬 수 없을 경우, 윈도우에 모든
라인을 포함시키지 않고, 화면에 보이는 만큼의 라인을 얻고 싶다면,
사용자가 CView 로 부터 파생하는 클래스를 작성해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 스크롤바
? 윈도우 자체는 스크롤바를 윈도우에 연결시키지 않는다.
? CScrollView 클래스의 멤버 함수들은 스크롤바에 의해 뷰로 보내지는
WM_HSCROLL, WM_VSCROLL 메시지를 처리해 준다.

1
7

CHAPTER 4

(C) 1998 Sang Il Kim

? CWnd::OnVScroll - 수직 스크롤 이벤트가 뷰에서 발생할 때 호출된다.
? afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
? Parameters
nSBCode - 발생하는 스크롤 행위와 타입
?SB_BOTTOM
아래로 스크롤
?SB_TOP
위로 스크롤
?SB_ENDSCROLL
스크롤의 끝
?SB_LINEDOWN
한 라인 아래로 스크롤
?SB_LINEUP
한 라인 위로 스크롤
?SB_PAGEDOWN
한 페이지 아래로 스크롤
?SB_PAGEUP
한 페이지 위로 스크롤
?SB_THUMBPOSITION
절대 위치로 스크롤
?SB_THUMBTRACK
스크롤 박스를 지정 위치로 드래그한다.
nPos
?SB_THUMBPOSITION or SB_THUMBTRACK 코드에 대한 현재 스크롤바 위치.
그렇지 않으면 사용되지 않는다.
pScrollBar
?알림 코드를 보내는 스크롤바 컨트롤. 이 파라미터는 스크롤바가 뷰에 속해 있으면
NULL이다.
Visual C++ Programming

1
7

? CWnd::OnHScroll - 수평 스크롤 이벤트가 뷰에서 발생할 때 호출된다.
? afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
? Parameters
nSBCode - 발생하는 스크롤 행위와 타입
?SB_LEFT
왼쪽으로 스크롤
?SB_RIGHT
오른쪽으로 스크롤
?SB_ENDSCROLL
스크롤의 끝
?SB_LINELEFT
한 라인 왼쪽으로 스크롤
?SB_LINERIGHT
한 라인 오른쪽으로 스크롤
?SB_PAGELEFT
한 페이지 왼쪽으로 스크롤
?SB_PAGERIGHT
한 페이지 오른쪽으로 스크롤
?SB_THUMBPOSITION
절대 위치로 스크롤
?SB_THUMBTRACK
스크롤 박스를 지정 위치로 드래그한다.
nPos
?SB_THUMBPOSITION or SB_THUMBTRACK 코드에 대한 현재 스크롤바 위치.
그렇지 않으면 사용되지 않는다.
pScrollBar
?알림 코드를 보내는 스크롤바 컨트롤. 이 파라미터는 스크롤바가 뷰에 속해 있으면
NULL이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 4

1
7

CHAPTER 4
? CScrollView::SetScrollSizes
? void SetScrollSizes
( int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDefault,
const SIZE& sizeLine = sizeDefault );
? Parameters
?sizeTotal

스크롤 뷰의 전체 크기

?sizePage

스크롤바 페이지를 나타내는 장치단위의 크기.
스크롤바 페이지는 사용자가 스크롤바 트랙 범위 내를
클릭할 때 이동된 거리이다.

?sizeLine 스크롤바 라인을 나타내는 장치단위의 크기.
스크롤바 라인은 사용자가 스크롤바 트랙 범위 내를 클릭할 때
이동된 거리이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?nMapMode 현재 뷰의 맵핑 모드를 설정한다.

1
7

CHAPTER 4
? OnInitialUpdate() 함수
? 뷰 윈도우가 완전히 생성된 후, OnDraw() 함수를 호출하기 직전에
프레임워크에 의해 첫번째로 호출되는 함수.
? 키보드 입력 받아들이기

? WM_CREATE 메시지
? 이 메시지는 윈도우가 뷰에 보내는 첫번째 메시지이다. 윈도우의 Create() 함
수가 호출되면 윈도우의 생성이 끝난 것이 아니므로, OnCreate() 함수내에서
는 윈도우 함수를 호출할 수 없다. 따라서 윈도우의 생성 후 초기화에 대한
함수는 OnInitialUpdate() 함수를 재정의(Override) 해서 사용해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 키보드를 누르게 되면, 윈도우는 가상 키 코드와 함께 WM_KEYDOWN과
WM_KEYUP 메시지를 해당 윈도우에 보낸다.
윈도우에 이 메시지가 도착하기 전에, ANSI 문자세트가 눌려진 경우, 이 메
시지는 Shift 키가 눌려진 상태를 검사하여 WM_CHAR로 변환하게 된다.
커서키와 펑션키와 같은 키들은 코드값이 없으므로 변환되지 않는다. 이때
발생된 메시지들은 WM_KEYDOWN과 WM_KEYUP 메시지 만을 갖는다.

1
7

CHAPTER 4
? WM_CLOSE 메시지
? 사용자가 시스템메뉴에서 [닫기]를 선택하거나, 부모 윈도우가 닫히게 되면
윈도우는 WM_CLOSE 메시지를 보내게 된다. 사용자는 OnClose() 함수를
재정의하여 윈도우를 받을 때 사용자에게 파일을 저장할 것인지 묻는 작업을
만들 수 있다. (OnClose() 에 처리하는 이와 같은 작업을
CDocument::SaveModified() 함수를 재정의하여 대신 사용할 수 있다.)

? WM_DESTROY 메시지
? 윈도우는 WM_CLOSE 메시지 후에 이 메시지를 보내고, OnDestroy() 함수가
호출된다. OnDestroy() 함수 내에서는 닫는 작업을 취소할 수 없다.
함수 내부에서 반드시 Base class 의 OnDestroy() 함수를 호출하도록 한다.
? WM_NCDESTROY 메시지
? 이 메시지는 윈도우가 파괴되고 난 후 최종적으로 받게 되는 메시지이고
OnNcDestroy() 함수가 호출된다. 함수 내부에서 반드시 Base class 의
OnNcDestroy() 를 호출하도록 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? WM_QUERYENDSESSION 메시지
? 윈도우 95를 종료하게 될 때 실행중인 모든 어플리케이션에
WM_QUERYENDSESSION 메시지를 보낸다. WM_CLOSE 메시지 핸들러를
기술했다면, WM_QUERYENDSESSION 메시지 핸들러를 추가해야 한다.

1
7

CHAPTER 4
? 키보드 처리
? 윈도우 시스템은 입력 포커스를 막 잃어버리거나 갖게 되는 윈도우에 대해
WM_KILLFOCUS와 WM_SETFOCUS 메시지들을 보내게 된다.
? MFC는 이들 메시지를 미리 정의된 메시지 핸들러인 CWnd::OnSetFocus(),
CWnd::OnKillFocus() 로 싸고 있다.
? 윈도우의 자식 컨트롤이 포커스를 얻게 되면, 이의 부모 윈도우에 대한
키보드 메시지들이 중단되며, 자식 컨트롤이 그 대신 메시지들을 얻게 된다.
? 어느 윈도우가 현재 포커스를 갖고 있는지 찾기 위해서는 CWnd::GetFocus()
(C) 1998 Sang Il Kim

메소드나 Win32 API 함수인 GetFocus() 를 호출하면 된다.

Visual C++ Programming

1
7

CHAPTER 4
? 키보드 메시지
? 윈도우 시스템은 입력 포커스를 갖고 있는 윈도우에게 사용자가 어떤 키들을 입력하고
있는지 알려 주기 위해 키보드 메시지들을 전송한다. 이들 메시지는 WM_KEYDOWN
과 WM_KEYUP이며, CWnd::OnKeyDown() 과 CWnd::OnKeyUp() 메시지 핸들러로
포장되어 있다.
? Alt키를 제외하고는 모든 키가 WM_KEYDOWN과 WM_KEYUP 메시지를 보낸다
? Alt키는 시스템 키로 WM_SYSKEYDOWN과 WM_SYSKEYUP 메시지를 보내는데,
MFC는 이를 CWnd::OnSysKeyDown()과 CWnd::OnSysKeyUp() 메시지 핸들러로
포장하고 있다.

? MFC가 키보드 메시지를 위해 정의한 메시지 핸들러의 프로토타입
afx_msg void OnMessageHandler (UINT nChar, UINT nRepCnt, UINT nFlags)
? nChar - 누르거나 손을 뗀 키
? nRepCnt - 반복 횟수(키의 입력 횟수), 시스템 키의 경우 - 값은 1
다른 키의 경우 - 값은 0
? nFlags - 스캔 코드와 키 전이 코드, 이전 키 상태, 키에 대한 컨텍스트 코드
Visual C++ Programming

(C) 1998 Sang Il Kim

? 사용자가 Alt키를 누른 상태에서 다른 키를 누르게 되도 MFC는 CWnd::SysKeyDown()
핸들러 메소드를 호출한다.

1
7

CHAPTER 4
? MFC 키보드 메시지 핸들러의 nFlags 매개 변수에서 사용한 비트
의미

0-7

스캔 코드 : 키보드에서 발생한 8비트의 OEM 스캔 코드 값

8

확장 키 : 기능 키나 숫자 키패드에 있는 키와 같은 확장 키를 나타낸다.
1이면 확장 키, 0이면 일반 키

9-10

예약된 부분 : 사용하지 않음

11-12

예약된 부분 : 윈도우 시스템이 내부적으로 사용

13

컨텍스트 코드 : 키를 눌렀을 때 Alt키를 눌렀는지를 나타낸다.
Alt키를 눌렀으면 1, 그렇지 않으면 0

14

이전 상태 : 키의 이전 상태를 나타낸다.
이전에 누른 상태였으면 1, 누르지 않은 상태였으면 0

15

전이 상태 : 키의 전이 상태를 나타낸다.
키를 누르고 있는 상태면 0, 원상 복구하고 있는 상태면 1

(C) 1998 Sang Il Kim

비트 값

Visual C++ Programming

1
7

CHAPTER 4
? MFC 키보드 메시지 핸들러에서 nFlags의 확장 키 비트에 의해 나타난 확장 키

위치

Alt

키보드의 오른쪽

화살표 키

숫자 키 패드와 주 키보드 키 사이

Ctrl

키보드의 오른쪽

Delete

한 곳에만 있음

End

한 곳에만 있음

Enter

두 개의 Enter 키

슬래시(/)

한 곳에만 있음
(C) 1998 Sang Il Kim

Home,
Insert
PageDown,
PageUp

한 곳에만 있음
양쪽의 / 키
Visual C++ Programming

1
7

CHAPTER 4
? 가상 키 코드
? 대부분의 응용 프로그램이 확장 키 비트를 무시하고, 그 대신 가상 키 코드를
사용하고 있다.
? 윈도우 시스템이 자동으로 올바른 가상 키 코드를 결정하기 때문에 키들은
항상 올바른 스캔 코드 값과 일치하게 된다.

가상 키 코드

키보드의 키

VK_0 ~ VK_9

키보드 맨 위에 있는 0~9까지의 키

VK_A ~ VK_Z

A~Z까지의 키

VK_ADD

숫자 키패드의 + 키

VK_BACK

백 스페이스 키

VK_CANCEL

Ctrl + Break 조합

(C) 1998 Sang Il Kim

? 윈도우가 키보드 입력을 위해 사용하는 가상 키 코드

Visual C++ Programming

1
8

CHAPTER 4
? 윈도우가 키보드 입력을 위해 사용하는 가상 키 코드
키보드의 키

VK_CAPITAL

CapsLock 키

VK_CLEAR

Clear 키 (NumLock이 꺼져 있을 때의 숫자 키패드의 5번 키)

VK_CONTROL

Ctrl 키

VK_DECIMAL

숫자 키패드의 . 키

VK_DELETE

Delete 키

VK_DIVIDE

숫자 키패드의 / 키

VK_DOWN

아래 화살표 키

VK_END

End 키

VK_ESCAPE

Esc 키

(C) 1998 Sang Il Kim

가상 키 코드

VK_F1~VK_F12 F1 ~ F12까지의 기능 키
Visual C++ Programming

1
8

CHAPTER 4

가상 키 코드

키보드의 키

VK_HOME

Home 키

VK_INSERT

Insert 키

VK_LEFT

왼쪽 화살표 키

VK_MENU

Alt 키

VK_MULTIPLY

숫자 키패드의 * 키

VK_NEXT

Page Down과 PgDn 키

VK_NUMLOCK

NumLock 키

VK_NUMPAD0
~ VK_NUMPAD9

숫자 키패드의 0 ~ 9까지의 키

VK_PAUSE

Pause 키

(C) 1998 Sang Il Kim

? 윈도우가 키보드 입력을 위해 사용하는 가상 키 코드

Visual C++ Programming

1
8

CHAPTER 4
가상 키 코드

키보드의 키

VK_PRIOR

Page Up과 PgUp 키

VK_RETURN

엔터 키

VK_RIGHT

오른쪽 화살표 키

VK_SCROLL

Scroll Lock 키

VK_SHIFT

Shift 키

VK_SNAPSHOT

Print Screen 키

VK_SPACE

스페이스 바

VK_SUBTRACT

숫자 키패드이 - 키

VK_TAB

탭키

VK_UP

위 화살표 키

(C) 1998 Sang Il Kim

? 윈도우가 키보드 입력을 위해 사용하는 가상 키 코드

Visual C++ Programming

1
8

CHAPTER 4
? 상태 변경 키와 토글 키의 상태를 감지
? 상태 변경 키 - Alt, Ctrl, Shift
? 토글 키 - CapsLock, Num Lock
? Win32 API 함수 GetKeyState() 를 사용 - 현재의 키의 상태를 나타내는
BOOL 값을 반환한다.
? 모든 가상 키의 상태를 한번에 알 필요가 있을 경우에는 Win32 API 함수인
GetKeyboardState() 를 호출하면 된다.
? BOOL bAltPressed = ::GetKeyState(VK_MENU);
? BOOL bCapsLockOn = ::GetKeyState(VK_CAPITAL) & 0x01;
16진수 값 0x01을 비트 단위 AND 연산자(&)에 적용하여 밑의 부분의
비트를 추출하면 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

Alt키를 눌렀는지의 여부를 결정하는 역할을 한다.

1
8

CHAPTER 4
? 문자 메시지
? 키보드 배치가 각 나라의 모국어의 특성에 따라 나라마다 다르기 때문에 코드
페이지와 문자 집합도 달라지게 된다.
? WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP
메시지를 사용할 때 문제가 발생하게 된다.
? 윈도우는 Win32 API 함수 TranslateMessage() 를 호출하여 이들 네 개의
메시지를 WM_CHAR와 WM_SYSCHAR 메시지로 변환할 수 있도록 한다.
? WM_CHAR 처리하기
? ON_WM_CHAR() 메시지 맵 항목과 함께 사용해야 한다.
같으나 nChar 문자는 OEM이 아닌 ANSI 문자이다.
? afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags);
? 변환된 WM_CHAR 메시지는 항상 앞의 WM_KEYDOWN 메시지와
뒤의 WM_KEYUP 메시지 사이에 끼게 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? OnChar() 메소드 프로토타입과 인수들은 OnKeyDown()과 OnKeyUp() 과

1
8

CHAPTER 4
? 윈도우에서 키보드 입력의 흐름
물리적
물리적 키보드
키보드
스캔 코드
윈도우
윈도우 95와
95와
키보드
키보드 드라이버
드라이버

논리적 키보드

WM_KEYDOWN
WM_KEYDOWN
메시지
메시지

(C) 1998 Sang Il Kim

WM_CHAR
WM_CHAR
메시지
메시지
WM_KEYUP
WM_KEYUP
메시지
메시지
Visual C++ Programming

1
8

CHAPTER 4
? 키보드 핸들러
void CMainWnd::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString msg = “WM_CHAR”; // 글자를 그림
ShowKeyInfo(msg, nChar, nRepCnt, nFlags);
CFrameWnd::OnChar(nChar, nRepCnt, nFlags); // 상속한 핸들러를 호출

(C) 1998 Sang Il Kim

}

Visual C++ Programming

1
8

의식과 운명
의식이
사고가
행동이
습관이
인격이

바뀌면
바뀌면
바뀌면
바뀌면
바뀌면

사고가
행동이
습관이
인격이
운명이

바뀐다.
바뀐다.
바뀐다.
바뀐다.
바뀐다.
(C) 1998 Sang Il Kim

-윌리암 제임스-

Visual C++ Programming

1
8

CHAPTER 5

(C) 1998 Sang Il Kim

그래픽 디바이스
인터페이스(GDI)
색상, 폰트

Visual C++ Programming

1
8

CHAPTER 5
? 디바이스 컨텍스트(Device Context)
? 디바이스 컨텍스트란?
?물리적 장치(모니터, 프린터… )의 그리기 속성에 관한 정보를 가지고 있는
윈도우 자료구조체. - (물리적 장치의 논리적 버전)
?논리적 장치의 예
- 메타파일 (장치와 독립적인 포맷으로 그림을 저장한 구조를 모아놓은 것)
? Win32 API에서 제공하는 Device Context
?화면 컨텍스트 - 비디오 화면에서 그래픽 동작을 지원한다.
?정보 컨텍스트 - 장치 데이터의 검색을 제공한다.
?프린터 컨텍스트 - 프린터나 플로터에서 그래픽 동작을 지원한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?메모리 컨텍스트 - 비트맵에서 그래픽 동작을 지원한다.

1
9

CHAPTER 5
? GDI (Graphic Device Interface)
? DC는 장치를 나타내며, 응용 프로그램이 하드웨어에 직접 그리지 않아도 되도록 하는
추상 층을 제공하는 역할을 한다.

? GDI는 윈도우 그래픽 함수 호출에 대응하여 적절한 장치 드라이버를 호출함으로써
이와 같은 추상 계층을 제공한다.
응용
응용 프로그램
프로그램

MFC
MFC Device
Device Context
Context 클래스
클래스

◐ 하드웨어와 MFC 응용 프로그램

GDI
GDI

장치
장치 드라이버
드라이버

물리적
물리적 하드웨어
하드웨어
Visual C++ Programming

(C) 1998 Sang Il Kim

사이의 추상 계층들

1
9

CHAPTER 5
? 디바이스 컨텍스트(Device Context) 클래스
? 윈도우에서 수행된 모든 그리기 작업은 장치 컨텍스트에 대해 이루어진다.
? C++ GDI 객체는 HDC 타입의 핸들로 정의되는 윈도우 디바이스 컨텍스트를
가지고 있다.
? 많은 디바이스 컨텍스트 클래스는 CDC 에서 파생된다.
클래스의 계층

CObject
CObject
CDC
CDC
CPaintDC
CPaintDC
CClientDC
CClientDC

(C) 1998 Sang Il Kim

◐ MFC 장치 컨텍스트

CWindowDC
CWindowDC
CMetaFileDC
CMetaFileDC
Visual C++ Programming

1
9

CHAPTER 5
? 디바이스 컨텍스트 (Device Context) 클래스
? DevStudio\Vc\mfc\include\<Afxwin.h>
클래스 이름

설명

윈도우 디바이스 컨텍스트를 캡슐화한다. (605라인)
윈도우의 사용자 영역에 대한 디바이스 컨텍스트를 캡슐화한다. (1032라인)
WM_PAINT 메시지에 응답하여 BeginPaint 와 EndPaint 함수를
캡슐화하는 것을 제외하고는 CDC와 동일하다. (1069라인)
CWindowDC 윈도우의 전체 영역에 대한 디바이스 컨텍스트를 캡슐화한다. (1053라인)
CMetaFileDC 메타파일에 대해 디바이스 컨텍스트를 캡슐화한다.

? 디스플레이 컨텍스트 클래스 - CClientDC와 CWindowDC
? 윈도우의 클라이언트 영역은 경계선, 캡션바, 메뉴바 등을 제외한 영역이다.
? CClientDC 객체를 만들게 되면 이 클라이언트 영역의 좌상단이(0, 0) 좌표에
해당하게 된다.
? 뷰 윈도우는 프레임윈도우의 차일드 윈도우이다.
? CWindowDC 는 윈도우 비클라이언트 영역의 좌상단이 (0, 0) 좌표가 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CDC
CClientDC
CPaintDC

1
9

CHAPTER 5
? 기반 클래스 - CDC
? 장치 컨텍스트 객체를 정의한다.
? 화면, 프린터, 창의 클라이언트 영역에 그릴 수 있는 메소드들을 제공한다.
? 모든 그래픽 출력은 CDC가 제공하는 클래스 메소드들을 사용해야 한다.
◐ CDC 객체의 클래스 멤버
클래스 멤버

설명

m_hDC

CDC 객체에 대한 출력 장치 컨텍스트.
출력을 만드는 대부분의 CDC GDI 호출은 이 멤버 DC를 사용한다.

CDC 객체에 대한 특성 장치 컨텍스트.
m_hAttribDC CDC객체로부터의 정보를 요청하는 대부분의 CDC GDI 호출은
이 멤버 DC를 사용한다.
(C) 1998 Sang Il Kim

? DC 설정
?CDC::SetAttribDC() - m_hAttribDC(특성 장치 컨텍스트)를 설정
?CDC::SetOutputDC() - m_hDC(출력 장치 컨텍스트)를 설정
? DC 해제
?CDC::ReleaseAttribDC() - m_hAttribDC를 반납
?CDC::ReleaseOutputDC() - m_hDC를 반납
Visual C++ Programming

1
9

CHAPTER 5
? CDC 객체를 만들고 사용하기
? 생성자인 CDC::CDC() 를 호출해야 한다.
? 세 가지 초기화 메소드 중의 하나를 호출해야 한다.
◐ CDC 객체의 초기화 메소드
초기화 메소드

설명

CreateDC()

프린터와 같은 특정 장치에 대한 장치 컨텍스트를 만든다.

특정 장치에 대한 정보 컨텍스트를 생성한다.

기존의 장치 컨텍스트와 호환성이 있는 새로운 메모리 장치
CreateCompatibleDC() 컨텍스트를 만든다.
메모리 내에 그래픽 이미지를 준비하고자 할 때 보통 사용한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

CreateIC()

장치 컨텍스트를 만들지 않고 장치 정보에 액세스하기 위해

1
9

? CDC::CreateDC()
? 특정 장치에 대한 장치 컨텍스트를 만든다.
? DC가 생성되면 TRUE를 반환, 생성되지 않으면 FALSE를 반환
? virtual BOOL CreateDC( LPCTSTR lpszDriverName,
LPCTSTR lpszDeviceName,
LPCTSTR lpszOutput, const void* lpInitData );
? CDC::CreateIC()
? 특정 장치에 대한 정보 컨텍스트를 만든다.
? IC가 생성되면 TRUE를 반환, 생성되지 않으면 FALSE를 반환
? virtual BOOL CreateIC( LPCTSTR lpszDriverName,
LPCTSTR lpszDeviceName,
LPCTSTR lpszOutput, const void* lpInitData );
? CDC::CreateCompatibleDC()
? virtual BOOL CreateCompatibleDC( CDC* pDC );
? pDC 매개 변수로 주어진 DC와 호환성이 있는 메모리 DC를 만든다.
? 매개 변수가 NULL인 경우에는 전체 비디오 화면과 호환성이 있는
메모리DC가 만들어진다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 5

1
9

CHAPTER 5
? CreateDC()와 CreateIC() 메소드에 대한 매개변수
매개 변수

의미

확장자 없이 장치 드라이버의 파일 이름을 나타내는 CString이거나
lpszDriverName NULL로 끝나는 문자열에 대한 포인터이다.
예) “EPSON”

lpszOutput

물리적 파일이나 출력 포트에 대한 파일 이름이나 장치 이름을
나타내는 CString이거나 NULL로 끝나는 문자열에 대한 포인터이다.

lpInitData

장치 드라이버에 대한 장치 관련 초기화 데이터를 담고 있는
DEVMODE 구조에 대한 포인터이다.

? DEVMODE 구조를 사용하기 위해서는 PRINT.H 파일을 포함해야 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

지원할 특정 장치의 이름을 나타내는(보통은 프린터) CString이거나
NULL로 끝나는 문자열에 대한 포인터이다. 드라이버가 하나
lpszDeviceName
이상의 장치를 지원할 경우에 이 매개 변수를 사용한다.
예) “EPSON FX-80”

1
9

CHAPTER 5

? 디바이스 컨텍스트 객체를 소멸하고, 윈도우 디바이스 컨텍스트를 해제하는 방법은
스택상에 객체를 생성하는 것이다.
Void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
CClientDC dc(this);
// 스택상에 dc를 만든다.
dc.GetClipBox(rect); // 클리핑 사각형을 얻는다.
}
// dc가 자동 해제된다.
? CDC::GetDC 를 사용하여 디바이스 컨텍스트를 얻을 수도 있다. GetDC 를 사용하였을
경우에는 반드시 ReleaseDC 를 수행해야 된다.
Void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
클리핑(Clipping) 영역 :
CDC* pDC = GetDC();
// dc 포인터
pDC -> GetClipBox(rect); // 클리핑 사각형을 얻는다. 윈도우가 그래픽
출력을 허용하는 영역
ReleaseDC(pDC);
// 반드시 호출해야 한다.
}
? CDC 객체 포인터는 어플리케이션 프레임워크가 소멸시켜 주기 때문에 자신이 직접
소멸시키면 안된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CDC 객체의 생성과 소멸
? 윈도우에서는 가능한 디바이스 컨텍스트를 제한하기 때문에, CDC 객체를 생성한 후,
객체의 사용이 모두 끝나면 반드시 해당 객체를 소멸해야 한다.

1
9

CHAPTER 5
? CPaintDC
? CPaintDC 객체는 창에 대한 그리기 표면을 나타낸다.
? BeginPaint()
?칠할 특정 창을 준비하며, PAINTSTRUCT란 특수 구조를 칠할 정보로 채운다.
?화면 장치 컨텍스트에 대한 핸들을 반환한다.
? EndPaint() - 특정 창의 칠하는 작업이 끝났음을 알린다.
? CPaintDC 객체를 사용할 때 따라야 할 기본 단계
1. CPaintDC 객체를 만든다.
2. CPaintDC 객체에 그린다.
3. CPaintDC 객체를 제거한다.
? CPaintDC 소멸자는 EndPaint() 함수를 호출한다.
? 스택에 디바이스 컨텍스트를 만든 경우 EndPaint() 함수는 자동으로 호출된다.
? View 클래스는 CView::OnDraw() 메소드의 매개 변수로 CPaintDC 객체를 받는다
Visual C++ Programming

(C) 1998 Sang Il Kim

? CPaintDC 생성자는 BeginPaint() 함수를 호출한다.

1
9

CHAPTER 5
? CPaintDC
? OnPaint() 메시지 핸들러에서 WM_PAINT
메시지에 대한 반응으로 타원 그리기
void CMainWnd::OnPaint()
{
// 칠하기 DC 만들기
CPaintDC dc(this);

hDC = BeginPaint (hWnd, &paintstruct);
// hDC를 사용하여 그래픽 동작을 실행
EndPaint (hWnd, &paintstruct);
}

return 0;
}

// DC에서 타원 그리기
CRect rc;
GetClientRect(&rc);
dc.Ellipse(rc);

? 디폴트 OnPaint는 적절한 디바이스 컨텍스트를 가지고 OnDraw를 호출하지만, 사용자가
특정한 디스플레이를 필요로 할 경우 OnPaint에서 PaintDC의 객체를 만들어 사용한다.
void CMyView::OnPaint()
{
CPaintDC dc(this);
OnPrepareDC(&dc);
dc.TextOut(0, 0, “for the display. Not the printer”);
OnDraw(&dc);
// 화면과 프린터에 공통되는 코드
}

Visual C++ Programming

(C) 1998 Sang Il Kim

? CPaintDC
? 윈도우 프로시저에서의 C 코드
switch (msg)
{
case WM_PAINT:
HDC
hDC;
PAINTSTRUCT paintstruct;

2
0

CHAPTER 5
? CClientDC
? 클라이언트 영역이나 창을 나타내는 장치 컨텍스트를 호출하고 제거한다.
? Win32 API 함수 GetDC()
?CClientDC 생성자로 부터 호출된다.
? Win32 API 함수 ReleaseDC()
?CClientDC 소멸자로 부터 호출된다.
? CClientDC 객체는 DC가 제어하는 클라이언트 영역을 포함하는 윈도우의
핸들을 멤버 변수 m_hWnd에 저장한다.

? CClientDC::CClientDC
// #include <afxwin.h>
? CClientDC ( CWnd* pWnd );
? Parameters
?pWnd 디바이스 컨텍스트가 생성되는 CWnd 객체에 대한 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

? CClientDC 객체를 생성하기 위해서 CWnd 객체를 매개변수로 생성자에
전달한다.

2
0

CHAPTER 5
? CClientDC
? OnLButtonDown() 메시지 핸들러의 WM_LBUTTONDOWN 메시지에
반응하여 CClientDC 객체를 이용한 다이아몬드 그리기
void MainWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CClientDC dc(this); // 그림을 그릴 ClientDC를 생성

(C) 1998 Sang Il Kim

}

// DC에 다이아몬드를 그린다.
CRect rc;
GetClientRect(&rc);
dc.MoveTo (0, (rc.bottom + rc.top) / 2);
dc.LineTo ((rc.right + rc.left) / 2, 0);
dc.LineTo (rc.right, (rc.bottom + rc.top) / 2);
dc.LineTo ((rc.right + rc.left) / 2, rc.bottom);
dc.LineTo (0, (rc.bottom + rc.top) / 2);

Visual C++ Programming

2
0

CHAPTER 5
? CWindowDC
? 클라이언트 영역과 비클라이언트 영역을 모두 포함한 전체 윈도우 표면을
나타내는 장치 컨텍스트를 호출하고 제거한다.
? Win32 API 함수 GetDC()
?CWindowDC 생성자로 부터 호출된다.
? Win32 API 함수 ReleaseDC()
?CWindowDC 소멸자로 부터 호출된다.
? CWindowDC 객체는 DC가 나타내는 윈도우 영역의 핸들을 멤버 변수
m_hWnd에 저장한다.

? CWindowDC::CWindowDC
// #include <afxwin.h>
? CWindowDC ( CWnd* pWnd );
? Parameters
?pWnd
디바이스 컨텍스트가 생성되는 CWnd 객체에 대한 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWindowDC 객체를 생성하기 위해서 CWnd 객체를 매개변수로 생성자에
전달한다.

2
0

CHAPTER 5
? CWindowDC
? OnRButtonDown() 메시지 핸들러의 WM_RBUTTONDOWN 메시지에 반응하여
CWindowDC 객체를 이용한 연속된 원 그리기

void MainWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
CWindowDC dc(this); // 그림을 그릴 WindowDC를 생성
CRect rc;
// 윈도우의 제목 표시줄에서, DC에 연속적으로 이어진 원을 그림
GetWindowRect(&rc);
// 윈도우 제목 표시줄의 높이를 결정
int cyCaption = GetSystemMetrics (SM_CYCAPTION);
// 원을 채워 넣을 사각형을 정의
CRect rcEllipse (0, 0, cyCaption, cyCaption);
// 원을 그림
(C) 1998 Sang Il Kim

}

while (rcEllipse.right < rc.right);
{
dc.Ellipse(rcEllipse);
rcEllipse.left += cyCaption;
rcEllipse.right += cyCaption;
}

Visual C++ Programming

2
0

CHAPTER 5
? CMetaFileDC

? CMetaFileDC::Create
? BOOL Create( LPCTSTR lpszFilename = NULL );
? Parameters
?lpszFilename NULL로 끝나는 문자열에 대한 포인터.
생성할 메타파일이 존재한다면, 그 파일명을 지정하는 NULL
값의 문자열을 가리킨다.
미리 지정된 파일명이 없다면, 메소드는 새로운 메타파일을
메모리 안에 생성한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? GDI 함수 호출을 기록하고 재작동하는 데 사용한다.
? 윈도우 메타파일 생성
1. CMetaFileDC 객체를 만든다.
2. CMetaFileDC::Create() 메소드를 호출한다.
3. CMetaFileDC 객체를 초기화한다.

2
0

CHAPTER 5
? 그래픽(GDI) 객체 (DevStudio\Vc\mfc\include\<Afxwin.h>
?CBitmap
?CBrush
?CFont
?CPalette
?CPen
?CRgn

481라인
브러시는 색칠할 때 사용되는 픽셀의 비트맵 패턴을 정의한다. (418라인)
451라인
색상을 맵핑하기 위한 인터페이스 (522라인)
선이나 경계선을 그리기 위해 사용되는 도구 (382라인)
영역(Region)은 다각형과 타원의 결합된 지역 (556라인)

SDK 그리기 도구

MFC 클래스

윈도우 데이터 유형

Bitmap

CBitmap

hBitmap

Brush

CBrush

hBrush

Font

CFont

hFont

Palette

CPalette

hPalette

Pen

CPen

hPen

Rgn

CRgn

hRgn

(C) 1998 Sang Il Kim

? SDK 그리기 도구의 데이터 유형과 MFC 그래픽 객체 클래스와의 관계

Visual C++ Programming

2
0

CHAPTER 5

CObject
CObject
CGdiObject
CGdiObject

◐ MFC 클래스 계층 구조에서
각 그래픽 객체들의 위치

CPen
CPen
CBrush
CBrush
CFont
CFont
CBitmap
CBitmap
CPalette
CPalette

? 스택에 선언된 그래픽 객체는 객체가 그 범위를 벗어나게 되면 자동으로
삭제된다.
? 포인터로 선언되고 새로운 연산자들을 할당 받은 그래픽 객체들은 DC를
이전 상태로 되돌릴 때에는 반드시 제거해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CRgn
CRgn

2
0

CHAPTER 5
? GDI 객체의 생성과 소멸
? 1단계 생성 : 생성자와 함께 객체를 생성하고, 초기화시킨다
(CPen 이나 CBrush 와 같은 클래스들)
? 2단계 생성 : 생성자는 객체를 생성하고, 함수를 사용하여 초기화시킨다.
(CFont 나 CRgn 과 같은 클래스들)
? void CMyView::OnDraw(CDC* pDC)
{
CPen myPen1(PS_DOT, 5, RGB(0, 0, 0));

// 1단계 생성

CPen myPen2;

// 2단계 생성

if(myPen2.CreatePen(PS_DOT, 5, RGB(0, 0, 0)))
// 여기에서 펜을 사용한다.
? GDI 객체 추적(Tracking)
? 객체를 추적하는 방법
?원래의 GDI 객체를 보관해 놓고, 새로운 GDI 객체를 선택한 다음, 작업이
완료되었을 때 보관해 놓은 원래의 객체를 복구 시킨다.
Visual C++ Programming

(C) 1998 Sang Il Kim

}

2
0

CHAPTER 5
? GDI 객체 추적(Tracking)
void CMyView::OnDraw(CDC* pDC)
{
CPen newPen (PS_DASHDOTDOT, 2, (COLORREF) 0); // 폭이 2픽셀인
검정펜을 작성한다
CPen* pOldPen = pDC -> SelectObject(&newPen); // 펜을 선택한다
pDC -> MoveTo(10, 10);
// 선을 그린다
pDC -> LineTo(110, 10);
pDC -> SelectObject(pOldpen); // newPen 이 선택 해제된다.(선택을 종료한다)
} // newPen 이 자동 소멸된다.

? 윈도우는 많은 stock GDI 객체를 가지고 있다. 이러한 객체는 윈도우의
부분이기 때문에 객체를 제거할 필요가 없다.
Stock GDI 객체를 선택함으로써 사용자가 만들어 놓은 GDI 객체의 선택을
제거할 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 내장(stock) GDI 객체

2
0

CHAPTER 5
? GDI 선택의 존속기간
? 어떠한 GDI 선택도 함수가 끝나고 난 후에는 유효하지 않으므로 디스플레이
디바이스 컨텍스트에 있어서는, 각 함수의 시작부분에서 새로운 디바이스 컨
텍스트를 얻어야 한다.
프린터나 메모리 버퍼와 같은 디바이스 컨텍스트에서는 윈도우 핸들을 보관
함으로써 존속기간을 지속시킬 수 있다.
? 표준 VGA 카드는 4비트 컬러코드를 사용하며, 동시에 16가지 색상만을
사용할 수 있다.
? 윈도우의 색상은 각각 8비트의 RGB 값으로 표현된다.
? 색상을 사용하는 GDI 함수는 32bit COLORREF 인자를 받는다.
(RGB 매크로를 사용하여 COLORREF 자료형으로 변환)
? 브러시에서는 디러링(dithering)된 색상을 사용할 수 있다.
CBrush brush (RGB(128, 128, 192));
? SetBkColor나 SetTextcolor 함수는 항상 디러링(dithering)된 색상을
사용할 수 없다.(근접한 순수색상이 표시된다.)
Visual C++ Programming

(C) 1998 Sang Il Kim

? 윈도우의 컬러 맵핑(Color Mapping)

2
1

RGB
? windows.h 파일에 정의
? COLORREF RGB( // COLORREF : 데이터 type
BYTE bRed,
// red component of color
BYTE bGreen, // green component of color
BYTE bBlue
// blue component of color
);
? RGB 매크로 정의
? #define RGB (r, g, b) ((DWORD) (((BYTE) (r) | \
((WORD) (g) << 8)) | (((DWORD) (BYTE) (b)) << 16)))
? 윈도우는 색상을 표현하기 위해 4byte를 사용

Zero Blue 0~255 Green 0~255 Red 0~255
1byte

3byte 색상표현

일반적으로 사용하지 않는다. (윈도우 RGB 칼라와 16칼라 이상을
지원하는 비디오 디바이스에 대한 칼라 팔레트를 구분하기 위해 사용)
? RGB 매크로로 표현할 수 있는 색상
? 256*256*256 = 16,777,216 color
Visual C++ Programming

(C) 1998 Sang Il Kim

?

2
11

Red
0
0
0
0
255
255
255
255
0
0
0
128
128
128
128
192

Green

Blue

Color

0
0
255
255
0
0
255
255
0
128
128
0
0
128
128
192

0
255
0
255
0
255
0
255
128
0
128
0
128
0
128
192

Black
Blue
Green
Cyan
Red
Magenta
Yellow
White
Dark blue
Dark green
Dark cyan
Dark red
Dark magenta
Dark yellow
Dark gray
Light gray

(C) 1998 Sang Il Kim

RGB

Visual C++ Programming

2
1

CHAPTER 5
? CPen 클래스

메소드

설명

CreatePen()

특정 유형, 너비, 붓, 속성을 지닌 논리적인 펜을 생성하며,
이것을 CPen 객체에 붙인다.

CreatePenIndirect()

LOGPEN 구조에서 유형, 너비, 색상이 정의된 펜을 생성하고,
이것을 CPen 객체에 붙인다.

FromHandle()

윈도우 HPEN으로부터 CPen 객체로 포인터를 반환한다.

GetExtLogPen()

펜의 기본적인 EXTLOGPEN 구조를 받는다.

GetLogPen()

펜의 기본적인 LOGPEN 구조를 받는다.

연산자 HPEN

현재 CPen 객체에 첨부되어 있는 윈도우 펜의 핸들을 반환한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CPen 객체는 윈도우 GDI 펜을 캡슐화하고 있다.

2
1

CHAPTER 5
? CPen::CreatePen
? BOOL CreatePen ( int nPenStyle, int nWidth, COLORREF crColor );
? BOOL CreatePen ( int nPenStyle, int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0, const DWORD* lpStyle = NULL );
? Parameters
펜의 스타일
펜의 두께
펜에 대한 RGB 색상
LOGBRUSH 구조체에 대한 포인터

?nStyleCount lpStyle 파라미터에 의해 가리키는 스타일의 길이를 기술한다.
?lpStyle
doubleword 값의 배열을 가리킨다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?nPenStyle
?nWidth
?crColor
?pLogBrush

2
1

CHAPTER 5
? 펜의 스타일 (DevStudio\Vc\include\<Wingdi.h> 1389라인)
?PS_SOLID

실선

?PS_DASH

긴 파선. 펜의 폭이 1일 때만 유효.

?PS_DOT

짧은 파선. 펜의 폭이 1일 때만 유효.

?PS_DASHDOT

1점 쇄선. 펜의 폭이 1일 때만 유효.

?PS_DASHDOTDOT

2점 쇄선. 펜의 폭이 1일 때만 유효.

?PS_NULL

투명

?PS_INSIDEFRAME 실선. 프레임이나 바운딩 사각형(Rectangle, Ellipse)을
?PS_USERSTYLE

사용자에 의해 제공되는 스타일 배열을 사용하는 펜

?PS_ALTERNATE

모든 다른 픽셀을 설정하는 펜

Visual C++ Programming

(C) 1998 Sang Il Kim

포함하는 객체에 대해 프레임내에 그리는 펜을 생성한다.

2
1

CHAPTER 5
? 사용자 정의 빨간 대시 펜을 이용한 OnLButtonDown()

? void CMainWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CClientDC dc(this); // 그림을 그릴 CClientDC를 생성
CPen penRed;
// 빨간 대시를 그릴 펜을 생성
penRed.CreatePen(PS_DASH, 1, RGB(255, 0, 0));
// 장치 컨텍스트에서 새로운 펜을 지정하고, 이전에 존재하던 복구할 펜을 저장 후 제거

CPen* ppenOld;
ppenOld = dc.SelectObject(&penRed);

dc.MoveTo (0, (rc.bottom + rc.top) / 2);
dc.LineTo ((rc.right + rc.left) / 2, 0);
dc.LineTo (rc.right, (rc.bottom + rc.top) / 2);
dc.LineTo ((rc.right + rc.left) / 2, rc.bottom);
dc.LineTo (0, (rc.bottom + rc.top) / 2);
}

dc.SelectObject(ppenOld);

// 처음의 상태대로 복구 (현재 상태는 제거)
Visual C++ Programming

(C) 1998 Sang Il Kim

// DC에 다이아몬드를 그림
CRect rc;
GetClientRect(&rc);

2
1

CHAPTER 5
? CBrush 클래스
? CBrush 객체는 윈도우 GDI 붓을 캡슐화하고 있다.
메소드

설명

LOGBRUSH 구조에서 지정된 유형, 색상, 무늬를 지닌 붓을
생성하며, 이것을 CBrush 객체에 붙인다.
장치와 무관한 비트맵으로부터 지정된 무늬를 지닌 붓을
CreateDIBPatternBrush()
생성하며, 이것을 CBrush 객체에 붙인다.
특정 빗금 무늬와 색상을 가진 붓을 생성하며, 이것을 CBrush
CreateHatchBrush()
객체에 붙인다.
비트맵에 의해 지정된 무늬를 가진 붓을 생성하며, 이것을
CreatePatternBrush()
CBrush 객체에 붙인다.
CreateBrushIndirect()

CreateSolidBrush()

지정된 한가지 색상의 붓을 생성하며, 이것을 CBrush 객체에 붙인다.

FromHandle()

윈도우 HBRUSH로부터 CBrush 객체로 포인터를 반환한다.

GetLogBrush()

CBrush 객체로부터 기본적인 LOGBRUSH 구조를 받는다.

연산자 HBRUSH

CBrush 객체에 첨부되어 있는 윈도우 핸들을 반환한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CreateSysColorBrush() 기본 시스템 색상의 붓을 생성하며, 이것을 CBrush 객체에 붙인다.

2
1

CHAPTER 5
? CBrush의 Constructor
?CBrush();
?CBrush(COLORREF crColor);
// crColor - 붓의 색상
?CBrush(int nIndex, COLORREF crColor); // nIndex - 붓의 무늬(해칭 패턴)
?CBrush(CBitmap* pBitmap);
// pBitmap - 붓의 무늬로서 사용할 비트맵을 포함하는 CBrush 객체에 대한 포인터
? 해칭(Hatching) 패턴의 종류 (DevStudio\Vc\include\<Wingdi.h> 1380라인)
해칭 패턴

의미

HS_HORIZONTAL

수평 해치

HS_VERTICAL

수직 해치

HS_FDIAGONAL

45’로 위 방향
(왼쪽에서 오른쪽)의 해칭
45’로 아래방향
(왼쪽에서 오른쪽)의 해칭

HS_CROSS

수직과 수평 십자가의 해칭

HS_DIAGCROSS

45’로 된 십자가 해칭

(C) 1998 Sang Il Kim

HS_BDIAGONAL

모양

Visual C++ Programming

2
1

CHAPTER 5
? 사용자 정의 파란색 원을 메울 빗금 무늬를 그릴 수 있는 붓을 이용한 OnPaint()메소드
? void CMainWnd::OnPaint()
{
CPaintDC dc(this);
// 페인트 DC를 생성

// 파란색의 왼쪽에서 오른쪽 아래의 빗금 무늬 붓 생성
CBrush br (HS_BFDIGONAL, RGB(0, 0, 255));

// DC에 원 그리기
CRect rc;
GetClientRect(&rc);
dc.Ellipse(rc);

}

dc.SelectObject(pbrOld);

// 처음의 상태대로 복구 (현재 상태는 제거)
Visual C++ Programming

(C) 1998 Sang Il Kim

// 장치 컨텍스트에서 새로운 붓을 선택하고,
// 이전에 존재하던 복구할 붓을 저장 후 제거
CBrush* pbrOld;
pbrOld = dc.SelectObject(&br);

2
1

CHAPTER 5
? CFont 클래스

? CFont 객체는 윈도우 GDI 글꼴을 캡슐화하고 있다.
? 글꼴을 생성하는 것은 장치 컨텍스트에서 텍스트를 그리기 위해서이다.

메소드

설명

CreateFont()

지정된 속성을 가진 CFont 객체 생성

CreatePointFont()

지정된 높이(포인트를 10등분 하여 측정)와 서체를 가진
CFont 객체 생성

CreatePointFontIndirect()

LOGFONT 구조에 명시된 속성을 가진 CFont 객체 생성.
글꼴의 높이는 논리적 단위 대신 포인트를 10등분한 단위로 측정

FromHandle()

윈도우 HFONT로부터 CFont 객체로 포인터를 반환한다.

operator HFONT()

CFont 객체에 첨부된 기본적인 윈도우 GDI 글꼴 핸들을 반환

GetLogFont()

CFont 객체에 첨부된 논리적 글꼴에 대한 정보를 LOGFONT에
기록함
Visual C++ Programming

(C) 1998 Sang Il Kim

CreateFontIndirect() LOGPEN 구조에 명시된 속성을 가진 CFont 객체 생성

2
2

CHAPTER 5
? CBitmap 클래스
? 비트맵은 그래픽 이미지, 그림이나 무늬를 결정짓는 픽셀들의 배열이다.
? CBitmap은 윈도우 비트맵에 대한 핸들을 캡슐화 한다.
? CPalette 클래스
? 팔레트는 색상 정보를 저장하는 윈도우 GDI 객체이다.
? MFC는 윈도우 색상 팔레트를 CPalette 클래스 안에 캡슐화 했다.
? CRgn 클래스
? 영역은 디스플레이 장치의 어느 구역 안에서 다각형이나 원형의 정보를
(C) 1998 Sang Il Kim

저장하는 윈도우 GDI 객체이다.
? CRgn은 GDI 영역 객체를 캡슐화 한다.

Visual C++ Programming

2
2

CHAPTER 5
메소드

설명

CombineRgn()

두 개의 지정된 영역 객체의 결합체를 생성한다.

CopyRgn()

CRgn 객체를 다른 쪽으로 복사한다.

CreateEllipticRgn()

원형의 구역을 가진 CRgn 객체를 생성한다.

CreateEllipticRgnIndirect()

원형의 구역을 가진 CRgn 객체를 생성하며, 이것을 소유하는
상자는 RECT 구조에서 정의한다.

CreateFromData()

지정된 영역과 기하학적으로 변형된 데이터들을 기초로 영역을
생성한다.

CreateFromPath()

지정된 디바이스 컨텍스트로 선택한 경로를 기초로 영역을 생성한다.

CreatePolygonRgn()
CreatePolyPolygonRgn()

CreateRectRgn()

다각형의 구역을 가진 CRgn 객체를 생성한다. 필요하다면
다각형의 맨 끝 꼭지점을 맨 처음 꼭지점에 연결함으로써
다각형의 영역은 자동으로 닫히게 된다.
일련의 닫힌 다각형들로 구성된 영역을 가진 CRgn 객체를
생성한다.
직사각형의 영역을 가진 CRgn 객체를 생성한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CRgn 클래스
? 영역을 생성하고 활용하는데 사용하는 CRgn 클래스

2
2

CHAPTER 5
? CRgn 클래스
? 영역을 생성하고 활용하는데 사용하는 CRgn 클래스
메소드

설명

CreateRectRgnIndirect()

RECT 구조에 의해 정의된 직사각형의 영역을 가진 CRgn 객체를
생성한다.

EqualRgn()

두 개의 CRgn 객체를 영역이 같은지를 결정하기 위하여 서로 비교한다.

FromHandle()

윈도우 영역에 대한 핸들로부터 CRgn 객체로 포인터를 반환한다.

GetRegionData()

지정된 영역을 기술하는 데이터로 버퍼를 채운다.

GetRgnBox()

CRgn 객체를 포함하는 직사각형과 동일한 직사각형을 받는다.

OffSetRgn()

지정한 위치로 CRgn 객체를 옮긴다.

PtInRegion()

영역 안에 지정된 지점이 있는지 확인한다.

RectInRegion()

영역의 경계선 안에 어떠한 지정된 직사각형의 부분이 존재하는지
확인한다.

SetRectRgn()

존재하는 CRgn 객체를 지정된 직사각형 영역으로 맞춘다.

연산자 HRGN

CRgn 객체 안의 윈도우 핸들을 반환한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CreateRoundRectRgn() 둥근 모서리의 직사각형을 가진 CRgn 객체를 생성한다.

2
2

CHAPTER 5
? 글꼴과 텍스트
? TTF(TrueType Font) : 아무런 이미지의 질 저하 없이 가상적으로 임의의
크기로 조정할 수 있는 벡터 글꼴
? 서체(typeface) : 글자의 스타일과 텍스트의 시각적 모양을 나타낸다.
? 글꼴 : 특정 서체에 있는 같은 글자의 집합
? 포인트 : 글꼴 문자의 높이를 측정하기 위해 사용
1포인트 - 1/72인치

? 윈도우에서 정의하는 글꼴 유형
? 래스터 글꼴(비트맵 글꼴)
? 벡터 글꼴 - 일련의 선 조각들로부터 구성된 글꼴
? 트루타입 글꼴 - 문자 윤곽을 정의하기 위해 선과 스플라인 곡선을 사용하는 글꼴
Visual C++ Programming

(C) 1998 Sang Il Kim

? 글꼴 특성
? 고정폭(단일 간격) : 모두 같은 폭을 갖는다.
? 가변폭 : 필요한 만큼의 공간만 갖는다.

2
2

CHAPTER 5
? 글꼴 계열
? 모든 서체는 글꼴의 스타일을 나타내는 글꼴 계열로 그룹이 나누어져 있다.
? DevStudio\Vc\include\<wingdi.h> 1073라인
◐ 윈도우에서 제공하는 글꼴 계열
계열 이름

설명

FF_DECORATIVE

고상한 글꼴. 예) Viking Runes

FF_MODERN

세리프가 있거나 없는 단일 간격 글꼴. 단일 간격 글꼴은 보통 현대적인데,
Pica, Elite, Courier New 등이 이에 속한다.

FF_ROMAN

세리프가 있는 비례 글꼴을 의미한다. 예) Times New Roman

FF_SCRIPT

필기체 형태의 글꼴을 의미한다. 예) Script, Cursive

FF_SWISS

세리프가 없는 비례 글꼴을 의미한다. 예) Arial

Visual C++ Programming

(C) 1998 Sang Il Kim

FF_DONTCARE 글꼴에 관한 정보가 전혀 필요하지 않을 때 사용하는 일반적인 계열 이름

2
2

? LOGFONT Structure(논리적 글꼴 구조)
? 장치 컨텍스트에서 사용하기 위해 논리적 글꼴을 만들 때 사용한다.
? 논리적 글꼴은 글꼴의 속성(굵은 글자체, 이탤릭체, 밑줄, 크기 ...) 을 정의한다.
? 글꼴을 사용하려면 먼저 장치 컨텍스트에 이를 선택해야 한다.
? 장치 컨텍스트에 선택되었으면, 논리적 글꼴이 물리적 글꼴이 된다.
? typedef struct tagLOGFONT {
LONG lfHeight;
// 문자 셀이나 문자의 논리적 높이
LONG lfWidth;
// 글꼴 내의 문자들의 평균 논리적 너비
LONG lfEscapement;
// 폰트에 쓰여진 텍스트의 각 라인의 각도( 1/10도 )
LONG lfOrientation;
// 각 문자의 기준선의 각도 ( 1/10도)
LONG lfWeight;
// 글꼴의 무게 (0-1000 사이)
BYTE lfItalic;
// TRUE 이면 이태릭체
BYTE lfUnderline;
// TRUE 이면 밑줄
BYTE lfStrikeOut;
// TRUE 이면 취소선
BYTE lfCharSet;
// 글꼴의 문자 집합
BYTE lfOutPrecision;
// 출력 정밀도.
BYTE lfClipPrecision;
// 클리핑 정밀도. 클리핑 경계에 있는 문자들을 처리하는 방법을 정의한다.
BYTE lfQuality;
// 출력 품질
BYTE lfPitchAndFamily; // 글꼴의 피치와 계열
CHAR lfFaceName[LF_FACESIZE]; // 32자로 제한된 문자열. 글꼴의 서체 이름을 나타낸다.
} LOGFONT;
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 5

2
2

CHAPTER 5
? 글꼴 생성
설명

CreateFontIndirect()

LOGFONT 구조에 의해 정의된 CFont 객체를 초기화한다.

CreateFont()

명시한 특성을 가진 CFont 객체를 초기화한다.

CreatePointFont()

지정한 높이와 서체를 갖는 CFont 객체를 초기화한다.

CreatePointFontIndirect()

LOGFONT 구조에 정의된 대로 CFont 객체를 초기화한다.
글꼴 높이는 논리적 단위 대신에 1/10 포인트를 사용한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

2
2

CHAPTER 5
? 글꼴 표시하기
? 트루타입 글꼴에서 맵핑 모드는 별로 중요하지 않으며, 단지 글꼴의 크기를
지정해주면 된다.

인덱스

설명

HORZSIZE
VERTSIZE
HORZRES
VERTRES
LOGPIXELSX
LOGPIXELSY

밀리미터(mm) 단위의 물리적 화면 폭
밀리미터(mm) 단위의 물리적 화면 높이
픽셀 단위의 화면 폭
래스터(raster) 라인 단위의 화면 높이
논리 인치당 수평 도트 수
논리 인치당 수직 도트 수

320
240
640
480
96
96

? MM_HIMETRIC 또는 MM_TWIPS와 같은 고정된 맵핑 모드를 사용할 경우,
디스플레이 드라이버는 물리적 화면 크기를 사용해서 맵핑을 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 화면에서의 논리적 인치와 물리적 인치

2
2

CHAPTER 5
? 맵핑 모드를 논리 트윕으로 설정하는 코드 (p155)
? pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(1440, 1440);
pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),
pDC->GetDeviceCaps(LOGPIXELSY));
? MM_TWIPS 맵핑 모드
? 12포인트 크기
?tmheight - 295
?tmInternalLeading - 55
(C) 1998 Sang Il Kim

?Netheight(폰트의 순수높이) - 240

Visual C++ Programming

2
2

CHAPTER 5
? 문자 높이 계산하기(p154)
? CDC의 멤버함수인 GetTextMetrics() 의 폰트 높이 측정 파라미터
?tmHeight

descender 와 diacritic 을 포함하는 폰트의 전체 높이

?tmExternalLeading

diacritic과 이전라인의 descender 사이의 거리

?Diacritic

구별자

?tminternalLeading
?Netheight

순수 높이

?Descender

하행문자

? Character의 전체크기
?tmHeight + tmExternalLeading

? 폰트의 크기 (=Netheight, 순수높이)
? ascending letter : ascender ( x의 높이보다 위로 나오는 부분, 上行문자 )
ex) b, d, f, h

? descending letter : descender ( x의 높이보다 아래로 나오는 부분, 下行문자 )
ex) g, j, p, q, y
Visual C++ Programming

(C) 1998 Sang Il Kim

?tmHeight - tmInternalLeading

2
3

CHAPTER 5

The TEXTMETRIC structure contains
basic information about a physical font.
All sizes are given in logical units.

typedef struct tagTEXTMETRIC { /* tm */
int tmHeight;
// 문자 높이 (ascent + descent)
int tmAscent;
// 기준선 위의 문자
int tmDescent;
// 기준선 아래의 문자
int tmInternalLeading;
// tmHeight 안쪽의 나머지 공간
int tmExternalLeading;
// 텍스트 행간의 나머지 공간
int tmAveCharWidth;
// 글꼴 문자의 평균 너비
int tmMaxCharWidth;
// 폭이 가장 긴 글꼴 문자의 너비
int tmWeight;
// 글꼴의 무게
BYTE tmItalic;
// 0이 아닐 때 이탤릭 글꼴
BYTE tmUnderlined;
// 0이 아닐 때 밑줄 글꼴
BYTE tmStruckOut;
// 0이 아닐 때 취소선이 있는 글꼴
BYTE tmFirstChar;
// 첫번째 글꼴 문자의 문자 값
BYTE tmLastChar;
// 마지막 글꼴 문자의 문자 값
BYTE tmDefaultChar;
// 기본 대체 문자
BYTE tmBreakChar;
// 단어 분리 포맷을 위한 문자 값
BYTE tmPitchAndFamily;
// 글꼴 피치와 글꼴 군에 대한 정보
BYTE tmCharSet;
// 글꼴의 문자 집합
int tmOverhang;
// 비어 있는 나머지 너비
int tmDigitizedAspectX;
// 대상 장치의 수평 면
int tmDigitizedAspectY;
// 대상 장치의 수직 면
} TEXTMETRIC;

Visual C++ Programming

(C) 1998 Sang Il Kim

? CDC::GetTextMetrics
? BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const;

2
3

CHAPTER 5
? CFont::CreateFont - 폰트를 생성하여 CFont 객체에 붙인다.
? BOOL CreateFont( int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename );
? CDC::GetTextExtent
? 현재 폰트를 사용하여 기술한 문자열의 높이와 폭(논리 단위)을 계산한다.
? CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
? CSize GetTextExtent( const CString& str ) const;
? Return Value
? Parameters
?lpszString 계산되는 크기에 대한 텍스트 문자열에 대한 포인터
?nCount

lpszString 파라미터에 의해 가리키는 문자열의 길이(바이트)

?str

계산되는 크기에 대한 텍스트 문자열을 포함하는 CString 객체에 대한 참조
Visual C++ Programming

(C) 1998 Sang Il Kim

문자열의 크기(논리단위)를 포함하는 CSize object.

2
3

? CDC::GetDeviceCaps() - 화면 수치들을 리턴해 준다.
? int GetDeviceCaps( int nIndex ) const;
? Parameters
?DRIVERVERSION 디바이스 드라이버 버전; for example, 0x100 for 1.0.
?TECHNOLOGY
디바이스 기술(technology).
?HORZSIZE
물리적인 디스플레이 폭 (밀리미터).
?VERTSIZE
물리적인 디스플레이 높이(밀리미터).
?HORZRES
디스플레이의 폭 (픽셀).
?VERTRES
디스플레이의 높이(in raster lines).
?LOGPIXELSX
디스플레이 폭의 논리 인치마다의 픽셀 수
?LOGPIXELSY
디스플레이 높이의 논리 인치마다의 픽셀 수
?BITSPIXEL
각 픽셀에 대한 색상 비트의 수
?PLANES
색상 판의 수
?NUMBRUSHES
디바이스 특정 브러시의 수
?NUMPENS
디바이스 특정 펜의 수
?NUMFONTS
디바이스 특정 폰트의 수
?NUMCOLORS
디바이스 색상 표에 있는 엔트리의 수
?ASPECTX
라인 그리기에 사용되는 디바이스 픽셀의 상대 폭
?ASPECTY
라인 그리기에 사용되는 디바이스 픽셀의 상대 높이
?ASPECTXY
라인 그리기에 사용되는 디바이스 픽셀의 대각선의 폭
?PDEVICESIZE
PDEVICE 내부 데이터 구조체의 크기
?CLIPCAPS
디바이스의 클리핑 성능
?SIZEPALETTE
시스템 팔레트에 있는 엔트리의 수
?NUMRESERVED
시스템 팔레트에 있는 예비된 엔트리의 수
?COLORRES
픽셀마다의 디바이스의 실제 색상 해상도
?RASTERCAPS
값은 디바이스의 래스터 성능을 나타낸다.
?CURVECAPS
디바이스의 곡선 성능
?LINECAPS
디바이스가 지원하는 라인 성능
?POLYGONALCAPS 디바이스가 지원하는 다각형 성능
?TEXTCAPS
디바이스가 지원하는 텍스트 성능

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 5

2
3

CHAPTER 5
? CDC::GetTextFace
? 현재 폰트에 대한 서체 이름을 널로 끝나는 문자열로 얻는다.
? int GetTextFace( int nCount, LPTSTR lpszFacename ) const;
? int GetTextFace( CString& rString ) const;
lpszFacename 파라미터에 의해 가리키는 버퍼의 크기

?lpszFacename

서체 이름이 넣어지는 버퍼에 대한 포인터

?rString

서체 이름이 넣어지는 CString에 대한 참조

(C) 1998 Sang Il Kim

? Parameters
?nCount

Visual C++ Programming

2
3

CHAPTER 5
? CDC::SetBrushOrg
? 현재의 브러시 원점을 설정한다.
? 디바이스 컨텍스트에 대한 기본 브러시 원점은 0, 0이다.
? 브러시는 8 x 8픽셀 비트맵으로 표시되기 때문에,
브러시 원점의 x와 y좌표는 0에서 7까지의 범위이다.
? CPoint SetBrushOrg( int x, int y );
? CPoint SetBrushOrg( POINT point );

?point 새로운 브러시 원점( 장치 단위 )을 포함하는 POINT 구조체나
CPoint 객체

Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?x
새로운 브러시 원점의 x 좌표 ( 장치 단위, 0 - 7 )
?y
새로운 브러시 원점의 y 좌표 ( 장치 단위, 0 - 7 )

2
3

CHAPTER 5
? EX05A 의 프로그램 요소들
? OnPrepareDC 에 맵핑 모드를 설정
? ShowFont Private 멤버 함수
? CFont::CreateFont 함수호출
?첫번째 인자 : 폰트의 높이
?두번째 인자 : 폰트의 너비
두번째 인자를 0으로 설정하면, 폰트디자이너가 정의한 비율로 설정된다.
?마지막 인자 : 폰트의 이름
?첫번째 인자가 음수 : 문자의 크기(tmHeight - tmInternalLeading)를 설정
(C) 1998 Sang Il Kim

양수 : 셀의 크기(tmHeight)가 된다.

Visual C++ Programming

2
3

CHAPTER 5
? OnDraw() 함수의 구성요소
? fontTest1 : 디폴트 너비로 선택된 트루타입 폰트 Arial
? fontTest2 : 디폴트 너비로 선택된 폰트 Courier
? fontTest3 : 범용(generic) Roman 폰트
? fontTest4 : LinePrinter 가 기술되었지만, 이 폰트는 디스플레이 하기위한
윈도우 폰트가 아니기 때문에 FF_MODERN 이라고 기술해 준 부분을

(C) 1998 Sang Il Kim

가지고 트루타입 Courier New 폰트를 선택한다.

Visual C++ Programming

2
3

CHAPTER 5
? EX05C 의 프로그램 요소들
? OnPrepareDC 에 맵핑 모드를 설정
? ShowFont Private 멤버 함수
? CFont::CreateFont 함수호출
?첫번째 인자 : 폰트의 높이
?두번째 인자 : 폰트의 너비
두번째 인자를 0으로 설정하면, 폰트디자이너가 정의한 비율로 설정된다.
?마지막 인자 : 폰트의 이름
?첫번째 인자가 음수 : 문자의 크기(tmHeight - tmInternalLeading)를 설정
(C) 1998 Sang Il Kim

양수 : 셀의 크기(tmHeight)가 된다.

Visual C++ Programming

2
3

CHAPTER 5

Value

Description

IDC_APPSTARTING
IDC_ARROW
IDC_CROSS
IDC_IBEAM
IDC_ICON
IDC_NO
IDC_SIZE
IDC_SIZEALL
IDC_SIZENESW
IDC_SIZENS
IDC_SIZENWSE
IDC_SIZEWE
IDC_UPARROW
IDC_WAIT

Standard arrow and small hourglass
Standard arrow
Crosshair
Text I-beam
Windows NT only:Empty icon
Slashed circle
Windows NT only:Four-pointed arrow
Same as IDC_SIZE
Double-pointed arrow pointing northeast and south
Double-pointed arrow pointing north and south
Double-pointed arrow pointing northwest and south
Double-pointed arrow pointing west and east
Vertical arrow
Hourglass
Visual C++ Programming

(C) 1998 Sang Il Kim

? Win32 에서 사용되는 커서

2
3

무릎 꿇고 있는 나무
로키산맥 해발 3천미터 높이에
수목 한계선인 지대가 있습니다.
이 지대의 나무들은 매서운 바람으로 인해
곧게 자라지 못하고
‘무릎 꿇고 있는 모습’을 한 채 있어야 합니다.
이 나무들은 열악한 조건이지만
생존을 위해 무서운 인내를 발휘하며 지냅니다.
그런데 세계적으로 가장 공명이 잘 되는 명품 바이올린은

(C) 1998 Sang Il Kim

바로 이 ‘무릎 꿇고 있는 나무’로 만든다고 합니다.
아름다운 영혼을 갖고
인생의 절묘한 선율을 내는 사람은
아무런 고난 없이 좋은 조건에서 살아온 사람이 아니라
온갖 역경과 아픔을 겪어온 사람입니다.

Visual C++ Programming

2
4

CHAPTER 6

(C) 1998 Sang Il Kim

모달 다이얼로그와
윈도우95 공통 컨트롤

Visual C++ Programming

2
4

CHAPTER 6
? 모달(Modal) 다이얼로그와 모드리스(Modeless) 다이얼로그
? 모달(Modal) 다이얼로그
다이얼로그 박스가 닫히기 전에는 어플리케이션의 다른 기능을
사용할 수 없다.
? 모드리스(Modeless) 다이얼로그
다이얼로그 박스가 화면에 출력된 상태에서도 어플리케이션의 다른 기능을
사용할 수 있다.
? 윈도우 공통 컨트롤 (DevStudio\Vc\mfc\include\<Afxcmn.h>)
? CAnimateCtrl, CHotKeyCtrl, CImageList, CListCtrl, CProgressCtrl,
CRichEditCtrl, CSliderCtrl, CSpinButtonCtrl, CStatusBarCtrl
? 공통 컨트롤은 모두 COMMCTRL.DLL에 저장되어 있다.
Ctrl 접미사를 가진 컨트롤 클래스들은 Win32 운영 체제에서만
사용할 수 있는 새로운 공통 컨트롤 클래스들이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CTabCtrl, CToolBarCtrl, CToolTipCtrl, CTreeCtrl

2
4

CHAPTER 6
? 애니메이트 컨트롤 (CAnimateCtrl)
? 윈도 AVI(Audio Video Interleaved) 영화 파일을 상영하는 윈도우이다.
? AVI 파일은 보통 영화의 프레임을 구성하는 일련의 정적 비트맵 이미지들을
디지털 소리와 엮어 합성한 것이다.
? 애니메이션 컨트롤은 소리를 지원하지 않는다.
? 핫 키 컨트롤 (CHotKeyCtrl)
? 핫 키 컨트롤 또는 키보드 가속기는 사용자가 특정 행동을 수행하거나 몇몇
명령을 보낼 수 있는 키 조합을 의미.
? 핫 키 컨트롤은 사용자가 자신의 핫 키를 정의할 수 있도록 하는 윈도우이다.

(C) 1998 Sang Il Kim

? 이미지 목록 컨트롤 (CImageList)
? 0부터 시작하는 비트맵 이미지의 배열이다.
? Win32는 이미지를 만들고, 추가하고, 삭제하고, 교체하고, 합하고, 잡아 끌고,
소멸할 수 있는 함수들을 제공한다.
Visual C++ Programming

2
4

CHAPTER 6
? 목록 보기 컨트롤 (CListCtrl)
? 아이콘과 텍스트의 레이블의 조합으로 이루어진 항목들의 목록을 나타낸다.
? 진행 표시자 컨트롤 (CProgressCtrl)
? 응용 프로그램이 특정 행동의 진행 과정을 보여주는 표준화된 방법을 제공.
? 리치 에디트 컨트롤 (CRichEditCtrl)
? 사용자가 텍스트를 입력하고 편집할 수 있을 뿐만 아니라 텍스트에 여러 가지
방법으로 서식을 지정할 수도 있다.
? 문자와 문단의 서식 지정과 OLE지원, 다양한 글꼴을 동시에 사용할 수 있다.
? 트랙바 컨트롤 (CSliderCtrl)
? 스핀 버튼 컨트롤 (CSpinButtonCtrl)
? 스크롤 위치나 컨트롤에 표시되는 수와 같이 어떤 값을 증가하거나
감소하는데 사용되는 한 쌍의 화살표 버튼
Visual C++ Programming

(C) 1998 Sang Il Kim

? 최소값과 최대값 사이의 선택된 범위의 값을 제공한다.

2
4

CHAPTER 6
? 상태 표시줄 컨트롤 (CStatusBarCtrl)
? 사용자가 다음에 무엇을 해야 하고 특정 동작의 상태가 무엇인지를 알 수
있도록 도와 주는 정보를 나타낸다.
? 탭 컨트롤 (CTabCtrl)
? 하나의 대화 상자나 창에 여러 개의 페이지를 설정할 수 있다.
? 도구 모음 컨트롤 (CToolBarCtrl)
? 한 줄의 단추들을 담고 있는 컨트롤 표시줄의 한 유형이다.
? 단추들은 단추 이미지를 담고 있는 비트맵으로부터 만들어진다.
? 도구 모음 단추는 마우스가 이 위로 지나갈 때 도구 설명(Tooltip)을
? 트리 보기 컨트롤 (CTreeCtrl)
? 항목들의 계층을 나타낸다.
? 트리 내의 각 항목은 텍스트 문자열은 물론 이와 관련된 비트맵을 갖고 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

나타낼 수 있다.

2
4

CHAPTER 6
? 도구 설명 컨트롤(CToolTipCtrl)
? 어플리케이션에서 툴바 버튼이나 다른 도구의 사용 기능을 한 라인으로
기술하여 텍스트를 표시하는 작은 팝업 윈도우.
? 체크 리스트 박스(CCheckListBox)
? 체크 박스가 리스트에 있는 각 항목의 옆에 나타나고, 사용자는 선택된
항목의 체크 박스를 체크하거나 해제할 수 있다.
? 이동 리스트 박스(CDragListBox)
? 리스트 상자에 있는 파일 이름과 문자열과 같이 항목을 이동(drag)할 수 있게
해 준다. 이 기능을 갖는 리스트 박스는 프로젝트에 있는 경로 이름이나
(C) 1998 Sang Il Kim

파일들과 같이 알파벳보다는 다른 순서로 분류되어 있는 항목에 유용하다.
? CHeaderCtrl
? 텍스트의 칼럼 위에 나타나는 크기를 조정할 수 있는 버튼.

Visual C++ Programming

2
4

CHAPTER 6
? 리소스와 컨트롤
? 다이얼로그는 일종의 윈도우이다.
? 다이얼로그 윈도우와 CView 윈도우의 차이점
?다이얼로그 윈도우는 다이얼로그 구성요소와 레이아웃을 포함하고 있는
리소스를 사용한다.
? 다이얼로그 컨트롤

(C) 1998 Sang Il Kim

?Edit Control(Text Box), Button, List Box, Combo Box,
Static Text(Label), Tree View, Progress Indicator, Slider
?다이얼로그 컨트롤은 CWnd 포인터나 인덱스 번호에 의해서 참조될 수 있다.
?컨트롤은 사용자의 행동에 반응하여 부모 다이얼로그(Parent Dialog)에
메시지를 보낸다.

Visual C++ Programming

2
4

CHAPTER 6
? 모달(Modal) 다이얼로그 프로그래밍
? 기존의 프로젝트에 새 다이얼로그 추가
1. 다이얼로그 에디터를 이용하여 다이얼로그를 작성한다.
3. ClassWizard를 사용하여 데이터 멤버를 만든다.
(Exchange Function은 ClassWizard가 만들어준다.)
4. ClassWizard를 사용하여 이벤트를 발생시키는 컨트롤의 메시지 핸들러를
만든다.
5. OnInitDialog 함수 안에 특정한 컨트롤들의 초기화를 시켜주는 코드와
메시지 핸들러의 코드를 작성한다.
(사용자가 다이얼로그를 닫을 때는 CDialog의 가상함수인 OnOK() 가
수행되도록 한다.)
6. 뷰 클래스안에서 다이얼로그를 보여주는 부분을 작성한다.
모달 다이얼로그를 만들때는 DoModal() 함수를 사용한다.
DoModal() 함수는 사용자가 다이얼로그를 닫을 때 리턴된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

2. ClassWizard를 사용하여 CDialog에서 파생된 다이얼로그 클래스를 만든다.

2
4

CHAPTER 6
? Progress Indicator 컨트롤(CProgressCtrl)
? Progress Indicator를 초기화하기 위해서는 OnInitDialog 함수 내에서
SetRange와 SetPos 멤버함수를 사용한다. 메시지 핸들러 내에서 SetPos
함수를 사용하여 진척정도를 조정할 수 있다. ( 0 - 100 사이의 범위를 갖는다. )
메소드

설명

int SetPos( int nPos );

진행 표시자의 현재 위치를 설정한다.

int OffsetPos( int nPos );

진행 표시자의 현재 위치에서
nPos만큼 증가시킨다.

int SetStep( int nStep );

진행 표시자의 증가되는 양을
설정한다.(디폴트 10)

int Steplt();

설정된 Step 만큼 현재 위치를
증가시킨다.
Visual C++ Programming

(C) 1998 Sang Il Kim

void SetRange(int nLower, int nUpper); 진행 표시자의 범위를 설정한다.

2
4

CHAPTER 6

매개변수

설명

dwStyle

그 컨트롤에 대한 창 스타일을 설정한다.
이것은 일반적인 창 스타일의 어떠한 조합도 가능하다.

rect

컨트롤의 크기와 위치를 지정하는 직사각형

nParentWnd

그 컨트롤의 부모 창에 대한 포인터

nID

트리 보기 컨트롤과 통신하기 위해 부모 창에서 사용하는 컨트롤 ID

Visual C++ Programming

(C) 1998 Sang Il Kim

? Progress Indicator 컨트롤(CProgressCtrl)

2
5

CHAPTER 6
? 트랙바 컨트롤(CSliderCtrl)
? 트랙바 컨트롤은 슬라이더라고도 불리며, 사용자가 아날로그값을 설정할 수
있도록 해준다. 컨트롤의 범위를 크게 설정하면, 트랙바의 움직임이 연속적인
것처럼 보인다. 범위를 작게 설정하면, 트랙바는 불연속적으로 움직인다.
트랙바는 WM_HSCROLL 이나 WM_VSCROLL 메시지를 맵핑시킬 필요가
없기 때문에, 스크롤바보다는 구현하기가 쉽다.

매시지 맵 항목

설명

ON_WM_HSCROLL

화살표 버튼을 눌렀을 때 TBS_HORZ 를 갖는
슬라이더 컨트롤에 의해 발생된다.

ON_WM_VSCROLL

화살표 버튼을 눌렀을 때 TBS_VERT(기본설정) 를 갖는
슬라이더 컨트롤에 의해 발생된다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CSliderCtrl 메시지에 대한 두 개의 메시지 맵 항목

2
5

CHAPTER 6
? 슬라이더 컨트롤을 위해 정의된 창 스타일(트랙바 컨트롤,Track Bar Styles-TBS)
스타일 매크로

설명

TBS_AUTOTICKS

허용하는 값 범위 내에서 각 증가에 따라 슬라이더 눈금 표시를 준다.
눈금 표시는 SetRange() 메소드를 호출함으로써 자동으로 생성된다.

TBS_NOTICKS

슬라이더가 눈금 표시를 가지지 못하게 한다.

슬라이더 컨트롤의 방향(수평,수직)에 관계없이 슬라이더
컨트롤의 양쪽 면에 눈금 표시를 한다.
선택된 범위의 시작점과 끝점을 가리키는 삼각형 모양의 슬라이더
TBS_ENABLESELRANGE
눈금 표시를 준다.
TBS_LEFT

수직 슬라이더 컨트롤의 왼쪽 면에 눈금 표시를 한다.

TBS_RIGHT

수직 슬라이더 컨트롤의 오른쪽 면에 눈금 표시를 한다.

TBS_HORZ

슬라이더 방향을 수평으로 한다.(기본값)

TBS_VERT

슬라이더 방향을 수직으로 한다.

TBS_TOP

수평 슬라이더 컨트롤의 위에 눈금 표시를 한다.

TBS_BOTTOM

수평 슬라이더 컨트롤의 아래에 눈금 표시를 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

TBS_BOTH

2
5

CHAPTER 6
통지 코드

설명

TB_PAGEUP

사용자가 슬라이더의 위쪽, 또는 왼쪽 채널을 클릭하거나,
PageUp키를 눌렀다.

TB_PAGEDOWN

사용자가 슬라이더의 아래쪽, 또는 오른쪽 채널을 클릭하거나,
PageDown키를 눌렀다.

TB_LINEUP

사용자가 키보드의 상향 화살표나 좌향 화살표를 눌렀다.

TB_LINEDOWN

사용자가 키보드의 하향 화살표나 우향 화살표를 눌렀다.

TB_ENDTRACK

사용자가 키를 떼어 어떤 가상 키 코드(WM_KEYUP)를
보내도록 한다. 화면 이동(scrolling)이 중단된다.

TB_THUMBTRACK

사용자가 슬라이더를 드래그했다.

사용자가 슬라이더를 드래그하다가(TB_THUMBTRACK)
TB_THUMBPOSITION 왼쪽 마우스 버튼에서 손을 뗐다. 절대 위치로 스크롤한다.
현재 위치는 nPos에 제공된다.
TB_TOP

사용자가 키보드에서 Home키를 눌렀다.

TB_BOTTOM

사용자가 키보드에서 End키를 눌렀다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? OnHScroll()과 OnVScroll() 메소드에서 슬라이더 컨트롤이 사용하는 통지 코드

2
5

CHAPTER 6
? 속성을 다루는 CSliderCtrl 클래스 메소드
메소드

설명

void GetChannelRect( LPRECT lprc ) const; 슬라이더 컨트롤의 채널 크기를 얻는다.

int GetLineSize( ) const;

슬라이더 컨트롤의 행 크기를 얻는다.

UINT GetNumTics( ) const;

슬라이더 컨트롤의 눈금 표시 수를 얻는다.

int GetPageSize( ) const;

슬라이더 컨트롤의 페이지 크기를 얻는다.

int GetPos() const;

슬라이더의 현재 위치를 얻는다.

int GetRangeMax( ) const;

슬라이더의 최대 위치를 얻는다.

int GetRangeMin( ) const;

슬라이더의 최소 위치를 얻는다.

void GetSelection(int& nMin,int& nMax) const;

현재의 선택 범위를 얻는다.

void GetThumbRect(LPRECT lprc) const; 슬라이더 컨트롤의 버튼 크기를 얻는다.

int GetTic( int nTic ) const;

지정된 눈금 표시의 위치를 얻는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

void GetRange(int& nMin,int& nMax) const; 슬라이더에 대한 최대 및 최소 위치를 얻는다.

2
5

CHAPTER 6
? 속성을 다루는 CSliderCtrl 클래스 메소드
메소드

설명

DWORD* GetTicArray( ) const;

슬라이더 컨트롤에 대한 눈금 표시 위치들의 배열을 얻는다.

int GetTicPos( int nTic ) const;

클라이언트 좌표 내에서 지정된 눈금 표시의 위치를 얻는다.

int SetLineSize( int nSize );

슬라이더 컨트롤의 행 크기를 설정한다.

int SetPageSize( int nSize );

슬라이더 컨트롤의 페이지 크기를 설정한다.

void SetPos( int nPos );
void SetRange( int nMin, int nMax,
BOOL bRedraw = FALSE );
void SetRangeMax( int nMax,
BOOL bRedraw = FALSE );
void SetRangeMin( int nMin,
BOOL bRedraw = FALSE );

슬라이더의 현재 위치를 설정한다.
슬라이더에 최대 및 최소 위치를 설정한다.
슬라이더의 최대 위치를 설정한다.

void SetSelection(int nMin,int nMax); 슬라이더의 선택 범위를 설정한다.
BOOL SetTic( int nTic );

지정된 눈금 표시의 위치를 설정한다.

void SetTicFreq( int nFreq );

슬라이더 컨트롤이 증가할 때 눈금 표시의 빈도수를 설정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

슬라이더의 최소 위치를 설정한다.

2
5

CHAPTER 6
? 연산을 다루는 CSliderCtrl 클래스 메소드
메소드

설명

void ClearSel(BOOL bRedraw = FALSE); 슬라이더 컨트롤에서 현재의 선택을 지워 버린다.
void ClearTics(BOOL bRedraw = FALSE); 슬라이더 컨트롤에서 현재의 눈금 표시를 제거한다.

void VerifyPos( );

슬라이더 컨트롤의 위치가 0인지 검사한다.

?예
눈금의 빈도수를 설정
m_pSlider1->SetTicFreq(8);
m_pSlider2->SetTicFreq(8);

(C) 1998 Sang Il Kim

페이지 크기를 설정
m_pSlider1->SetPageSize(8);
m_pSlider2->SetPageSize(8);
행 크기를 설정
m_pSlider1->SetLineSize(1);
m_pSlider2->SetLineSize(1);
Visual C++ Programming

2
5

CHAPTER 6
? 스핀 버튼 컨트롤(CSpinButtonCtrl)
? 스핀 컨트롤 바로 앞에 위치한 에디트 컨트롤은 스핀 버튼의 버디(buddy)라고
한다. 버디에서 정수값을 사용한다면, ClassWizard를 사용하여 에디트 컨트롤의
integer 데이터 멤버를 추가하기만 하면 된다.
스핀 컨트롤의 속성에서 Auto Buddy와 Set Buddy Integer 속성을 설정해야 한다.
OnInitDialog() 함수에서 SetRange() 와 SetAccel() 멤버 함수를 사용하여 범위와,
가속 정도를 설정할 수 있다. 만약 정수가 아닌 값을 에디트 컨트롤에 표시하려면,
WM_VSCROLL 과 WM_HSCROLL 메시지를 맵핑한 후, GetPos() 과 GetBuddy()
를 사용해야 한다.

메시지 맵 항목

설명

ON_WM_HSCROLL

화살표 단추를 누를 때 UDS_HORZ 스타일을 가지는
스핀 컨트롤에 의해 전송된다.

ON_WM_VSCROLL

화살표 단추를 누를 때 UDS_VERT 스타일을 가지는
스핀 컨트롤에 의해 전송된다.

ON_EN_UPDATE

문자가 변할 때 편집 컨트롤에 의해 전송된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 스핀 버튼 컨트롤(CSpinButtonCtrl)
? 스핀 버튼 컨트롤 메시지에 대한 메시지 맵 항목

2
5

CHAPTER 6
? 스핀 버튼 컨트롤(CSpinButtonCtrl) 클래스 메소드
메소드

설명

void SetRange(int nLower, int nUpper); 스핀버튼의 범위를 설정한다.
int SetPos( int nPos );

스핀버튼의 현재위치를 설정한다.

BOOL SetAccel( int nAccel,
UDACCEL* pAccel );

스핀버튼의 가속정도를 설정한다.

int SetBase( int nBase );

스핀버튼에 대한 기반을 설정한다.

CWnd* SetBuddy(CWnd* pWndBuddy); 스핀버튼에 대한 버디 윈도우를 설정한다.
void GetRange( int &lower, int &upper )
스핀버튼의 범위를 얻는다.
const;
스핀버튼의 현재위치값을 리턴한다.

UINT GetAccel( int nAccel,
스핀버튼의 가속정도를 얻는다.
UDACCEL* pAccel ) const;
UINT GetBase( ) const;

스핀버튼에 대한 현재 기반을 얻는다.

CWnd* GetBuddy() const;

현재 버디 윈도우의 포인터를 리턴한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

int GetPos() const;

2
5

CHAPTER 6
? 스핀 버튼 컨트롤(CSpinButtonCtrl)을 위해 정의된 창 스타일
스타일 매크로

설명

UDS_ALIGNLEFT

스핀 버튼을 버디의 왼쪽 끝에 정렬한다.

UDS_ALIGNRIGHT

스핀 버튼을 버디의 오른쪽 끝에 정렬한다.

UDS_ARROWKEYS

키보드에서 화살표키를 누를 때, 컨트롤의 현재 위치를
증가시키고 감소시킨다.

UDS_AUTOBUDDY

z 순서에서 이전의 창을 선택함으로써 자동으로 버디를 선택한다.

UDS_HORZ

스핀 버튼의 화살표를 좌우 화살표로 한다.

UDS_SETBUDDYINT

현재 위치가 변할 때 버디의 문자를 설정하도록 컨트롤에게 말한다.
문자는 현재 위치가 10진수나 16진수 문자열로 바뀌어 나타난다.

UDS_WRAP

현재 위치가 감기도록 한다. 최대값 이상의 값은 이동(scroll)범위의
최소값으로 다시 시작하도록 감기고, 그 반대도 마찬가지이다.

Visual C++ Programming

(C) 1998 Sang Il Kim

UDS_NOTHOUSANDS 모든 세자리 십진수 사이에 천자리 구분자를 하지 못하게 한다.

2
5

CHAPTER 6
? 목록 상자 컨트롤(CListBox)
? 단일 선택 목록 상자 - 한 번에 하나의 항목만을 선택할 수 있다.

(C) 1998 Sang Il Kim

? 다중 선택 목록 상자 - 여러 개의 항목을 선택할 수 있다.

Visual C++ Programming

2
6

CHAPTER 6
? CListBox 컨트롤 창 스타일 (DevStudio\Vc\include\winuser.h)
스타일 매크로

설명

LBS_DISABLENOSCROLL

목록 상자가 스크롤이 필요할 만큼의 충분한 항목을 가지고 있지 않을
때 수직 이동 표시줄을 사라지게 하는 대신 작동만 되지 않도록 한다.

LBS_EXTENDEDSEL

목록 상자에서 마우스와 특별한 키의 조합을 사용하여 여러 개의
항목을 선택할 수 있도록 허락한다.

LBS_HASSTRINGS

문자열 항목을 담고 있는 자신이 직접 그린 목록 상자를 지정한다.
그 목록 상자는 문자열들에 대한 메모리 할당을 책임진다.
GetText()로 추출할 수 있는 특정한 항목의 문자
수평 이동 표시줄과 함께 여러 개의 열을 갖도록 목록 상자를 지정한다.

LBS_MULTICOLUMN SetColumnWidth()를 이용하여 열의 너비(수)를 설정할 수 있다.

LBS_NOINTEGRALHEIGHT

LBS_NOREDRAW

사용자가 항목을 한 번 클릭하거나 두 번 클릭을 할 때마다 문자열
항목을 선택, 또는 선택 취소를 한다.
윈도우는 대개 목록 상자가 충분하지 않으면, 일부 항목들은 출력
하지 못하게 목록 상자의 크기를 잡는다. 이 매크로는 생성할 때
부분 항목들을 볼 수 있도록 정확히 목록 상자의 크기를 잡는다.
목록 상자는 변경이 있을 때 다시 그리기를 하지 않는다.
WM_SETREDRAW 메시지를 보냄으로써 언제라도 이 스타일을
변경할 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

LBS_MULTIPLESEL

2
6

CHAPTER 6
? CListBox 컨트롤 창 스타일
스타일 매크로

설명

목록 상자가 보일 수는 있지만, 선택할 수 없는 항목들을 포함하고
있음을 가리킨다.
목록 상자는 사용자가 목록 항목을 한 번 클릭하거나 두 번 클릭할 때
LBS_NOTIFY
부모 창에게 입력 메시지를 보낸다.
목록 상자의 부모 창이 그 내용을 그리는 데 책임을 가지며, 목록의
LBS_OWNERDRAWFIXED
항목을 모두 같은 높이로 그리도록 지정한다.
목록 상자의 부모 창이 그 내용을 그리는 데 책임을 가지며, 목록의
LBS_OWNERDRAWVARIABLE
항목을 모두 다른 높이로 그리도록 지정한다.

LBS_NOSEL

LBS_STANDARD
LBS_USETABSTOPS
LBS_WANTKEYBOARDINPUT

목록 상자의 문자열을 알파벳순으로 정렬한다.
이 스타일은 네 개의 스타일 비트의 조합이다.
LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER.
이 목록 상자는 그 주위에 경계선을 그리고, 목록 내의 문자열들을
알파벳순으로 정렬하고, 사용자가 목록 항목을 한 번 클릭하거나
두 번 클릭할 때 부모 창에게 입력 메시지를 보낸다.
문자열 항목을 그릴 때 탭 문자들을 확장하도록 목록 상자에게
알려 준다. 기본 탭 위치는 32다이얼로그 단위
사용자가 키를 누를 때 WM_VKEYTOITEM 및 WM_CHARTOITEM
메시지를 목록 상자의 부모 창에게 보냄으로써 응용 프로그랭에게
키보드 입력을 처리할 수 있도록 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

LBS_SORT

2
6

CHAPTER 6
? CListBox 메시지에 대한 메시지 맵 항목
메시지 맵 항목

설명

ON_LBN_DBLCLK

사용자가 목록 상자에 있는 항목을 두 번 클릭할 때 LBS_NOTIFY
스타일을 가지는 목록 상자가 이 메시지를 부모 창에게 보낸다.

ON_LBN_ERRSPACE

목록 상자가 충분한 메모리를 할당할 수 없다.

ON_LBN_KILLFOCUS 이 메시지는 목록 상자가 입력 포커스를 잃어 버릴 때 발생한다.

현재 선택된 목록 상자 항목이 취소되었을 때 LBS_NOTIFY
스타일을 가지는 목록 상자가 이 메시지를 부모 창에게 보내다.

목록 상자에서 다른 항목을 선택할 때 LBS_NOTIFY 스타일을
가지는 목록 상자가 이 메시지를 부모 창에게 보낸다. 선택이
CListBox::SetCurSel() 클래스 메소드에 의해 변경되었다면,
ON_LBN_SELCHANGE
통보 메시지는 전송되지 않는다. 다중 목록 상자의 경우 선택이
바뀌지 않는다 하더라도 사용자가 화살표를 누를 때는 이 통보
메시지가 전송된다.
ON_LBN_SETFOCUS 이 메시지는 목록 상자가 입력 포커스를 얻을 때 발생한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

ON_LBN_SELCANCEL

2
6

CHAPTER 6
? CListBox 클래스 메소드
? 범용 메소드
? 단일 선택 목록 상자 메소드
?int GetCurSel( ) const;
현재 선택된 목록 상자 항목에 대한 색인(0을 기반으로 한 색인)을 얻는다.
?int SetCurSel( int nSelect ); 목록 상자 문자열을 선택한다.
? 다중 선택 목록 상자 메소드
? 문자열에만 해당하는 메소드
?LB_ERRSPACE(-2) : 목록 상자가 항목을 저장할 만큼 충분한 메모리가 없을 때
?LB_ERR(-1) : 목록 상자가 어떤 다른 오류를 만났을 때
?LB_OKAY(0) : 모든 것이 예상대로 진행되었을 때
? 가상 메소드
Visual C++ Programming

(C) 1998 Sang Il Kim

? 위 네 가지 메소드들의 가능한 반환값

2
6

CHAPTER 6
? 범용 CListBox 클래스 메소드
메소드

설명

int GetCount( ) const;

목록 상자에 있는 항목의 개수를 얻는다.

int GetHorizontalExtent( ) const;

목록 상자의 수평 스크롤 너비(픽셀 단위)를 얻는다.

DWORD GetItemData
목록 상자 항목과 관련이 있는 32비트 값을 얻는다.
( int nIndex ) const;
void* GetItemDataPtr
목록 상자 항목에 대한 포인터를 얻는다.
( int nIndex ) const;
int GetItemHeight
( int nIndex ) const;

목록 상자에 있는 항목들의 높이를 얻는다.

LCID GetLocale( ) const;

목록 상자에 대한 지역 식별자(LCID, Locale identifier)를 얻는다.

int GetSel( int nIndex ) const; 목록 상자 항목의 선택 상태를 얻는다.
int GetText( int nIndex, LPTSTR lpszBuffer ) const;
void GetText( int nIndex, CString& rString ) const;

목록 상자 문자열을 버퍼로 복사한다.

int GetTextLen
목록 상자 문자열의 길이(바이트 단위)를 반환한다.
( int nIndex ) const;
Visual C++ Programming

(C) 1998 Sang Il Kim

int GetItemRect( int nIndex,
목록 상자 항목의 경계 직사각형을 얻는다.
LPRECT lpRect ) const;

2
6

CHAPTER 6
? 범용 CListBox 클래스 메소드
메소드

설명

int GetTopIndex( ) const;

목록 상자에서 맨 먼저 보이는 항목의 색인(0을 기반으로 한 색인)을 얻는다.

UINT ItemFromPoint (CPoint pt,
포인트에 가장 가까운 목록 상자 항목 색인을 결정하고 반환한다.
BOOL& bOutside ) const;

void SetColumnWidth
다중 열을 가지는 목록 상자의 열 너비를 설정한다.
( int cxWidth );
void SetHorizontalExtent
( int cxExtent );

목록 상자의 수평 스크롤 너비(픽셀 단위)를 설정한다.

int SetItemData( int nIndex,
목록 상자 항목과 관련이 있는 32비트 값을 설정한다.
DWORD dwItemData );

int SetItemDataPtr
목록 상자 항목에 대한 포인터를 설정한다.
( int nIndex, void* pData );
int SetItemHeight
목록 상자에 있는 항목들의 높이를 설정한다.

LCID SetLocale
목록 상자에 대한 지역 식별자(LCID)를 설정한다.
( LCID nNewLocale );
void SetTabStops( );

BOOL SetTabStops( const int& cxEachStop );
BOOL SetTabStops( int nTabStops, LPINT rgTabStops );

int SetTopIndex
( int nIndex );

목록 상자 탭 멈춤 위치를 설정한다.

목록 상자에서 맨 먼저 보이는 항목의 색인(0을 기반으로 한 색인)을 설정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

( int nIndex, UINT cyItemHeight );

2
6

CHAPTER 6
? 다중 선택 ListBox 메소드
메소드

설명

int GetAnchorIndex( ) const;

다중 선택 목록 상자에서 현재 anchor item의 색인을 얻는다.

int GetCaretIndex( ) const;

다중 선택 목록 상자에서 포커스 직사각형을 갖는 항목의 색인을 얻는다.

int GetSelCount( ) const;

다중 선택 목록 상자에서 현재 선택된 항목의 수를 얻는다.

int GetSelItems( int nMaxItems, 현재 선택된 모든 다중 선택 목록 상자 항목들의 색인을
LPINT rgIndex ) const; 정수 배열 버퍼에 넣는다.
SelItemRange()

다중 선택 목록 상자에서 범위 내에 있는 항목들의 선택 상태를 전환한다.

int SetCaretIndex( int nIndex,
다중 선택 목록 상자에서 지정된 색인에 해당하는 항목에
BOOL bScroll = TRUE ); 포커스 직사각형을 설정한다.
int SetSel( int nIndex,
BOOL bSelect = TRUE);

다중 선택 목록 상자에서 항목의 선택 상태를 전환한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

void SetAnchorIndex
다중 선택 목록 상자에서 확장된 선택의 시작 항목을 설정한다.
( int nIndex );

2
6

CHAPTER 6
? 문자열에 해당하는 메소드
메소드

설명

int AddString( LPCTSTR lpszItem ); 문자열을 목록 상자에 추가한다.
int DeleteString( UINT nIndex );

목록 상자에서 문자열을 지운다.

int Dir( UINT attr,
현재 디렉토리에서 파일 이름을 목록 상자에 추가한다.
LPCTSTR lpszWildCard );
int FindString( int nStartAfter,
목록 상자에서 문자열을 찾는다.
LPCTSTR lpszItem ) const;
int FindStringExact( int nIndexStart,
지정된 찾는 문자열과 일치하는 첫번째 문자열을
LPCTSTR lpszFind ) const; 목록 상자에서 찾는다.

void ResetContent( );

목록 상자로부터 모든 항목들을 지운다.

int SelectString( int nStartAfter,
단일 선택 목록 상자에서 문자열을 찾아 선택한다.
LPCTSTR lpszItem );

Visual C++ Programming

(C) 1998 Sang Il Kim

int InsertString
문자열을 목록 상자의 지정된 색인에 삽입한다.
( int nIndex, LPCTSTR lpszItem ); (nIndex : -1, 리스트의 끝에 문자열 추가)

2
6

CHAPTER 6
? 가상 메소드 ( 재정의 가능)
메소드

설명

virtual int CharToItem
( UINT nKey, UINT nIndex );

이 메소드를 재정의함으로써 문자열을 가지지 않는
자신이 직접 그린 목록 상자에 대해 사용자 정의
WM_CHAR 메시지 다루기를 제공한다.

virtual int CompareItem
정렬된 자신이 직접 그린 목록 상자에서 새로운 항목의
( LPCOMPAREITEMSTRUCT
위치를 얻기 위해 MFC에 의해 호출된다.
lpCompareItemStruct );
virtual void DeleteItem
사용자가 정렬된 자신이 직접 그린 목록 상자에서
( LPDELETEITEMSTRUCT
새로운 항목을 지울 때 MFC에 의해 호출된다.
lpDeleteItemStruct );

virtual void MeasureItem
자신이 직접 그린 목록 상자가 목록 상자의 크기를
( LPMEASUREITEMSTRUCT
알아내기 위해 생성되었을 때 MFC에 의해 호출된다.
lpMeasureItemStruct );
이 메소드를 재정의함으로써 LBS_WANTKEYBOARDINPUT
virtual int VKeyToItem
스타일 비트 설정을 가지는 목록 상자에 대해 사용자 정의
( UINT nKey, UINT nIndex ); WM_KEYDOWN 메시지 다루기를 제공한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

virtual void DrawItem
자신이 직접 그린 목록 상자를 다시 그려야 할 때가
( LPDRAWITEMSTRUCT
결정되었을 때 MFC에 의해 호출된다.
lpDrawItemStruct );

2
6

CHAPTER 6
? 리스트 컨트롤(CListCtrl, 목록 보기 컨트롤)
? 텍스트와 이미지를 포함하는 리스트를 원할 경우, 리스트 컨트롤을 사용한다.
? 항목들은 0 부터 시작하는 정수 인덱스값을 갖는다.
? 리스트 컨트롤이나 트리컨트롤 모두 이미지 리스트(CImageList)라고 하는
공통 컨트롤 요소에서 생성된 그래픽 이미지를 불러온다.
? 사용자는 아이콘이나 비트맵으로 만들어진 이미지 리스트를 만들어

(C) 1998 Sang Il Kim

리스트 컨트롤에 이미지 리스트의 포인터를 넘겨준다.

Visual C++ Programming

2
7

CHAPTER 6
보기

설명

아이콘 보기

LVS_ICON 창 스타일로 지정되므로 항목들이 최대 크기의
아이콘으로 출력되며, 아래에 이름표를 가진다. 사용자가 항목을
목록 보기 창의 어떤 위치로든 옮길 수 있다.

작은 아이콘 보기

LVS_SMALLICON 창 스타일로 지정되므로 항목들이 작은 크기의
아이콘으로 출력되며, 오른쪽에 이름표를 가진다. 사용자가 항목을
목록 보기 창의 어떤 위치로든 옮길 수 있다.

목록 보기

LVS_LIST 창 스타일로 지정되므로 항목들이 작은 크기의
아이콘으로 출력되며, 오른쪽에 이름표를 가진다. 항목들이 열을
기준으로 정렬되고 고정된다. 다른 목록 보기 위치로 옭길 수 없다.

자세히 보기

LVS_REPORT 창 스타일로 지정되며, 각 줄에 하나의 항목이
출력되며, 열에 정보를 가진 채 나란히 정렬된다. 왼쪽 열에는 작은
아이콘과 이름표가 나타난다. 나머지 열에는 응용프로그램 관련
하위 항목이 들어간다. 각 열은 LVS_NOCOLUMNHEADER
창 스타일이 지정되어 있지 않으면 Win32 머리글 공통 컨트롤을
사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CListCtrl이 지원하는 네 종류의 보기

2
7

CHAPTER 6
스타일 매크로

설명

LVS_ALIGNLEFT

항목들이 아이콘 보기와 작은 아이콘 보기에서 왼쪽으로 정렬된다.

LVS_ALIGNTOP

항목들이 아이콘 보기와 작은 아이콘 보기에서 그 컨트롤의 위에서부터
왼쪽으로 정렬된다.

LVS_AUTOARRANGE

항목들이 아이콘 보기와 작은 아이콘 보기에서 자동으로 정렬된다.

LVS_EDITLABELS

항목문자가 적절한 위치에서 편집될 수 있도록 허락한다.

LVS_ICON

아이콘 보기

LVS_LIST

리스트(목록)보기

LVS_NOCOLUMNHEADER

자세히 보기에서 열 머리글이 출력되지 않는다.

LVS_NOLABELWRAP

아이콘 보기에서 항목 문자가 하나의 줄에 출력된다.

LVS_NOSCROLL

스크롤이 작동되지 않게 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CListCtrl을 위해 정의된 창 스타일

2
7

CHAPTER 6
스타일 매크로

설명

LVS_NOSORTHEADER

열 머리글이 버튼으로서의 기능을 하지 않는다.

LVS_OWNERDRAWFIXED

자세히 보기에서 원하는 때에 부모 창에게 항목을 그릴 수 있게 한다.

LVS_REPORT

자세히 보기

LVS_SHAREIMAGELISTS

이미지 목록을 다중 목록 보기 컨트롤에서 사용할 수 있게 한다.

LVS_SINGLESEL

한 번에 단 하나의 항목만이 선택될 수 있게 한다.

LVS_SMALLICON

작은 아이콘 보기

LVS_SORTASCENDING

항목 테스트를 기준으로 오름차순으로 항목들을 정렬한다.

LVS_SORTDESCENDING 항목 테스트를 기준으로 내림차순으로 항목들을 정렬한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CListCtrl을 위해 정의된 창 스타일

2
7

CHAPTER 6
스타일 매크로

설명

CCS_BOTTOM

컨트롤은 부모 창의 클라이언트 영역 바닥에 줄을 맞추며, 부모 창의
클라이언트 영역의 너비에 자신의 크기를 맞춘다.

CCS_NODIVIDER

컨트롤의 맨 위에서 두 개의 픽셀 하이라이트가 그려지는 것을 막는다.

CCS_NOHILITE

컨트롤의 맨 위에서 한 개의 픽셀 하이라이트가 그려지는 것을 막는다.

CCS_NOMOVEV

컨트롤이 WM_SIZE 메시지에 반응하여 스스로 크기를 재조정하거나
수평 방향으로 움직이도록 한다. 수직으로는 움직이지 못하게 한다.

CCS_NOPARENTALIGN

부모 창의 맨 위나 아래 바닥에 자동으로 줄이 맞춰지는 것을 막는다.

CCS_NORESIZE

컨트롤이 생성하거나 크기를 재조정할 때 지정된 너비와
높이를 사용하게 한다.

CCS_TOP

컨트롤은 부모 창의 클라이언트 영역 맨 위에 줄을 맞추며,
부모 창의 클라이언트 영역의 너비에 자신의 크기를 맞춘다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CListCtrl이 사용하는 윈도우 공통 컨트롤 창 스타일

2
7

CHAPTER 6
? 이미지 목록과 리스트 컨트롤
? 리스트 항목에서 사용하는 아이콘은 이미지 목록으로 저장된다.
?큰 아이콘 목록
LVS_ICON 목록 보기 스타일에서 사용하는 최대 크기의 아이콘 이미지를
담고 있는 이미지 목록
?작은 아이콘 목록
LVS_ICON 목록 보기 스타일을 갖지 않는 작은 크기의 아이콘 이미지를
담고 있는 이미지 목록

항목의 아이콘 옆에 나타날 수 있는 상태 이미지를 담을 수 있는 이미지 목록.
이 이미지는 보통 어떤 응용 프로그램에 특정 상태를 표시하는 데 사용한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?상태 아이콘 목록

2
7

CHAPTER 6
? 리스트 컨트롤 항목과 하위 항목
? 리스트 컨트롤은 항목의 목록을 가진다.
?아이콘
?이름표
?현재 상태

?응용 프로그램에 의해 정의된 값

? 리스트 컨트롤(CListCtrl)

(C) 1998 Sang Il Kim

? LV_ITEM 구조체
typedef struct _LV_ITEM {
UINT
mask;
// 유효한 데이터인지, 채워야 할 필요가 있는지 가리키는 비트 플래그 집합
int
iItem;
// 0에서 시작하여 번호를 매기는 인덱스를 가지는 항목
int
iSubItem; // 1에서 지작하여 번호를 매기는 인덱스를 가지는 하위항목
UINT
state;
// 항목의 현재 상태
UINT
stateMask; // 유효한 상태 멤버 비트를 지정한다.
LPSTR
pszText; // 구조가 항목 속성을 지정할 때 항목 문자를 포함하고 있는 문자열에 대한 포인터
int
cchTextMax; // pszText가 가리키고 있는 버퍼의 크기
int
iImage;
// 아이콘 보기와 작은 아이콘 이미지 목록에서 항목 아이콘의 인덱스
LPARAM lParam;
// 항목과 연관 있는 응용 프로그램에서 정의한 32비트 값
} LV_ITEM;

Visual C++ Programming

2
7

CHAPTER 6
? LV_ITEM mask 멤버에서 사용하는 비트 플래그

설명

LVIF_TEXT

pszText 멤버가 유효하다.

LVIF_IMAGE

iImage 멤버가 유효하다.

LVIF_PARAM

lParam 멤버가 유효하다.

LVIF_STATE

state 멤버가 유효하다.

LVIF_DI_SETITEM

윈도우는 요청이 있는 항목 정보를 저장해야 한다.

부모 창에게 WM_NOTIFY 통보 메시지를 보낸다.
? 이 메시지들은 리스트 컨트롤의 부모 클래스에서 메시지 핸들러를 씀으로써
잡고 처리할 수 있다.
( DevStudio\Vc\include\Commctrl.h )
Visual C++ Programming

(C) 1998 Sang Il Kim

? 리스트 컨트롤 통보 메시지
? 대부분의 윈도우 공통 컨트롤과 마찬가지로 리스트 컨트롤은 자신의

2
7

CHAPTER 6
메시지 맵 항목

설명

LVN_BEGINDRAG

왼쪽 마우스 버튼을 포함하는 끌어서 놓기 작업이 시작된다.

LVN_BEGINLABELEDIT

이름표 편집 작업이 시작된다.

LVN_BEGINRDRAG

오른쪽 마우스 버튼을 포함하는 끌어서 놓기 작업이 시작된다.

LVN_COLUMNCLICK

열을 클릭했다.

LVN_DELETEALLITEMS

사용자가 컨트롤의 모든 항목을 지웠다.

LVN_DELETEITEM

사용자가 컨트롤의 한 항목을 지웠다.

LVN_ENDLABELEDIT

이름표 편집 작업이 끝난다.

LVN_GETDISPINFO

목록 보기 항목을 출력하거나 정렬할 때 필요한 정보를 제공해 달라는
부모 창의 요청

LVN_INSERTITEM

새로운 항목을 삽입했다.

LVN_ITEMCHANGED

항목을 변경했다.

LVN_ITEMCHANGING

항목을 변경하고 있다.

LVN_KEYDOWN

키를 눌렀다.

LVN_PEN

펜 윈도우(펜과 디지타이저 타블렛을 가진 시스템)에서 사용된다.

LVN_SETDISPINFO

부모 창에게 항목에 대한 출력 정보를 갱신하게 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 리스트 컨트롤을 위해 정의된 통보 메시지

2
7

CHAPTER 6
? 리스트 컨트롤 사용하기
1. 이미지 목록 붙이기
2. 자세히 보기를 위한 열 추가하기
3. CListCtrl 객체에 항목 추가하기
4. WM_NOTIFY 메시지를 처리하기 위해 상속한 OnChildNotify() 메소드
재정의하기
? 이미지 목록 붙이기
? 생성하는 리스트 컨트롤이 LVS_ICON 스타일을 사용하면, 리스트 항목에
대한 이미지 목록을 필요로 한다.
? 출력할 리스트에 대한 이미지 목록을 생성하기 위해서는
? 컨트롤에서 사용하는 모든 이미지 목록에 대한 CListCtrl::SetImageList()
를 호출한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

CImageList 클래스를 사용한다.

2
7

CHAPTER 6
? 자세히 보기를 위한 열 추가하기
? 보통 사용자에게 열의 크기를 재조정할 수 있게 하기 위해 머리글 공통
컨트롤(CHeaderCtrl)을 사용한다.
1. LV_COLUMN 구조를 초기화
2. InsertColumn() 메소드를 호출하여 원하는 각 열을 생성

(C) 1998 Sang Il Kim

? LV_COLUMN 구조
typedef struct _LV_COLUMN {
UINT mask;
// 유효한 데이터 멤버를 지정한다.
int
fmt; // 열 정렬 식별자(LVCFMT_CENTER, LVCFMT_LEFT, LVCFMT_RIGHT)
int
cx;
// 열의 너비(단위 : 픽셀)
LPTSTR pszText;
// 열 머리글 문자열에 대한 포인터
int
cchTextMax; // pszText가 가리키는 문자 수
int
iSubItem;
// 하위 항목의 인덱스
} LV_COLUMN;
Visual C++ Programming

2
8

CHAPTER 6

설명

LVCF_FMT

fmt 멤버가 유효하다.

LVCF_SUBITEM

iSubItem 멤버가 유효하다.

LVCF_TEXT

pszText 멤버가 유효하다.

LVCF_WIDTH

cx 멤버가 유효하다.

(C) 1998 Sang Il Kim

? LV_COLUMN mask 멤버의 가능한 값

Visual C++ Programming

2
8

CHAPTER 6
? 리스트 컨트롤 클래스 메소드
메소드

설명

CImageList* SetImageList
리스트 뷰 컨트롤에 이미지 리스트를 할당한다.
( CImageList* pImageList, int nImageList);
CImageList* GetImageList
리스트 뷰 아이템에 그려진 이미지 리스트의
( int nImageList ) const; 핸들값을 리턴한다.
int GetItemCount();

리스트 뷰 컨트롤의 아이템 개수를 리턴한다.

BOOL SetColumnWidth( int nCol, int cx);

컬럼의 너비를 설정한다.

int GetItemText( int nItem, int nSubItem,
LPTSTR lpszText, int nLen ) const;
현재 선택한 아이템의 텍스트를 리턴한다.
CString GetItemText
( int nItem, int nSubItem) const;
Visual C++ Programming

(C) 1998 Sang Il Kim

BOOL SetColumn
리스트 뷰 컨트롤의 컬럼 속성을 설정한다.
( int nCol, const LV_COLUMN* pColumn);

2
8

CHAPTER 6
? 리스트 뷰 컨트롤의 Operation
설명

InsertItem

리스트 뷰 컨트롤에 아이템을 추가한다.

DeleteItem

컨트롤의 아이템을 제거한다.

DeleteAllItem

컨트롤의 모든 아이템을 제거한다.

FindItem

특정한 문자를 포함하는 아이템을 찾는다.

SortItems

어플리케이션에서 정의된 비교함수를 사용하여 정렬한다.

Scroll

리스트 뷰 컨트롤을 스크롤한다.

RedrawItems

리스트 뷰 컨트롤의 아이템을 다시 그린다.

Update

컨트롤이 특정한 아이템을 다시 그리도록 한다.

Arrange

그리드에 아이템을 배치한다.

InsertColumn

리스트 뷰 컨트롤에 새로운 컬럼을 추가한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

Operation

2
8

CHAPTER 6
? 트리 컨트롤(CTreeCtrl)
? 리스트 뷰 컨트롤이나 트리 컨트롤 모두 같은 이미지 리스트를 사용하고
같은 공지 메시지를 공유하지만, 아이템을 식별하는 방법은 다르다.
트리 컨트롤은 정수 인덱스를 사용하는 대신에 HTREEITEM 핸들을 사용
한다. 아이템을 추가하기 위해서는 InsertItem() 을 사용한다. 그러나 우선
아이템을 식별하는 TV_INSERTSTRUCT 구조체를 만들어야 한다.
? TV_INSERTSTRUCT 구조체
typedef struct _TV_INSERTSTRUCT {
HTREEITEM hParent;
TV_ITEM

(C) 1998 Sang Il Kim

HTREEITEM hInsertAfter;
item;

} TV_INSERTSTRUCT;
Visual C++ Programming

2
8

CHAPTER 6
? 트리 컨트롤(CTreeCtrl)
? TV_ITEM 구조체
typedef struct _TV_ITEM {
UINT

mask;

UINT

state;

UINT

stateMask;

LPSTR

pszText;

int

cchTextMax;

int

iImage;

int

iSelectedImage;

int

cChildren;

LPARAM

lParam;

(C) 1998 Sang Il Kim

HTREEITEM hItem;

} TV_ITEM;
Visual C++ Programming

2
8

CHAPTER 6
? 트리 컨트롤(CTreeCtrl)을 위해 정의된 창 스타일

스타일 매크로

설명

TVS_HASLINES

자식 항목은 그들을 대응되는 부모 항목과 연결하는 선을 가지고 있다.

TVS_LINESATROOT

자식 항목은 그들을 트리의 루트에 연결하는 선을 가지고 있다.

TVS_HASBUTTONS

트리는 각각의 부모 항목 왼편에 단추를 가진다.

TVS_EDITLABELS

트리 보기 항목 이름표는 편집할 수 없다.

TVS_SHOWSELALWAYS

선택된 항목은 트리 보기 항목이 입력 포커스를 잃어 버렸다
하더라도 선택된 채 남아 있을 것이다.

TVS_DISABLEDRAGDROP

트리 보기 컨트롤에게 TVN_BEGINDRAG 알림 메시지를
보내지 못하게 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

( DevStudio\Vc\include\Commctrl.h )

2
8

CHAPTER 6
? 트리 통보 메시지 ( DevStudio\Vc\include\Commctrl.h )
통보

설명

TVN_BEGINDRAG

끌어서 놓기 작업이 시작됐다.

TVN_BEGINLABELEDIT

적절한 이름표 편집을 시작했다.

TVN_BEGINRDRAG

오른쪽 마우스 버튼을 사용하여 끌어서 놓기 작업을 시작했다.

TVN_DELETEITEM

지정된 항목이 지워졌다.

TVN_ENDLABELEDIT 적절한 이름표 편집이 끝났다.

TVN_ITEMEXPANDED

부모 항목의 자식 항목 목록이 확장되거나 없어졌다.

TVN_ITEMEXPANDING

부모 항목의 자식 항목 목록이 확장되거나 없어지려고 한다.

TVN_KEYDOWN

키를 아래로 눌렀다.

TVN_SELCHANGED 현재 선택이 한 항목에서 다른 항목으로 변경되었다.
TVN_SELCHANGING 선택이 한 항목에서 다른 항목으로 변경되려고 한다.

TVN_SETDISPINFO 항목에 유지되는 정보를 갱신한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

TVN_GETDISPINFO 트리 컨트롤이 항목을 출력하기 위해 필요로 하는 정보를 얻는다.

2
8

CHAPTER 6
? 트리 컨트롤 (CTreeCtrl) 클래스 메소드
메소드

설명

CImageList* SetImageList( CImageList*
트리 뷰 컨트롤에 이미지 리스트를 할당한다.
pImageList, int nImageListType );
CImageList* GetImageList
( UINT nImage );

트리 뷰 아이템에 그려진 이미지리스트의
핸들값을 리턴한다.

HTREEITEM GetSelectedItem();

선택한 아이템의 핸들값을 리턴한다.

BOOL SetItem( TV_ITEM* pItem );
트리 뷰의 아이템을 설정한다.

(C) 1998 Sang Il Kim

BOOL SetItem( HTREEITEM hItem,
UINT nMask, LPCTSTR lpszItem,
int nImage, int nSelectedImage,
UINT nState, UINT nStateMask,
LPARAM lParam );

UINT GetItemState( HTREEITEM hItem,
아이템의 상대값을 리턴한다.
UINT nStateMask ) const;
CString GetItemText
아이템의 텍스트를 리턴한다.
( HTREEITEM hItem) const;
Visual C++ Programming

2
8

CHAPTER 6

매개변수

설명

dwStyle

그 컨트롤에 대한 창 스타일을 설정한다. 이것은 일반적인
창 스타일과 트리 스타일의 어떠한 조합도 가능하다.

rect

컨트롤의 크기와 위치를 지정하는 직사각형

nParentWnd

그 컨트롤의 부모 창에 대한 포인터

nID

트리 보기 컨트롤과 통신하기 위해 부모 창에서 사용하는 컨트롤 ID

Visual C++ Programming

(C) 1998 Sang Il Kim

? CTreeCtrl

2
8

CHAPTER 6
? 아이콘(Icon)
? Small Icon : 16 x 16 픽셀
? Large Icon : 32 x 32 픽셀
? 각 아이콘 마다 두 개의 분리된 비트맵이 있다.
? 색상 이미지를 위한 비트맵 : 픽셀당 4비트
? 마스크(mask)를 위한 모노크롬 비트맵 : 픽셀당 1비트
?마스크 비트 0(FALSE) : 불투명한(opaque) 색
?마스크 비트 1(TRUE) : 이미지 색상 : 검정색(0) - 투명

(C) 1998 Sang Il Kim

이미지 색상 : 흰색(0xF) - 픽셀 위치에 배경 색상이 반전

Visual C++ Programming

2
9

CHAPTER 6
? CWnd::GetDlgItem
? 지정한 자식 윈도우 포인터나 핸들을 리턴한다.
? 보통 이 함수는 다이얼로그에 있는 컨트롤을 얻는데 사용된다.
? CWnd* GetDlgItem(int nID) const;
void CWnd::GetDlgItem(int nID, HWND* phWnd) const;
? Return value
?첫번째 형식의 함수는 지정 자식 윈도우에 대한 포인터를 리턴하거나
자식 윈도우가 존재하지 않으면 NULL
?nID

얻을 자식 윈도우 또는 컨트롤의 ID

?phWnd

지정 자식 윈도우 핸들로 채워지는 HWND에 대한 포인터

Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters

2
9

CHAPTER 6

? CListBox::InsertString
? 그 위치에 있는 현재 항목과 그 아래에 있는 다른 항목들을 아래로 이동하여
주어진 인덱스에 새로운 항목을 삽입한다.
? 이런 방식으로 문자열을 삽입하는 것은 LBS_SORT 스타일이 설정되어 있으면
다른 분류 옵션을 중복시킨다.
? int InsertString( int nIndex, LPCTSTR lpszItem );
? Return Value
성공하면 새로 삽입된 항목의 인덱스, 아니면 LB_ERR 또는 LB_ERRSPACE
? Parameters
?nIndex
새로운 문자열이 있는 인덱스
-1 : 리스트의 끝에 문자열이 추가된다.
?lpszItem 리스트박스에 삽입되는 null로 끝나는 문자열
Visual C++ Programming

(C) 1998 Sang Il Kim

? CComboBox::InsertString
? 그 위치에 있는 현재 항목을 아래로 이동하고 주어진 인덱스에 새로운 항목을 삽입한다.
? 이런 방식으로 문자열을 삽입하는 것은 CBS_SORT 스타일이 설정되어 있으면
다른 분류 옵션을 중복시킨다.
? int InsertString( int nIndex, LPCTSTR lpszString );
? Parameters
?nIndex
새로운 문자열이 있는 인덱스
-1 : 리스트의 끝에 문자열이 추가된다.
?lpszString 콤보박스에 삽입되는 null로 끝나는 문자열

2
9

CHAPTER 6
? CWnd::SetScrollRange
? 특정 스크롤바의 스크롤 범위를 설정한다.
? void SetScrollRange( int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE );
? Parameters
?nBar
SB_HORZ 수평 스크롤바를 변경
SB_VERT

수직 스크롤바를 변경

?nMinPos

최소로 가능한 스크롤 값

?nMaxPos

최대로 가능한 스크롤 값

?bRedraw

스크롤바를 다시 그려야 한다면 TRUE, 그렇지 않으면 FALSE

? void SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw = TRUE );
? Parameters
?nMinPos
최소 스크롤바 위치
?nMaxPos

최대 스크롤바 위치

?bRedraw

스크롤바를 다시 그려야 한다면 TRUE, 그렇지 않으면 FALSE
Visual C++ Programming

(C) 1998 Sang Il Kim

? CScrollBar::SetScrollRange

2
9

CHAPTER 6
? CDialog::DoModal
? 모달 형식으로 다이얼로그를 표시하기 위하여 DoModal 멤버함수를 호출
? virtual int DoModal( );
? Return vlaue
다이얼로그 윈도우가 생성될 수 없으면 -1,
에러가 발생하면 IDABORT이거나 성공하면 EndDialog에 전달되는 값.
?EndDialog에 전달되는 값
취소 버튼 : IDCANCEL, 확인 버튼 : IDOK
? CDialog::OnOK
? 확인(OK) 버튼을 누를 때 호출된다.
? 이 함수의 기본적인 클래스의 구현은 데이터 교환과 확인을 수행하고 IDOK의
? OnOK는 모달 다이얼로그에서만 사용된다.
? 모덜리스 다이얼로그에서 확인 버튼을 넣으려면, 이 함수를 중복하고 그 내에서
DestroyWindow를 호출해야 한다.
? virtual void OnOK( );
Visual C++ Programming

(C) 1998 Sang Il Kim

파라미터로 EndDialog를 호출하여 다이얼로그를 파괴한다.

2
9

CHAPTER 6
? CDialog::OnCancel
? 취소 버튼(IDCANCEL)을 누를 때 호출된다.
? 이 함수의 기본적인 클래스의 구현은 IDCANCEL의 파라미터로 EndDialog를
호출하여 다이얼로그를 파괴한다.
? OnCancel은 모달 다이얼로그에서만 사용된다.
? 모덜리스 다이얼로그에서 취소 버튼을 넣으려면, 이 함수를 중복하고

? CDialog::EndDialog
? 모달 다이얼로그를 파괴하기 위하여 호출된다.
? EndDialog는 다이얼로그를 즉시 파괴하지 않고, 현 메시지 핸들러가 완료된
다음에 파괴하기 위하여 플래그를 설정한다.
? EndDialog는 CDialog객체를 삭제하지 않고, 단순히 관련된 윈도우를 파괴한다.
? virtual EndDialog( int nResult );
? Parameters
?nResult 다이얼로그를 표시하는 데 호출되는 DoModal 함수에 의해
리턴되는 정수
Visual C++ Programming

(C) 1998 Sang Il Kim

그 내에서 DestroyWindow를 호출해야 한다.
? virtual void OnCancel();

2
9

CHAPTER 6
? CWnd::DoDataExchange
? 다이얼로그의 컨트롤과 데이터를 교환
? virtual void DoDataExchange( CDataExchange* pDX);
? Parameters
?pDX
CDataExchange 객체에 대한 포인터
? 지정 스크롤바의 현재 위치를 얻는다.
? 현재 위치는 스크롤바의 현재 스크롤 범위에 따른 상대적인 값이다.
? int GetScrollPos( int nBar ) const;
? Parameters
?nBar 스크롤바의 현재 위치
SB_HORZ 수평 스크롤바의 현재 위치를 얻는다.
SB_VERT 수직 스크롤바의 현재 위치를 얻는다.
? CScrollBar::GetScrollPos
? 스크롤바의 현재 위치를 얻는다.
? int GetScrollPos( ) const;
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::GetScrollPos

2
9

CHAPTER 6
? CScrollBar::SetScrollPos
? 스크롤바의 현재 위치를 설정한다.
? int SetScrollPos( int nPos, BOOL bRedraw = TRUE );
? Parameters
?nPos
스크롤 박스의 새로운 위치
?bRedraw TRUE는 새로운 위치를 반영하기 위하여 자동으로 스크롤바를
다시 그리게 한다.
FALSE는 스크롤바 디스플레이를 갱신하지 않는다.
? CScrollBar::GetScrollRange
? 현재 스크롤바 범위를 리턴한다.
(C) 1998 Sang Il Kim

? void GetScrollRange( LPINT lpMinPos, LPINT lpMaxPos ) const;
? Parameters
?lpMinPos
최소 스크롤바 위치를 받는 정수의 주소
?lpMaxPos 최대 스크롤바 위치를 받는 정수의 주소
Visual C++ Programming

2
9

CHAPTER 6
? CDC::SetBkColor
? 디바이스 컨텍스트의 현재 배경 색상을 기술한 RGB 색상 값으로 설정한다.
? virtual COLORREF SetBkColor( COLORREF crColor );
? Parameters
?crColor
새로운 배경 색상의 RGB 값
? CImageList::SetBkColor
? 이미지를 칠할 때 사용되는 배경 색상을 설정한다.
? COLORREF SetBkColor( COLORREF cr );
? Parameters
?cr
배경 색상

(C) 1998 Sang Il Kim

? CListCtrl::SetBkColor
? 컨트롤의 현재 배경 색상을 설정한다.
? BOOL SetBkColor( COLORREF cr );
? Parameters
?cr
배경 색상을 기술하는 값
Visual C++ Programming

2
9

CHAPTER 6
? CDC::GetBkColor
? 디바이스 컨텍스트에 대한 현재 배경의 RGB 값을 얻는다.
? COLORREF GetBkColor( ) const;
? CImageList::GetBkColor
? 이미지를 칠하는 데 사용되는 현재 배경을 얻는다.
? COLORREF GetBkColor( ) const;
? CListCtrl::GetBkColor
(C) 1998 Sang Il Kim

? 컨트롤의 현재 배경 색상을 얻는다.
? COLORREF GetBkColor( ) const;

Visual C++ Programming

2
9

CHAPTER 6
? CWnd::OnCtlColor
? WM_CTLCOLOR 메시지에 대한 핸들러 함수
? 이 메시지는 컨트롤의 배경을 칠할 때 사용되는 브러시를 얻기 위하여 보통
자식 컨트롤에 의해 부모에 전달된다.
? afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor);
? Parameters
?pDC

컨트롤을 그리는데 사용되는 디바이스 컨텍스트에 대한 포인터

?pWnd

컨트롤에 대한 포인터
버튼 컨트롤
다이얼로그 박스
편집 컨트롤
리스트 박스 컨트롤
메시지 박스
스크롤바 컨트롤
정적 컨트롤

(C) 1998 Sang Il Kim

?nCtlColor 컨트롤의 타입
CTLCOLOR_BTN
CTLCOLOR_DLG
CTLCOLOR_EDIT
CTLCOLOR_LISTBOX
CTLCOLOR_MSGBOX
CTLCOLOR_SCROLLBAR
CTLCOLOR_STATIC

Visual C++ Programming

3
0

CHAPTER 6
? CWnd::SetDlgItemText
? 특정 자식 윈도우의 윈도우 텍스트를 특정 텍스트 문자열로 설정한다.
? void SetDlgItemtext( int nID, LPCTSTR lpszString );
? Parameters
?nID
윈도우 텍스트가 설정되는 자식 윈도우 ID
?lpszString 새로운 윈도우 텍스트를 포함하는 null로 끝나는 문자열 버퍼에
대한 포인터
? CWnd::SetWindowText

? void SetWindowText( LPCTSTR lpszString );
? Parameters
?lpszString

새로운 윈도우 텍스트로 사용되는 null로 끝나는 문자열에
대한 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

? 윈도우에 텍스트를 설정한다.
? 윈도우의 캡션(제목) 바에 윈도우 텍스트를 표시한다.

3
0

CHAPTER 6

? CWinApp::LoadIcon
? 아이콘 리소스를 로드한다.
? HICON LoadIcon( LPCTSTR lpszResourceName ) const;
? HICON LoadIcon( UINT nIDResource ) const;
? Parameters
?lpszResourceName
MAKEINTRESOURCE 매크로를 사용하면
발생되는 아이콘 리소스의 이름
?nIDResource
아이콘에 대한 리소스 ID
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::GetWindowText
? 현재 윈도우 캡션(제목)의 텍스트를 얻는다.
? int GetWindowText( LPCTSTR lpszStringBuf, int nMaxCount ) const;
? void GetWindowText( CString& rString ) const;
? Parameters
?lpszStringBuf
null로 끝나는 윈도우에 있는 문자 버퍼에 대한 포인터
?nMaxCount
lpszStringBuf에 의해 가리키는 버퍼의 크기
?rString
윈도우 텍스트로 채워지는 CString에 대한 참조

3
0

CHAPTER 6
? CListCtrl::SetImageList
? 컨트롤에 항목을 표시하는 데 사용되는 이미지 리스트를 설정한다.
? CImageList* SetImageList( CImageList* pImageList, int nImageList );
? Parameters
?pImageList 새로운 이미지 리스트
?nImageList 이미지 리스트 타입
LVSIL_NORMAL 큰 이미지를 포함하는 이미지 리스트
LVSIL_SMALL
작은 이미지를 포함하는 이미지 리스트
LVSIL_STATE
상태 이미지를 포함하는 이미지 리스트

(C) 1998 Sang Il Kim

? CListCtrl::GetItemText
? 항목이나 관련 서브 항목으로부터 기술한 텍스트를 얻는다.
? int GetItemText( int nItem, int nSubItem, LPTSTR lpszText,
int nLen ) const;
? CString GetItemText( int nItem, int nSubItem ) const;
? Parameters
?nItem
항목의 인덱스
?nSubItem 얻는 텍스트의 서브 항목의 인덱스
?lpszText 항목 텍스트를 받는 버퍼의 주소
?nLen
lpszText에 의해 기술되는 텍스트 버퍼의 길이
Visual C++ Programming

3
0

CHAPTER 6
? CListCtrl::InsertItem - 새로운 항목을 컨트롤에 삽입한다.
? int InsertItem( const LV_ITEM* pItem );
? int InsertItem( int nItem, LPCTSTR lpszItem );
? int InsertItem( int nItem, LPCTSTR lpszItem, int nImage );
? int InsertItem( UINT nMask, int nItem, LPCTSTR lpszItem,
UINT nState, UINT nStateMask, int nImage, LPARAM lParam );
새로운 항목을 기술하는 LV_ITEM 구조체에 대한 포인터
항목이 삽입되는 곳의 인덱스
새로운 항목의 라벨을 포함하는 문자열에 대한 포인터
새로운 항목의 이미지의 인덱스나 항목이 콜백 항목이면
I_IMAGECALLBACK
?nMask
어느 속성이 설정되는가를 나타내는 마스크 플래그
?nState
항목 상태 플래그
?nStateMask 어느 nState비트가 설정되는가를 나타내는 마스크 플래그
?nImage
이미지 리스트에 있는 항목의 이미지 인덱스
?lParam
이 항목에 관련되는 프로그래머가 제공하는 32비트 데이터
Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?pItem
?nItem
?lpszItem
?nImage

3
0

CHAPTER 6
EX06B

Dialog
Static
Static
Trackbar
Static
Static
Trackbar
Static
Static
Edit

Property
ID
Caption
ID
Caption
ID
Caption
Style/Point
ID
Caption
ID
Caption
Style/Point
ID
Caption
ID
Caption
ID
Style

Setting
IDD_DIALOG1
Windows Common Controls Dialog
IDC_STATIC
Progress
IDC_STATIC
Trackbar 1
Bottom/Right
IDC_STATIC_TRACK1
Static
IDC_STATIC
Trackbar 2
Bottom/Right
Tick marks, Auto ticks
IDC_STATIC_TRACK2
Static
IDC_STATIC
Buddy
IDC_BUDDY_SPIN1
Read-only
Visual C++ Programming

(C) 1998 Sang Il Kim

Object

3
0

CHAPTER 6
EX06B

Spin
Static
Static
List Control

Property
Style
ID
Caption
ID
Caption
ID
Style

Style/View
More Styles
Static
ID
Caption
Static
ID
Caption
Tree Control ID
Style
Static

ID
Caption

Setting
Auto buddy
IDC_STATIC
Spin
IDC_STATIC
List Control
IDC_LISTVIEW1
Single selection
Show selection always
List
Border
IDC_STATIC_LISTVIEW1
Current Selection
IDC_STATIC
Tree Control
IDC_TREEVIEW1
Has buttons, Has lines
Lines at root, Border
IDC_STATIC_TREEVIEW1
Current Selection
Visual C++ Programming

(C) 1998 Sang Il Kim

Object

3
0

CHAPTER 7

(C) 1998 Sang Il Kim

모덜리스 다이얼로그와
윈도우 공통 다이얼로그

Visual C++ Programming

3
0

CHAPTER 7
? 공통 다이얼로그
? CFileDialog, CFontDialog, CColorDialog, CPrintDialog
? 이 클래스들은 COMDLG32.DLL 이 지원한다.
? 모덜리스 다이얼로그
? 모달 다이얼로그와 모덜리스 다이얼로그는 동일한 기초 클래스 CDialog 에서
파생된다.

사용되는 생성자

모달 다이얼로그

모덜리스 다이얼로그

리소스 템플릿 ID를
파라미터로 하는 생성자

디폴트 생성자
(파라미터 없음)

윈도우를 만들기 위해
CDialog::DoModal()
사용되는 함수

CDialog::Create()
(리소스 템플릿 ID를
파라미터로 함)
Visual C++ Programming

(C) 1998 Sang Il Kim

? 모덜리스 다이얼로그 생성하기

3
0

CHAPTER 7
? 사용자 정의메시지
? 다이얼로그는 뷰클래스의 멤버함수를 곧바로 부를 수 있지만, 이 경우에는
다이얼로그와 뷰를 반드시 연결해야만 한다. 그러나 보다 나은 방법은
? 사용자가 메시지를 만들어 뷰에 보내고, 뷰 클래스에서 이 메시지를 받아
해당 처리를 하도록 한다.
CWnd::SendMessage()
CWnd::PostMessage()

보낸 메시지의 처리가 모두 된 후에야
비로소 리턴
메시지 큐에 메시지를 추가하고 바로 리턴하여
다음 코드를 수행

? 다이얼로그를 팝업(Pop-up) 스타일로 설정했다면, 다이얼로그는 뷰의 클라
이언트 영역으로 제한되지 않는다.
? 다이얼로그의 오너(Owner)는 뷰 윈도우가 아니라 어플리케이션의
메인프레임 윈도우이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 다이얼로그 소유권(Ownership)

3
0

CHAPTER 7
? SendMessage()와 PostMessage()의 차이점
? A윈도우 (메시지를 보내는 윈도우)
① pW->SendMessage(WM_MYMSG, 0, 0);
AfxMessageBox(“전송완료 1”);
② pW->PostMessage(WM_MYMSG, 0, 0);
AfxMessageBox(“전송완료 2”);
? B윈도우 (메시지를 받는 윈도우)
LONG CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)
return 0L;
① B윈도우에서 메시지 처리가 다 된 후에 리턴
② B윈도우에서 메시지 처리와는 상관없이 단지 메시지 큐에 해당 메시지만을
추가하고 바로 리턴하여 다음 코드인 AfxMessageBox(“전송완료 2”)를 수행
Visual C++ Programming

(C) 1998 Sang Il Kim

복잡한 계산 처리 루틴

3
1

CHAPTER 7

? PostMessage
? 어플리케이션의 메시지 큐에 메시지를 포스트한다.
? 메시지가 포스트될 때, 큐에 있는 이미 다른 메시지들의 뒤에 넣어지고 나중
어느 시점에서 어플리케이션에서 받게 된다.
? PostMessage는 메시지가 처리되는 것을 기다리지 않는다.
? BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0);
? Parameters
?message
포스트되는 메시지
?wParam
메시지 특정 부가 정보
?lParam
메시지 특정 부가 정보
Visual C++ Programming

(C) 1998 Sang Il Kim

? SendMessage
? 특정 윈도우에 메시지를 보낸다.
? 보내지는 메시지는 즉시 전달된다.
? SendMessage는 그 메시지가 처리될 때까지 리턴하지 않는다.
? LRESULT SendMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0);
? Parameters
?message
보내지는 메시지
?wParam
메시지 특정 부가 정보
?lParam
메시지 특정 부가 정보

3
11

CHAPTER 7
? 모달 다이얼로그와 모덜리스 다이얼로그의 차이점
? CDialog::DoModal()로 생성된 모달 다이얼로그에서 CDialog::OnOK() 함수나
CDialog::OnCancel() 함수를 호출하면 결과적으로 CDialog::EndDialog()
함수가 호출되어 다이얼로그가 소멸된다.
? CDialog::Create()로 생성된 모덜리스 다이얼로그 경우에는 EndDialog()
대신에 DestroyWindow() 함수를 호출해서 다이얼로그 윈도우를
소멸시킨다.
? DestroyWindow() 함수를 호출해서 다이얼로그 윈도우를 소멸하는 이유
?이렇게 재정의 하지 않으면 Enter키나 ESC키를 눌렀을 경우 EndDialog()를
(C) 1998 Sang Il Kim

호출하게 된다.

Visual C++ Programming

3
1

CHAPTER 7
? 윈도우 공통 다이얼로그
클래스

목적

CColorDialog

사용자가 색상을 선택하거나 만들어낼 수 있게 한다.

CFileDialog

사용자가 파일을 열거나 저장하게 해준다.

CFindReplaceDialog 사용자가 한 문자열을 다른 문자열로 대체하게 해준다.
사용자가 페이지 번호 파라미터를 입력하게 해준다.

CFontDialog

사용자가 사용가능한 폰트의 리스트에서 하나의 폰트를
선택하게 해준다.

CPrintDialog

사용자가 프린터를 설정하고 문서 내용을 프린트하게 해준다.

(C) 1998 Sang Il Kim

CPageSetupDialog

Visual C++ Programming

3
1

CHAPTER 7
? CFileDialog 클래스 직접 사용하기
? CFileDialog dlg(TRUE, “bmp”, “*.bmp”);
if(dlg.DoModal() == IDOK) {
CFile file;
VERIFY(file.Open(dlg.GetPathName(), CFile::modeRead));
}
?첫 번째 파라미터 : TRUE(File Open

다이얼로그),

FALSE(File Save 다이얼로그)

?두 번째 파라미터 : “bmp” (디폴트 확장자)
?CFileDialog::GetPathName() : 선택된 파일의 전체 경로를 저장하는
CString 객체를 리턴한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?세 번째 파라미터 : “*.bmp” (다이얼로그 파일 이름란에 출력될 문자열)

3
1

CHAPTER 7
? 중첩(nested) 다이얼로그
? Win32는 하나의 다이얼로그를 다른 다이얼로그 내에 “중첩시키는”
방법으로 여러 다이얼로그를 마치 하나처럼 보이게 할 수 있다.
? 중첩 다이얼로그를 만들기 위해서는 일반적으로 그룹 박스 컨트롤
(차일드 윈도우 ID : stc32=0x045f)을 포함한 다이얼로그 리소스 템플릿을
만들고, 기초 클래스(CFileDialog)에서 새로운 클래스를 유도한다.
? 그리고 ClassWizard를 이용해서 템플릿의 새로운 컨트롤에 대한

(C) 1998 Sang Il Kim

메시지들을 맵핑한다.

Visual C++ Programming

3
1

CHAPTER 7
? 파일 다이얼로그 캡션바에 아이콘 추가
? BOOL CSpecialFileDialog::OnInitDialog()
{
CFileDialog::OnInitDialog();
HICON hIcon = AfxGetApp() -> LoadIcon(IDI_ICON1);
GetParent() -> SetIcon(hIcon, TRUE);

// Large Icon 설정

GetParent() -> SetIcon(hIcon, FALSE); // Small Icon 설정
return TRUE;
(C) 1998 Sang Il Kim

}

Visual C++ Programming

3
1

Object

EX07A
Dialog

Static Text
Object

EX07B
Dialog
GroupBox
Button

Property

Setting

ID

IDD_DIALOG1

Caption

Modeless Dialog

Style

Popup

Border

Dialog Frame

ID

IDC_STATIC

Caption

Edit1

Property

Setting

ID

IDD_FILESPECIAL

Style

Child

Border

None

ID

Stc32=0x045f

ID

IDC_DELETE

Caption

Delete all matching files
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 7

3
1

허물을 덮어주세요

(C) 1998 Sang Il Kim

어느 화가가 알렉산드로스 대왕의 초상화를 부탁받고
고민에 빠졌습니다.
왜냐하면 대왕의 이마에는 추하기 짝이 없는
상처가 있었기 때문입니다.
화가는 대왕의 상처를
그대로 화폭에 담고 싶지 않았습니다.
대왕의 자랑스러움에
손상을 입히고 싶지 않았기 때문입니다.
그러나 상처를 그리지 않는다면
그 초상화는 진실한 것이 되지 못하므로
화가 자신의 신망은 여지없이 땅에 떨어질 것입니다.
화가는 고민끝에 한 가지 방법을 생각해 냈습니다.
대왕이 이마에 손을 대고 쉬고 있는 모습을 그려야겠다고
생각한 것입니다.
타인의 상처를 보셨습니까?
그의 허물을 가려줄 방법을 생각해봐야 하지 않을까요?
사랑은 허다한 허물을 덮는다고 합니다.
Visual C++ Programming

3
1

CHAPTER 8

(C) 1998 Sang Il Kim

ActiveX 컨트롤 사용하기

Visual C++ Programming

3
1

CHAPTER 8
? ActiveX 컨트롤과 일반 윈도우 컨트롤
? ActiveX 컨트롤
?윈도우 컨트롤과 동일한 방식으로 C++ 프로그램에 추가할 수 있는
소프트웨어 모듈
? 일반 컨트롤
?일반 컨트롤이나 윈도우95 공통 컨트롤은 다이얼로그의 차일드 윈도우이다.
?MFC의 클래스인 CEdit 나 CTreeCtrl 과 같은 형태로 표시된다.
?클라이언트 프로그램은 이러한 컨트롤의 차일드 윈도우를 생성하는 일을
담당한다.
(C) 1998 Sang Il Kim

?일반 컨트롤은 BN_CLICKED 과 같은 통보 명령 메시지(Notification
Command Message)를 다이얼로그에 보낸다.
?만일 사용자가 에디트 컨트롤에서 텍스트를 얻으려면
CWnd::GetWindowText() 함수를 호출할 수 있다.
Visual C++ Programming

3
2

CHAPTER 8
? ActiveX 컨트롤과 일반 윈도우 컨트롤
? 윈도우 컨트롤
?별도의 DLL로 존재
? 일반 컨트롤
?“CUSTOM Control” - 프로그래머가 만드는 컨트롤
?자신의 부모 윈도우에게 WM_COMMAND 통보 메시지를 보내고

(C) 1998 Sang Il Kim

부모 윈도우로부터 사용자 정의 메시지를 받는다.

Visual C++ Programming

3
2

CHAPTER 8
? ActiveX 컨트롤과 일반 컨트롤의 유사점
? 다이얼로그에 ActiveX 컨트롤을 삽입할 경우
?다이얼로그 에디터를 이용하여 컨트롤을 삽입하면 리소스 템플릿에 ActiveX
컨트롤 식별자가 나타난다.
? 다이얼로그가 아닌 윈도우에 삽입할 경우
?부모 윈도우의 WM_CREATE 핸들러에서 ActiveX 컨트롤을 표현하는 클래
스의 Create() 멤버 함수를 호출하면 된다.
? ActiveX 컨트롤을 포함하는 윈도우를 컨테이너(container)라고 부른다.
? ActiveX 컨트롤과 일반 컨트롤의 차이점 - 속성과 메소드
? 클라이언트 프로그램에서는 지정된 인덱스로 속성을 얻을 수 있고, 고유한
리턴값을 수용한다.
? 생성된 Dialog Data Exchange(DDX) 코드는 ActiveX 컨트롤의 속성과
클라이언트 클래스의 데이터 멤버간의 데이터를 교환한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 속성(Properties) - 정수 인덱스와 대응하는 기호 이름

3
2

CHAPTER 8
? ActiveX 컨트롤과 일반 컨트롤의 차이점 - 속성과 메소드
? 메소드(Methods) - 함수와 유사하다.
기호 이름, 파라미터, 리턴값 등을 갖는다.
? 일반 컨트롤 - 컨테이너에 WM_통보 메시지를 보낸다.
? ActiveX 컨트롤 - “이벤트”를 생성한다.
?“이벤트”는 ActiveX 컨트롤이 호출하는 컨테이너 함수이다.
?“이벤트”는 ActiveX 컨트롤에 값을 리턴하지 않는다.
? ActiveX 컨트롤 설치하기
? Project 메뉴 - Add To Project 선택 - Component And Controls 선택
? ActiveX 컨트롤은 클라이언트 프로그램이 특별한 익스포트(exported)된
함수를 호출할 때 자기 자신을 등록한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

- Registered ActiveX Controls 선택 - Calendar Control 8.0 선택 - Insert

3
2

CHAPTER 8
? ActiveX 컨트롤의 ClassWizard C++ 래퍼(wrapper) 클래스
? 프로젝트에 ActiveX 컨트롤을 삽입하면 ClassWizard는 컨트롤의 메소드와
속성에 맞추어진 C++ wrapper 클래스를 생성한다.
? 이 클래스는 CWnd 클래스로부터 유도되며, 모든 속성과 메소드에 대한
멤버 함수를 갖고 있다.
? 동적으로 ActiveX 컨트롤 인스턴스를 생성하는데 사용할 수 있는 생성자를
갖는다.
? unsigned long CCalendar::GetBackColor()
unsigned long result;
InvokeHelper(DISPID_BACKCOLOR, DISPATCH_PROPERTYGET,
VT_I4, (void*)&result, NULL);
return result;
}
Visual C++ Programming

(C) 1998 Sang Il Kim

{

3
2

CHAPTER 8
? ActiveX 컨트롤에 AppWizard 지원
? AppWizard 의 Step3 - ActiveX Control 옵션 체크되면 AppWizard는
어플리케이션 클래스의 InitInstance() 멤버 함수에 다음의 라인을 추가한다.
?AfxEnableControlContainer(); // Ex08a.cpp
?#include <afxdisp.h>
// MFC OLE automation classes, StdAfx.h
? 기존 프로젝트에 ActiveX 컨트롤을 추가하려면 두 라인만 추가하면 된다.
? 다이얼로그 클래스 데이터 멤버와 래퍼(wrapper) 클래스 사용법
? CDialog::OnInitDialog()
CWnd::UpdateData(FLASE)를 호출하여 다이얼로그 클래스의 데이터 멤버값을 읽어들인다.
? CDialog::OnOK()
CWnd::UpdateData(TRUE)를 호출하여 다이얼로그 클래스의 데이터 멤버에 값을 저장한다.
얻어야 할 경우 버튼 핸들러에서 UpdateData(FALSE)를 호출하면 다이얼로그의
모든 컨트롤로부터 모든 속성값을 읽게 되어 시간을 낭비하게 된다.
? 다이얼로그 데이터 멤버의 사용을 피하고, 래퍼(wrapper) 클래스의 Get 함수를
호출하는 것이 더욱 효율적이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? ActiveX 컨트롤 속성에 데이터 멤버를 추가하고, 버튼 핸들러에서 Value 속성값을

3
2

CHAPTER 8
? ClassWizard 와 컨테이너 다이얼로그
? 템플릿에 한 개 이상의 ActiveX 컨트롤이 포함되면 ClassWizard를 이용해서
데이터 멤버와 이벤트 핸들러 함수를 추가할 수 있다.
? 다이얼로그 함수 내에서 속성을 변경할 경우
?ActiveX 컨트롤을 위한 래퍼(wrapper) 클래스의 객체를 데이터 멤버로 추가해야 한다.
?Calendar 컨트롤의 래퍼(wrapper) 클래스로 CCalendar 클래스가 있고, 다이얼로그
클래스에 m_calendar 데이터 멤버가 있을 경우 Value 속성값을 얻는 방법

(C) 1998 Sang Il Kim

COleVariant var = m_calendar.GetValue();

Visual C++ Programming

3
2

CHAPTER 8
? ClassWizard 와 컨테이너 다이얼로그
? DDX_OCShort(pDX, ID_CALENDAR1, 0x11, m_sCalDay);
? 다이얼로그를 생성하여 출력
CMyDialog dlg;
dlg.m_sCalDay = 5;
dlg.DoModal();

Day 속성의
정수 인덱스
(디스패치ID)

? DDX 코드는 컨트롤이 출력되기 전에 멤버 함수로부터 속성값을 설정하는
일을 담당한다.
? DDX 코드는 사용자가 OK 버튼을 클릭할 때 속성값으로부터 데이터 멤버를 설정한다.
? Visual C++ 5.0의 버그로 인해 ClassWizard는 Calendar컨트롤을 포함한 많은
컨트롤들의 속성을 정확히 감지하지 못한다.
생성할 수 없다. 특히 Calendar의 Value 속성과 같은 VARIANT 형 속성에 대해서는
DDX 함수가 존재하지 않는다. 이런 속성에 대해서는 래퍼(wrapper) 클래스를
사용해야 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? ClassWizard가 컨트롤의 속성을 정확히 탐지해도 모든 속성에 대해 데이터 멤버를

3
2

CHAPTER 8
? CWnd::GetSafeHwnd
? CWnd 객체와 현재 관련된 윈도우 핸들을 리턴한다.
? NULL CWnd 를 호출한다 해도 안전(safe) 하기 때문에 GetSafeHwnd 라 부른다.

(C) 1998 Sang Il Kim

? HWND GetSafeHwnd( ) const;
? Return Value
?CWnd 객체와 현재 관련된 윈도우 핸들
?CWnd가 NULL이거나 윈도우에 관련된 핸들이 없으면 NULL

Visual C++ Programming

3
2

CHAPTER 8
? DDX_Text : 편집박스에 데이터를 교환하는 데 사용된다.
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*
void AFXAPI DDX_Text( CDataExchange*

pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int
pDX, int

nIDC, BYTE& value );
nIDC, short& value );
nIDC, int& value );
nIDC, UINT& value );
nIDC, long& value );
nIDC, DWORD& value );
nIDC, CString& value );
nIDC, float& value );
nIDC, double& value );
nIDC, COleCurrency& value );
nIDC, COleDateTime& value );

? Parameters
?pDX CDataExchange(데이터 교환) 객체의 포인터.
?nIDC 교환이나 확인이 발생하는 컨트롤의 리소스 ID
?value 컨트롤에 입력된 데이터 (dialog box, form view, or control view)

Visual C++ Programming

(C) 1998 Sang Il Kim

?
?
?
?
?
?
?
?
?
?
?

3
2

CHAPTER 8

? DDX 전역함수
함수

설명

DDX_CBIndex()

콤보 박스 컨트롤과 INT 데이터 멤버 사이의 INT 데이터의 흐름을 관리한다.

DDX_CBString()

콤보 박스의 편집 컨트롤과 CString 데이터 멤버 사이의
CString 데이터의 흐름을 관리한다.

DDX_Check()

체크 박스 컨트롤과 INT 데어터 멤버 사이의 INT 데이터의 흐름을 관리한다.

DDX_Control()

서브클래스 컨트롤과 CWnd 데이터 멤버 사이의 데이터 흐름을 관리한다.

DDX_LBString()
DDX_LBStringExact()

DDX_Radio()
DDX_Scroll()
DDX_Text()

목록 상자 컨트롤과 INT 데이터 멤버 사이의 INT 데이터의
흐름을 관리한다.
목록 상자의 편집 컨트롤과 CString 데이터 멤버 사이의
CString 데이터의 흐름을 관리한다.
목록 상자의 편집 컨트롤과 대화상자, 폼 View, Control View 객체의
CString 데이터 멤버 사이의 CString 데이터의 흐름을 관리한다.
라디오 컨트롤 그룹과 INT 데이터 멤버 사이의 INT 데이터의
흐름을 관리한다.
이동 표시줄 컨트롤과 INT 데이터 멤버 사이의 INT 데이터의
흐름을 관리한다.
편집 컨트롤과 CString 데이터 멤버 사이의 INT, UINT, LONG,
DWORD, CString , FLOAT, DOUBLE 데이터의 흐름을 관리한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

DDX_LBIndex()

3
3

CHAPTER 8
? DDV (데이터 유효성 검사, Dialog Data Validation)
? 이 함수들은 전형적으로 유효성 검사시 일어난 문제점을 알리는 메시지 상자를
나타내고, 문제가 일어난 컨트롤에 포커스를 맞춘다.
? 사용자가 입력한 데이터가 유효하지 않거나 받아들일 수 있는 범위를 벗어났을 때
예외를 발생시킨다.
? 컨트롤의 DDV 함수의 호출은 DDX 함수를 호출한 후에 일어나야 한다.
메소드

설명

DDV_MaxChars()

특정 값의 매개 변수와 연결된 컨트롤에서 문자의 개수가 지정된 값을
초과하지 않았는지를 확인한다.

DDV_MinMaxByte()

컨트롤의 BYTE 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxDouble()

컨트롤의 DOUBLE 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxFloat()

컨트롤의 FLOAT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxInt()

컨트롤의 INT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxLong()

컨트롤의 LONG 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxUnsigned() 컨트롤의 UINT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

DDV_MinMaxDWord() 컨트롤의 DWORD 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

3
3

CHAPTER 8
? CDataExchange 클래스
? CDataExchange 객체의 포인터 ( CDataExchange* pDX )가 DDX 와 DDV에 필요한
컨텍스트 정보를 제공한다.

메소드

설명

Fail()

DDV의 유효성 검사가 실패했을 때 호출된다. 입력 포커스는 전단계의
활성화된 컨트롤에 위치하고 예외가 발생된다.

PrepareCtrl()

DDX나 DDV를 위해 컨트롤(편집 컨트롤 제외)을 준비한다.

PrepareEditCtrl()

DDX나 DDV를 위한 특정 편집 컨트롤을 준비한다.

? CDataExchange가 제공하는 두 개의 전역 데이터 멤버
?m_bSaveAndValidate : DDX와 DDV의 방향을 결정하는 BOOL Flag
Flag - FALSE : DDX를 데이터 멤버 값으로 대화 컨트롤을 초기화하는데 사용한다.
TRUE : DDV를 데이터 값을 검증하고 대화 컨트롤 값으로부터 데이터 멤버값을
설정하는데 사용한다.
?m_pDlgWnd : 데이터 교환이 일어나는 대화 상자나 창의 포인터.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CDataExchange 전역함수

3
3

CHAPTER 8
? DDX_OCColor

? void AFXAPI DDX_OCColor( CDataExchange* pDX, int nIDC,
DISPID dispid, OLE_COLOR& value );
? Parameters
?pDX
데이터 교환 객체에 대한 포인터
?nIDC
연결하는 컨트롤의 리소스 ID
?dispid
컨트롤 속성의 디스패치(dispatch) ID
?value
다이얼로그 박스, 폼 뷰 또는 컨트롤 뷰 객체에서 데이터가 교환되었을 때
멤버 변수에 대한 참조
? MFC 컨트롤 객체(CStatic, CEdit, CComboBox)를 윈도우 컨트롤에 연결하는 데
사용된다.
? 한번 붙으면, 클래스를 사용하여 컨트롤을 액세스하고 조정할 수 있다.
? void AFXAPI DDX_Control( CDataExchange* pDX, int nIDC,
CWnd& rControl );
? Parameters
?pDX
데이터 교환 객체에 대한 포인터
?nIDC
연결하는 컨트롤의 리소스 ID
?rControl 기술한 컨트롤에 연결되는 MFC 컨트롤 객체에 대한 참조
Visual C++ Programming

(C) 1998 Sang Il Kim

? DDX_Control

3
3

CHAPTER 8
? COleDateTime::Format
? 문자열에 대한 sprintf 함수이다.
? CString Format( DWORD dwFlags = 0, LCID lcid = LANG_USER_DEFAULT );
? CString Format( LPCTSTR lpszFormat ) const;
? CString Format( UINT nFormatID ) const;
? Parameters
Use the system default locale settings,
rather than custom user settings.
VAR_TIMEVALUEONLY
Ignore the date portion during parsing.
VAR_DATEVALUEONLY
Ignore the time portion during parsing.
?lcid
Indicates locale ID to use for the conversion.
?lpszFormat
sprintf에 전달되는 서식 문자열
%D Total days in this COleDateTime
%H Hours in the current day
%M Minutes in the current hour
%S Seconds in the current minute
%% Percent sign
?nFormatID sprintf에 전달되는 서식 문자열에 대한 문자열 리소스 ID
Visual C++ Programming

(C) 1998 Sang Il Kim

?dwFlags
LOCALE_NOUSEROVERRIDE

3
3

? Form at a time string
%a Abbreviated weekday name
%A Full weekday name
%b Abbreviated month name
%B Full month name
%c Date and time representation appropriate for locale
%d Day of month as decimal number (01 - 31)
%H Hour in 24-hour format (00 - 23)
%I Hour in 12-hour format (01 - 12)
%j Day of year as decimal number (001 - 366)
%m Month as decimal number (01 - 12)
%M Minute as decimal number (00 - 59)
%p Current locale's A.M./P.M. indicator for 12-hour clock
%S Second as decimal number (00 - 59)
%U Week of year as decimal number, with Sunday as first day of week (00 - 51)
%w Weekday as decimal number (0 - 6; Sunday is 0)
%W Week of year as decimal number, with Monday as first day of week (00 - 51)
%x Date representation for current locale
%X Time representation for current locale
%y Year without century, as decimal number (00 - 99)
%Y Year with century, as decimal number
%z, %Z Time-zone name or abbreviation; no characters if time zone is unknown
%% Percent sign

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 8

3
3

CHAPTER 8
When an embedded OLE control fires an event, the control's container receives
the event using a mechanism, called an "event sink map," supplied by MFC.
This event sink map designates handler functions for each specific event,
as well as parameters of those events. For more information on event sink maps,
see the article ActiveX Control Containers in Visual C++ Programmer's Guide.
Event Sink Maps
?BEGIN_EVENTSINK_MAP
Starts the definition of an event sink map.
?DECLARE_EVENTSINK_MAP
Declares an event sink map.
?END_EVENTSINK_MAP
Ends the definition of an event sink map.
?ON_EVENT
Defines an event handler for a specific event.
?ON_EVENT_RANGE
Defines an event handler for a specific event fired from a set of OLE controls.
?ON_EVENT_REFLECT
Receives events fired by the control before they are handled by the control's
container.
?ON_PROPNOTIFY
Defines a handler for handling property notifications from an OLE control.
?ON_PROPNOTIFY_RANGE
Defines a handler for handling property notifications from a set of OLE controls.
?ON_PROPNOTIFY_REFLECT
Receives property notifications sent by the control before they are handled by
the control's container.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Event Sink Maps

3
3

CHAPTER 8
? ON_EVENT
? ON_EVENT( theClass, id, dispid, pfnHandler, vtsParams )

?vtsParams

The class to which this event sink map belongs.
The control ID of the OLE control.
The dispatch ID of the event fired by the control.
Pointer to a member function that handles the event.
This function should have a BOOL return type, and parameter types
that match the event's parameters (see vtsParams). The function
should return TRUE to indicate the event was handled;
otherwise FALSE.
A sequence of VTS_ constants that specifies the types of the
parameters for the event. These are the same constants that are
used in dispatch map entries such as DISP_FUNCTION.

Remarks
?Use the ON_EVENT macro to define an event handler function for an event fired
by an OLE control.
?The vtsParams argument is a space-separated list of values from
the VTS_constants.
?One or more of these values separated by spaces (not commas) specifies the
function's parameter list.
?specifies a list containing a short integer followed by a BOOL.

Visual C++ Programming

(C) 1998 Sang Il Kim

Parameters
?theClass
?id
?dispid
?pfnHandler

3
3

CHAPTER 8
? EVENT_CUSTOM
? EVENT_CUSTOM( pszName, pfnFire, vtsParams )

Remarks
?Use the EVENT_CUSTOM macro to define an event-map entry for
a custom event.
?The vtsParams parameter is a space-separated list of values from
the VTS_ constants.
?One or more of these values separated by spaces (not commas)
specifies the function's parameter list.
?specifies a list containing a short integer followed by a BOOL.
Visual C++ Programming

(C) 1998 Sang Il Kim

Parameters
?pszName The name of the event.
?pfnFire
The name of the event firing function.
?vtsParams A space-separated list of one or more constants specifying
the function's parameter list.

3
3

CHAPTER 8

Symbol

Parameter Type

Symbol

Parameter Type

VTS_I2
VTS_I4
VTS_R4
VTS_R8
VTS_COLOR
VTS_CY
VTS_DATE
VTS_BSTR
VTS_DISPATCH
VTS_FONT
VTS_HANDLE
VTS_SCOPE
VTS_BOOL

short
long
float
double
OLE_COLOR
CURRENCY
DATE
const char*
LPDISPATCH
IFontDispatch*
HANDLE
SCOPE
BOOL

VTS_VARIANT
VTS_PVARIANT
VTS_UNKNOWN
VTS_OPTEXCLUSIVE
VTS_PICTURE
VTS_TRISTATE
VTS_XPOS_PIXELS
VTS_YPOS_PIXELS
VTS_XSIZE_PIXELS
VTS_YSIZE_PIXELS
VTS_XPOS_HIMETRIC
VTS_YPOS_HIMETRIC
VTS_XSIZE_HIMETRIC
VTS_YSIZE_HIMETRIC

const VARIANT*
VARIANT*
LPUNKNOWN
OLE_OPTEXCLUSIVE
IPictureDisp*
OLE_TRISTATE
OLE_XPOS_PIXELS
OLE_YPOS_PIXELS
OLE_XSIZE_PIXELS
OLE_YSIZE_PIXELS
OLE_XPOS_HIMETRIC
OLE_YPOS_HIMETRIC
OLE_XSIZE_HIMETRIC
OLE_YSIZE_HIMETRIC

Visual C++ Programming

(C) 1998 Sang Il Kim

? EVENT_CUSTOM
? The VTS_ contains and their meanings are as follows:

3
3

사랑한다는 것은

(C) 1998 Sang Il Kim

사랑한다는 것은
그런 것. 어둡고 높은 계단을 함께 오르며
시린 손을 마주잡는 것.
가난의 고독 고독의 가난
세월이 가면 나이도 먹어가지만
함께 손잡았던 기억은 사라지지 않아
사랑한다는 것은
그런 것. 비탈길 돌계단에 함께 서 있었음을
오래오래 기억하는 것.

Visual C++ Programming

3
4

CHAPTER 9

(C) 1998 Sang Il Kim

메모리관리

Visual C++ Programming

3
4

CHAPTER 9
? MFC의 메모리 관리
? 메모리 할당 - 스택 프레임(또는 스택, 또는 프레임)할당과 힙 할당 두 가지로 분류한다.

? 힙(Heap) 할당
? 프로세스가 할당하도록 예약된 메모리 영역이다.
? 힙에서 할당할 경우에는 메모리 블록에 대한 포인터를 사용한다.
? 메모리는 C나 C++의 메모리 할당 함수나 메소드, 연산자 중의 하나를 사용하여
동적으로 할당된다.
? malloc(), free() 대신에 new와 delete를 사용하면, 메모리 유출의 자동 조사 기능을
포함한 MFC 메모리 관리 디버깅 기능을 이용할 수 있다.
? 할당할 수 있는 동적 메모리의 양은 시스템 내에서 사용할 수 있는 가상 메모리의 양에
의해서만 제한된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 스택(Stack) 할당
? 함수에 대한 인수와 블록 내의 지역 변수를 갖고 있는 메모리 영역이다.
? 스택에서 할당할 경우에는 실제 메모리 블록에서 작업하게 된다.
? 컴파일러가 이들 항목에 대한 메모리를 자동으로 할당하게 되고, 함수가 호출될 때마다
스택이 만들어지게 된다.
? 스택 할당의 두 가지 주요 기능
?프레임으로부터 지역 변수의 자동 할당. 큰 배열이나 데이터 구조도 포함된다.
?자신의 범위를 벗어난 경우에는 지역 변수들이 자동으로 반납된다.

3
4

CHAPTER 9
? 메모리 관리
? 원하는 만큼의 메모리를 할당만 하면 된다.
? 세부적인 것은 윈도우가 알아서 해결한다.
? 일단, 프로그램이 실행되면 프로그램의 코드(코드 세그먼트)와
데이터(데이터 세그먼트)는 메모리상에 존재해야만 한다.
? 프로그램 인스턴스를 공유한다.
? 코드 세그먼트는 공유하고, 데이터 세그먼트는 따로 갖는다.
? 코드 세그먼트와 리소스(아이콘, 메뉴, 커서 등과 같은 윈도우가 기본적으로
제공하고 있는 자원)를 메모리에서 제거했다가, 필요한 경우에 다시 로드한다
(C) 1998 Sang Il Kim

? 분산된 유휴 메모리를 하나의 연속적인 메모리로 만든다.

Visual C++ Programming

3
4

CHAPTER 9
? 메모리의 내부
? 여러 번 실행된 어플리케이션은 하나의 코드부를 공유한다.
코드부

복사본 2
데이터부

복사본 3
데이터부

(C) 1998 Sang Il Kim

복사본 1
데이터부

Visual C++ Programming

3
4

CHAPTER 9
Free Memory

Free Memory

Notepad

Notepad

Pbrush

Free Memory

Notepad

Notepad

Write

Write

Write

Write

Windows

Windows

Windows

Windows

MS-DOS

MS-DOS

MS-DOS

MS-DOS

Pbrush를 삭제

Notepad를 이동

Free Memory

Free Memory

Q

(C) 1998 Sang Il Kim

Q를 실행

◐ 윈도우의 유휴 메모리 관리 방식 ◑
Visual C++ Programming

3
4

CHAPTER 9
? 32비트 메모리 페이징
4 Gigabytes

3 Gigabytes

가상 기계 관리자(VMM)와 가상 장치 드라이버와
같은 중요 윈도우 구성 요소들의 코드와 데이터를
찾을 수 있는 곳이다.

예약된 시스템 활동 영역
(시스템에서 전용으로 사용, 응용 프로그램과
DLL은 액세스 할 수 없다.)
공유 활동 영역
윈도우 95의 모든 프로세스가 사용함

2 Gigabytes

(C) 1998 Sang Il Kim

4 Megabytes

전용 활동 영역
현재 실행하고 있는 Win32 프로세스의
주소 공간
16-bit/MS-DOS

0 Megabytes

◐ Win95 가상 주소 공간 배치 ◑
Visual C++ Programming

3
4

CHAPTER 9
? 32비트 주소 공간과 윈도우 95 메모리 영역
? 16비트/MS 도스 호환 활동 영역
?이전의 응용 프로그램과의 호환성을 제공한다.
?TSR(램 상주) 프로그램과 MS 도스 장치 드라이버에서 사용한다.
?Win32 프로세스는 16비트/MS 도스 호환 계를 읽거나 쓰기 위해 액세스 할 수 없다.
?이 영역에 액세스하게 되면, 보통 프로세서 예외 상황이 발생한다.
? 전용 활동 영역
?현재 실행중인 Win32 프로세스의 전용 주소 공간을 담고 있다.
?다른 프로세스가 액세스하여 프로세스의 데이터를 망가뜨리는 것을 방지하기 위해
페이지를 맵핑하고 있다.
? 공유 활동 영역
?윈도우NT 에서는 존재하지 않는다.

Win32 응용 프로그램은 공유계에서 메모리를
할당 받을 수 없고, 반드시 메모리 맵핑 파일을
사용해야 한다.

?모든 프로세스의 주소 공간에 맵핑된 구성 요소들을 담고 있다.
?Win32가 사용하는 공통 시스템 DLL도 이 공유 활동 영역에서 찾을 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

윈도우 95 메모리 관리자는 프로세스의 전용 주소 공간에 속하는 모든 메모리

3
4

CHAPTER 9
4 Gigabytes

시스템 사용을 위해 예약된 공간

2 Gigabytes

잘못된 메모리 쓰기 동작을
잡기 위해 사용하는 64KB 공간

0 Gigabytes

시스템 사용을 위해
예약된 64KB 공간

◐ Windows NT 가상 주소 공간 배치 ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

응용 프로그램이
사용할 수 있는 공간

3
4

CHAPTER 9
? 윈도우 95는 밑의 2GB만 완전히 보호한다. 위의 2GB는 덜 안전한 상태에
있는데, 이들 영역이 모든 프로세스들에 맵핑되어 있기 때문이다.
? 윈도우 NT는 전체 4GB 주소 공간을 완전히 다른 프로세스로부터 보호한다.
? 윈도우 95와 NT 메모리 관리자가 모두 메모리 페이징과 32비트 선형
주소를 사용하고 있지만, 4GB주소 공간은 서로 다르게 처리하고 있다.
? 메모리 맵핑 파일을 이용하면, 디스크의 파일을 메모리의 특정 범위 주소로
맵핑하여 파일을 메모리에서 직접 다룰 수 있다.

? Win32 API는 프로세스에 대한 새로운 페이지를 할당하기 위해
VirtualAlloc()과 MapViewOfFile() 두 개의 함수를 제공한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 페이지 할당하기

3
4

CHAPTER 9
? VirtualAlloc()
? 응용 프로그램의 가상 주소 공간의 일련의 페이지들을 예약하거나
사용하고자 할 때 VirtualAlloc()을 사용한다.
? LPVOID VirtualAlloc(
LPVOID lpAddress,
DWORD dwSize,
DWORD flAllocationType,
DWORD flProtect
);

// 예약하거나 사용할 공간의 주소
// 공간의 크기
// 할당 유형
// 액세스 보호 유형

? Parameters
?lpAddress

새 영역의 원하는 시작 주소. 인수가 NULL인 경우에는 시스템이

?dwSize

원하는 새 영역의 크기(바이트 단위)

?flAllocationType

할당 유형

?flProtect

그 페이지가 가져야 할 액세스 보호 유형을 나타낸다.
Visual C++ Programming

(C) 1998 Sang Il Kim

그 영역을 어디에 할당할지 결정하게 된다.

3
5

CHAPTER 9
? VirtualAlloc()에서 사용하는 할당 유형 플래그들
플래그

의미

MEM_COMMIT
MEM_RESERVE

지정한 범위의 페이지에 대해 물리적 메모리를 할당한다.
프로세스의 가상 주소 공간에 예약하지만, 물리적 메모리를
할당하지는 않는다. 예약된 부분은 이를 반납할 때까지 메모리
할당시 사용할 수 없다.
가능한 가장 높은 주소에 메모리를 할당한다.

MEM_TOP_DOWN

플래그

의미

PAGE_READONLY
PAGE_READWRITE
PAGE_EXECUTE
PAGE_EXECUTE_READ

사용하고자 하는 페이지에
사용하고자 하는 페이지에
사용하고자 하는 페이지에
사용하고자 하는 페이지에

PAGE_GUARD
PAGE_NOACCESS
PAGE_NOCACHE

이 영역 내의 페이지들이 가드 페이지가 됨을 명시
사용하고자 하는 페이지에 대한 모든 액세스를 막는다.
사용하고자 하는 페이지에 캐싱을 허용하지 않는다.

PAGE_EXECUTE_READWRITE

대해
대해
대해
대해

읽기 전용 액세스를 명시
읽기 쓸 수 있음을 명시
실행할 수 있음을 명시
읽고 실행할 수 있음을 명시

사용하고자 하는 페이지에 대해 읽고 쓰고 실행할 수 있음을 명시

Visual C++ Programming

(C) 1998 Sang Il Kim

? VirtualAlloc() 액세스 보호 플래그

3
5

CHAPTER 9

(C) 1998 Sang Il Kim

? 가드 페이지
? 가드 페이지는 잘못된 메모리 액세스에 대해 한 번의 보호를 제공하는
역할을 한다.
? 가드 페이지 내의 주소를 프로그램이 액세스하려고 시도하면, 윈도가
STATUS_GUARD_PAGE 예외 상황을 발생시키게 되며,
PAGE_GUARD를 없애게 된다.

Visual C++ Programming

3
5

CHAPTER 10

(C) 1998 Sang Il Kim

비트맵(Bitmaps)

Visual C++ Programming

3
5

CHAPTER 10
? GDI 비트맵과 장치-독립적인 비트맵(DIB, device-independent bitmap)
? GDI 비트맵 객체 - 윈도우의 GDI 모듈 내에서 관리되는 장치-의존적인
데이터 구조체를 갖는다.

? 컬러 비트맵(Color Bitmap)과 모노 비트맵(Monochrome Bitmap)
? 윈도우는 브러시 색상을 다룰 때와는 다른 방식으로 컬러 비트맵을 다룬다.
? 컬러 비트맵
?4개의 컬러 플래인(color plane)이 있다.
?각 컬러 플래인당 1비트씩을 조합하여 하나의 픽셀을 나타낸다.
?비트맵 색상은 표준 16컬러로 제한된다.
?윈도우는 비트맵에서 디더링(dithering)된 색상을 사용하지 않는다.
? 모노 비트맵
?한 개의 컬러 플래인을 갖는다.
?각 픽셀은 off(0, 검정색) 아니면 on(1, 흰색)인 단일 비트로 표현된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? DIB - 고유한 색상 정보를 포함하고 있어서 색상 팔레트 관리가 쉽고
프린트시 그레이 음영을 제어하기 쉽다.
? Win32 API에 의해 직접 지원되는 포맷은 DIB 뿐이다.

3
5

CHAPTER 10
? GDI 비트맵 사용하기
? “비트맵”은 화면상에 표시되거나 프린터로 출력되는 페이지 자체가 될 수
있기 때문에 비트맵을 디스플레이 디바이스 컨텍스트나 프린터 디바이스
컨텍스트로 직접 선택할 수 없다.
? CDC::CreateCompatibleDC() 함수를 이용하여 “메모리 디바이스 컨텍스트”를
만들어 사용한다.
? 리소스로부터 GDI 비트맵 로드하기
? 비트맵을 쉽게 사용하는 방법
? 리소스 컴파일러 - 디스크로부터 DIB를 읽어서 프로젝트의 RES 파일에 저장
? 링커 - DIB를 프로그램의 EXE 파일에 복사한다.
? CDC::LoadBitmap() - DIB로 저장된 BMP 파일을 GDI 비트맵 형식으로
자동 변환해 준다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?리소스로부터 비트맵을 로드한다.

3
5

CHAPTER 10
? 리소스로부터 GDI 비트맵 로드하기
? Red Blocks 비트맵을 출력하는 OnDraw() 함수
?void CMyView::OnDraw(CDC* pDC)
{
CBitmap bitmap;
CDC dcMemory;
bitmap.LoadBitmap(IDB_REDBLOCKS);
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SelectObject(&bitmap);
// CDC 소멸자는 dcMemory를 삭제한다. 비트맵이 선택 해제된다.
// CBitmap 소멸자는 선택 해제된 비트맵을 삭제한다.
}
Visual C++ Programming

(C) 1998 Sang Il Kim

pDC->BitBlt(100, 100, 54, 96, &dcMemory, 0, 0, SRCCOPY);

3
5

CHAPTER 10
? 디스플레이 맵핑 모드의 효과
? 맵핑 모드 MM_LOENGLISH 에서의 비트맵은 보기 좋은 편은 아니다.
? COLORONCOLOR를 파라미터로 이용하여 CDC::SetStretchBltMode()
함수를 호출하면 비트맵 모양이 보다 좋아 보인다.
? 비트 스트레칭
? 맵핑 모드가 MM_TEXT가 아닌 경우에도 Red Blocks 비트맵을 정확히
54x96 픽셀의 사각형이 되도록 하려면 BitBlt() 함수 대신 StretchBlt()
함수를 사용해야 한다.
? CSize size(54, 96);
pDC -> DPtoLP(&size);
&dcDisplayMemory, 0, 0, 54, 96, SRCCOPY);
? BitBlt()나 SetStretchBlt() 함수 호출에 있어서 GDI가 실제로 비트들을
축소 하거나 확대하는 경우, 디스플레이 갱신 속도는 느려지게 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

pDC -> StretchBlt(0, 0, size.cx, -size.cy,

3
5

CHAPTER 10
? 비트맵의 전송
? 비트 블록 전송 (BBT : Bit Block Transfer, BitBlt)
?비트맵 데이터를 한 곳에서 다른 곳으로 전송하려면, 비트들의 블록을 전송해야 한다.
?비트 블록을 전송할 때에는 버퍼로 메로리 DC를 사용해야 한다.
? CDC::BitBlt (비트 전송)
? 기술한 소스 컨텍스트에서 CDC 객체에 붙은 디바이스 컨텍스트에 비트맵을 복사한다.
디바이스 컨텍스트의 각각에 대한 논리 좌표 맵핑이 동일하지 않으면, BitBlt() 함수는
비트맵을 복사하기 위해 StretchBlt() 함수를 사용한다.
(StretchBlt는 필요한 대로 비트맵을 확대하거나 축소한다.)
// 대상 사각형의 왼쪽 상단의 x 좌표(논리 좌표)
// 대상 사각형의 왼쪽 상단의 y 좌표(논리 좌표)
// 복사하는 비트맵의 폭(논리 단위)
// 복사하는 비트맵의 높이(논리 단위)
// 소스 디바이스 컨텍스트에 대한 포인터
// 소스 비트맵의 왼쪽 상단의 x 좌표(논리 좌표)
// 소스 비트맵의 왼쪽 상단의 y 좌표(논리 좌표)
// 비트맵을 복사할 때 사용하는 래스터 처리

(C) 1998 Sang Il Kim

? BOOL BitBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
DWORD dwRop
);

Visual C++ Programming

3
5

CHAPTER 10

int ySrc
int nSrcWidth
int nSrcHeight
DWORD dwRop

// 소스 사각형의 왼쪽 상단의 y 좌표(논리 단위)
// 소스 사각형의 폭(논리 단위)
// 소스 사각형의 높이(논리 단위)
// 비트맵을 복사할 때 사용하는 래스터 처리

);

Visual C++ Programming

(C) 1998 Sang Il Kim

? CDC::StretchBlt (비트를 늘여서 맞추기)
? BOOL StretchBlt(
int x
// 대상 사각형의 왼쪽 상단의 x 좌표(논리 단위)
int y
// 대상 사각형의 왼쪽 상단의 y 좌표(논리 단위)
int nWidth
// 대상 사각형의 폭(논리 단위)
int nHeight
// 대상 사각형의 높이(논리 단위)
CDC* pSrcDC
// 소스 디바이스 컨텍스트에 대한 포인터
int xSrc
// 소스 사각형의 왼쪽 상단의 x 좌표(논리 단위)

3
5

CHAPTER 10
? 래스터 연산(raster-operation, dwRop)

?SRCAND
?SRCCOPY
?SRCERASE
?SRCINVERT
?SRCPAINT
?WHITENESS

모든 출력을 검정색으로 한다.
대상 비트맵을 반대로 한다.
AND 연산자를 사용하여 패턴과 원본 비트맵을 결합한다.
OR 연산자를 사용하여 원본 비트맵을 반전시킨 것을 대상 비트맵과 결합한다.
원본 비트맵을 반전시킨 것을 대상 비트맵에 복사한다.
OR 연산자를 사용하여 대상과 원본 비트맵의 결합한 것을 반대로 한다.
패턴을 대상 비트맵에 복사한다.
XOR 연산자를 사용하여 대상 비트맵과 패턴을 결합한다.
OR 연산자를 사용하여 원본 비트맵을 반전시킨 것을 패턴과 결합한다.
OR 연산자를 사용하여 이 처리의 결과를 대상 비트맵과 결합한다.
AND 연산자를 사용하여 대상과 원본 비트맵의 픽셀을 결합한다.
원본 비트맵을 대상 비트맵에 복사한다.
대상 비트맵을 반대로 하고, 그 결과를 AND 연산자를 사용하여
원본 비트맵과 결합한다.
XOR 연산자를 사용하여 대상과 원본 비트맵의 픽셀을 결합한다.
OR 연산자를 사용하여 대상과 원본 비트맵의 픽셀을 결합한다.
모든 출력을 흰색으로 한다.

(C) 1998 Sang Il Kim

?BLACKNESS
?DSTINVERT
?MERGECOPY
?MERGEPAINT
?NOTSRCCOPY
?NOTSRCERASE
?PATCOPY
?PATINVERT
?PATPAINT

Visual C++ Programming

3
6

CHAPTER 10
? BitBlt(비트 블록 전송), StretchBlt(비트를 늘여서 맞추기)
? 비트맵을 확대하거나 축소하는 방법을 결정하기 위해 StretchBlt()는
대상 장치 컨텍스트의 현재 확대 모드를 사용하고 있다.
? 이 모드는 CDC::StretchBltMode() 메소드를 사용하여 설정된다.
? 모든 장치 컨텍스트가 비트 블록 전송, StretchBlt() 비트 블록 전송을 지원하지는
않는다.
? CDC::GetDeviceCaps() 메소드를 RASTERCAPS를 매개 변수로 전달하여 호출하고,
반환 값에 RC_BITBLT, RC_STRETCHBLT가 있는지 조사하면,
DC에서 비트 블록 전송, StretchBlt 비트 블록 전송을 사용할 수 있는지 알 수 있다.
? if((dc.GetDeviceCaps(RASTERCAPS) & RC_STRETCHBLT) == 0)
{

RC_BITBLT
// 장치가 BitBlt, StretchBlt를 지원하지 않음
(C) 1998 Sang Il Kim

}
else
{
// 장치가 BitBlt, StretchBlt를 지원함
}
Visual C++ Programming

3
6

CHAPTER 10
? CDC::SetStretchBltMode - 현재 비트맵 확장 모드를 설정한다.
? int SetStretchBltMode( int nStretchMode );
? Parameters
?nStretchMode
새로운 확장 모드
Description

BLACKONWHITE

1

COLORONCOLOR

3

HALFTONE

4

WHITEONBLACK 2
STRETCH_ANDSCANS
STRETCH_DELETESCANS
STRETCH_HALFTONE
STRETCH_ORSCANS

Performs a Boolean AND operation using the color values for the
eliminated and existing pixels. If the bitmap is a monochrome bitmap,
this mode preserves black pixels at the expense of white pixels.
Deletes the pixels. This mode deletes all eliminated lines of pixels
without trying to preserve their information.
Maps pixels from the source rectangle into blocks of pixels in the
destination rectangle. The average color over the destination block
of pixels approximates the color of the source pixels.
After setting the HALFTONE stretching mode, an application must
call the Win32 function ::SetBrushOrgEx to set the brush origin.
If it fails to do so, brush misalignment occurs.
Performs a Boolean OR operation using the color values for the
eliminated and existing pixels. If the bitmap is a monochrome bitmap,
this mode preserves white pixels at the expense of black pixels.
windows 95: Same as BLACKONWHITE
windows 95: Same as COLORONCOLOR
windows 95: Same as HALFTONE
windows 95: Same as WHITEONBLACK
Visual C++ Programming

(C) 1998 Sang Il Kim

Value

3
6

CHAPTER 10
? CGdiObject::GetObject
? CGdiObject 에 붙어있는 GDI 오브젝트에 대한 정보를 얻는다.
? int GetObject( int nCount, LPVOID lpObject ) const;

Object

Buffer type

CPen
CBrush
CFont
CBitmap
CPalette

일반 펜에 대해 LOGPEN. 확장 펜에 대해 EXLOGPEN
LOGBRUSH
LOGFONT
BITMAP
논리 팔레트에 있는 엔트리의 수를 기술하는 WORD.
실제 팔레트 엔트리를 얻으려면 CPalette::GetPaletteEntries 를 사용
Not supported

CRgn

Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?nCount
기술한 버퍼에 복사되는 바이트의 최대 수.
보통 버퍼에 의해 가리키는 오브젝트의 sizeof()
?lpObject 오브젝트 정보가 넣어지는 버퍼에 대한 포인터.

3
6

CHAPTER 10
? BitBlt의 전송 소스와 전송 대상의 좌표 지정
BitBlt(dx, dy, dw, dh, pSrcDC, sx, sy, rop);
전송대상의
디바이스 컨텍스트

전송소스의
디바이스 컨텍스트

(0, 0)

(0, 0)
전송된다

(dx, dy)

(sx, sy)
dh

dw

dh
dw
(C) 1998 Sang Il Kim

(dx, cy) : 디바이스 컨텍스트의 어디로 전송되는 가를 지정한다.
dw : 전송하는 비트맵의 폭
dh : 전송하는 비트맵의 높이
(sx, sy) : 디바이스 컨텍스트의 어디에서 전송하는 가를 지정한다.
Visual C++ Programming

3
6

CHAPTER 10
? 래스터 연산(Raster Operation) (DevStudio\Vc\include\wingdi.h)
래스터 연산

논리 연산

의미

SRCCOPY

dst = src

전송 소스의 패턴을 사용한다.

NOTSRCCOPY

dst = ~src

전송 소스의 패턴을 반전하여 사용한다.

SRCPAINT

dst = dst | src

전송 소스와 전송 대상의 패턴을 OR한다.

SRCAND

dst = dst & src

전송 소스와 전송 대상의 패턴을 AND한다.

SRCINVERT

dst = dst ^ src

전송 소스와 전송 대상의 패턴을 XOR한다.

SRCERASE

dst = ~dst & src 소거한다.

(C) 1998 Sang Il Kim

전송 소스의 패턴을 전송 대상의 패턴에서

Visual C++ Programming

3
6

CHAPTER 10
? 래스터 연산(Raster Operation)
전송 소스의 패턴
(SRC)

전송 대상의 패턴
(DST)

SRCCOPY

NOTSRCCOPY

SRCPAINT

SRCAND

SRCINVERT

SRCERASE
(C) 1998 Sang Il Kim

? 래스터 연산에 의한 DST의 변화

Visual C++ Programming

3
6

CHAPTER 10
? 예제 EX10A
? 맵핑 모드가 MM_LOENGLISH로 설정된 스크롤 뷰에 리소스 기반
비트맵을 출력한다.
? CGdiObject 클래스의 멤버 함수 GetObject()의 호출을 통해 비트맵
크기를 얻는다.
? 비트맵을 이용해서 화면 출력 향상하기

(C) 1998 Sang Il Kim

? 화면에서 매끄러운 움직임을 지원하기 위해 프로그램 자체 비트맵을 생성한다.
?메모리 디바이스 컨텍스트에 선택된 비트맵을 그린다.
?그려진 비트맵을 화면으로 옮긴다.

Visual C++ Programming

3
6

CHAPTER 10
? 예제 EX10B
? 원이 이동될 때 WM_MOUSEMOVE 메시지에 따라 원이 지워졌다가 다시
그려지기 때문에 화면이 깜박거리는 문제를 해결하기 위해 GDI 비트맵을
사용한다.
? OnInitialUpdate()
?디스플레이 장치와 호환이 되는 메모리 디바이스 컨텍스트와 비트맵을 만든다.
?메모리 디바이스 컨텍스트와 비트맵은 디스플레이 디바이스 컨텍스트 dc와
호환되지만 메모리 디바이스 컨텍스트는 디스플레이 디바이스 컨텍스트와
일치하는 맵핑모드를 설정해야 한다.
?비트맵을 그리기 위해 메모리 디바이스 컨텍스트를 준비한다.
? OnDraw()
?메모리 디바이스 컨텍스트의 핸들을 전달한다.
?메모리 디바이스 컨텍스트에서 디스플레이 디바이스 컨텍스트로 비트맵을 복사한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? OnPaint()

3
6

CHAPTER 10
? 무효화 사각형
? InvalidateRect(rectOld, TRUE);
InvalidateRect(rectNew, TRUE);
?파라미터가 True(디폴트)이면 윈도우는 무효 사각형이 다시 그려지기전에
배경색을 지운다. 따라서 화면 깜박임이 발생하게 된다.
? InvalidateRect(rectOld, FALSE);
InvalidateRect(rectNew, FALSE);
?파라미터가 False이면 무효 사각형 전체가 비트맵에 복사되기 때문에

(C) 1998 Sang Il Kim

배경을 지우지 않는다.

Visual C++ Programming

3
6

CHAPTER 10
? DIB와 CDib 클래스
? MFC에는 GDI 비트맵을 위한 클래스(CBitmap)는 있지만 DIB를 위한
클래스는 없다.
? 팔레트 프로그래밍에 관한 조언
? 윈도우에 단일 DIB를 출력하는 경우
논리적 팔레트(DIB에서 사용할 색상을 포함하는 GDI 객체)를 만든 다음
논리적 팔레트를 하드웨어 시스템 팔레트(비디오 카드가 출력할 수 있는
256색상 테이블)에 맵핑시켜야 한다. - realize
? 시스템 팔레트
?사용자가 임의로 색을 지정하여 사용할 수 있는 색상 - 236개
? 배경 프로그램의 경우
?시스템 팔레트는 변경되지 않은 상태에서 윈도우는 논리적 팔레트와 시스템
팔레트 간에 새로운 맵핑을 설정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 고정된 색상 - 20개

3
7

CHAPTER 10
? 팔레트 프로그래밍에 관한 조언
? 프로그램의 팔레트는 언제 리얼라이즈(realize) 해야 하나?
?프로그램에서 팔레트를 리얼라이즈 하게 되면 자신의 메인 윈도우로
WM_PALETTECHANGED 메시지를 보낸다.
?자신의 프로그램이 입력 포커스를 받게 되면 WM_QUERYNEWPALETTE
메시지가 보내진다.
?프로그램에서는 이 두 개의 메시지에 대응하여 팔레트를 리얼라이즈 해야 한다.
?이 팔레트 메시지들이 뷰 윈도우로 보내지는 것이 아니므로 메인 프레임 윈도우에서
이 메시지들을 맵핑한 다음 뷰에 통보해야 한다.
?Win32 함수 RealizePalette()를 호출하여 리얼라이즈를 수행하기 전에
SelectPalette() 함수를 호출하여 디바이스 컨텍스트로 DIB의 논리적 팔레트를
?SelectPalette()의 파라미터
True - 어플리케이션이 전경 프로그램으로 실행되든지, 배경 프로그램으로 실행되든지
상관없이 항상 배경 팔레트로 처리된다.
False - 어플리케이션이 전경 프로그램으로 실행되고 있는 경우 전경 팔레트로 처리.
어플리케이션이 배경 프로그램으로 실행되고 있는 경우 배경 팔레트로 처리.
Visual C++ Programming

(C) 1998 Sang Il Kim

선택해야 한다.

3
7

CHAPTER 10
? 팔레트의 종류
? 하드웨어 팔레트 ( Hardware Palette ) - 그래픽 카드의 하드웨어 팔레트
? 시스템 팔레트 ( System Palette ) - 윈도우의 팔레트 매니저가 사용하는 팔레트
? 논리적 팔레트 ( Logical Palette ) - 어플리케이션에서 만들어진 팔레트
( CPalette 클래스로 표현된다 )
? 리얼라이즈 (Realize)과정
논리적 팔레트를 시스템 팔레트로 맵핑하는 과정
? 전경(foreground)/배경(background) 프로그램과 전경/배경 팔레트
? 전경 프로그램 - 현재 활성화된 프로그램
? 전경 팔레트 - 전경 프로그램에 의해 리얼라이즈된 팔레트
? 팔레트 관련 메시지
팔레트가 변경되면 윈도우는 실행중인 모든 프로그램의 메인 윈도우로 이 메시지를
전달하여 변경된 시스템 팔레트에 맞게 자신의 영역을 다시 그리도록 한다.
? WM_QUERYNEWPALETTE 메시지 - 비활성 프로그램이 입력 포커스를 받아 활성화
될 때 이 메시지를 활성화된 프로그램에 전달하여 리얼라이즈할 기회를 제공한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? WM_PALETTECHANGED 메시지 - 활성화된 프로그램의 리얼라이즈로 인해 시스템

3
7

CHAPTER 10
인덱스 RGB 색상

색상

인덱스 RGB 색상

색상

0

RGB(0, 0, 0)

검정

246

RGB(255, 251, 240)

크림색

1

RGB(128, 0, 0)

어두운 검정

247

RGB(160, 160, 164)

어두운 회색

2

RGB(0, 128, 0)

어두운 녹색

248

RGB(128, 128, 128)

중간 회색

3

RGB(128, 128, 0)

어두운 노랑

249

RGB(255, 0, 0)

빨강

4

RGB(0, 0, 128)

어두운 청색

250

RGB(0, 255, 0)

녹색

5

RGB(128, 0, 128)

어두운 보라

251

RGB(255, 255, 0)

노랑

6

RGB(0, 128, 128)

어두운 하늘색 252

RGB(0, 0, 255)

파랑

7

RGB(192, 192, 192)

밝은 회색

253

RGB(255, 0, 255)

보라

8

RGB(192, 220, 192)

연한 녹색

254

RGB(0, 255, 255)

하늘색

9

RGB(166, 202, 240)

하늘색

255

RGB(255, 255, 255) 흰색
Visual C++ Programming

(C) 1998 Sang Il Kim

? 정적 시스템 색상

3
7

CHAPTER 10
? 논리적 팔레트
? LOGPALETTE 구조
typedef struct tagLOGPALETTE {
WORD

palVersion;

// 그 구조에 대한 윈도우 버전. 0x300

WORD

palNumEntries; // 색상 항목의 수

PALETTEENTRY

palPalEntry[1];

// 각 항목에 대한 사용 플래그를 명시하는 PALETTEENTRY 구조의 배열
} LOGPALETTE;
typedef struct tagPALETTEENTRY {
BYTE peRed;
(C) 1998 Sang Il Kim

BYTE peGreen;
BYTE peBlue;
BYTE peFlags;

// 팔레트 항목의 사용방법

} PALETTEENTRY;
Visual C++ Programming

3
7

CHAPTER 10
? 팔레트 항목을 사용할 방법을 정의하는 플래그
설명

PC_EXPLICIT

논리적 팔레트 항목의 하위 단어가 하드웨어 팔레트 인덱스임을
나타낸다.

PC_NOCOLLAPSE

색상을 시스템 팔레트 내의 기존 색상에 맵핑하기보다는 시스템
팔레트 내의 미사용 항목에 위치하도록 한다.

PC_RESERVED

논리적 팔레트 항목은 팔레트 애니메이션을 위해 사용하며,
다른 창이 컬러 맵핑하는 것을 막게 된다.

(C) 1998 Sang Il Kim

플래그 값

Visual C++ Programming

3
7

CHAPTER 10
메소드

설명

AnimatePalette()

애니메이션 팔레트를 만들기 위해 논리적 팔레트 항목을 교체한다.

CreateHalftonePalette()

장치 컨텍스트에 대한 하프톤 팔레트를 만들고
이를 CPalette 객체에 부착한다.

CreatePalette()

윈도우 색상 팔레트를 만들고, 이를 CPalette 객체에 부착한다.

FromHandle()

기존의 윈도우 HPALETTE 팔레트 핸들로부터 CPalette 객체에
대한 포인터를 얻는다.

GetEntryCount()

논리적 팔레트 내의 색상 항목의 수를 얻는다.

GetNearestPaletteIndex()

지정된 색상 값과 가장 가깝게 일치하는 논리적 팔레트 항목의
인덱스를 얻는다.

GetPaletteEntries()

논리적 팔레트로부터 지정된 범위의 팔레트 항목을 얻는다.

ResizePalette()
SetPaletteEntries()

CPalette 객체의 논리적 팔레트에 있는 색상 항목들의 수를 지정된
항목 수로 변경한다.
CPalette 객체의 논리적 팔레트에 있는 특정 범위의 항목들에 대한
RGB 색상 값과 플래그를 설정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CPalette 클래스 메소드

3
7

CHAPTER 10
? DIBs, 픽셀, 색상 테이블
? DIB는 픽셀이라 불리는 요소들이 2차원 배열로 구성된 것이다.

(C) 1998 Sang Il Kim

? 픽셀은 DIB의 컬러 해상도에 따라 1, 4, 8, 16, 24, 32의 연속적인 비트들로
구성된다.
? 1bpp(비트이미지) - Mono
? 4bpp - 16컬러
? 8bpp - 256컬러 ? 16bpp (하이 컬러) - 65,536컬러
? 24bpp (트루 컬러) - 1,680만 컬러
? bpp (bit per pixel)
? DIB가 색상 테이블을 가지고 있지 않을 경우 Win32 함수
CreateHalftonePalette()가 리턴하는 팔레트를 사용한다.

Visual C++ Programming

3
7

CHAPTER 10
? 장치 종속 비트맵 (DDB : Device Dependent Bitmap)
? 하드웨어 팔레트에 의존하는 비트맵
? BITMAP 구조 ( DevStudio\Vc\include\<Wingdi.h> 374라인)
typedef struct tagBITMAP
LONG

bmType;

// 비트맵 유형

LONG

bmWidth;

// 비트맵의 너비 (픽셀 단위)

LONG

bmHeight;

// 비트맵의 높이 (픽셀 단위)

LONG

bmWidthBytes; // 한 주사선에 대한 바이트 수

WORD

bmPlanes;

// 비트맵 내의 색상 면의 수

WORD

bmBitsPixel;

// 픽셀의 색상을 묘사하기 위해 필요한 비트들의 수

LPVOID

bmBits;

// 이미지 데이터를 형성하고 있는 문자 값의 배열에 대한 포인터

} BITMAP;
Visual C++ Programming

(C) 1998 Sang Il Kim

{

3
7

CHAPTER 10
? 장치 독립 비트맵 (DIB : Device Independent Bitmap)
? DIB 이미지가 생성된 장치의 색상 포맷에 관한 정보를 담고 있다.
? DIB 이미지가 생성된 장치의 해상도에 관한 정보를 담고 있다.
? DIB 이미지가 생성된 장치의 팔레트에 관한 정보를 담고 있다.
? 팔레트의 RGB 색상 요소들을 DIB 이미지 내의 픽셀들로 맵핑하기 위해
사용하는 비트들의 배열을 담고 있다.
? 디스크의 파일 크기를 줄이기 위해 사용한 데이터 압축 도식을 나타내는

(C) 1998 Sang Il Kim

데이터 압축 식별자를 담고 있다.

Visual C++ Programming

3
7

CHAPTER 10
BITMAPFILEHEADER
(BMP file only)

bfType = “BM”
bfOffBits

BITMAPFILEHEADER

biSize (구조체 크기<Byte>)
biWidth (픽셀 단위의 비트맵 폭)
biPlanes (픽셀 단위의 비트맵 높이)
biPlanes=1 (대상 디바이스를 위한 컬러 플레인, 항상1)
biBitCount (픽셀 당 비트수 1,4,8,16,24,32)
biCompression (압축 타입 지정)
biSizeImage (이미지 크기)
biClrused (실제로 비트맵에 사용한 색상 테이블의 색상
인덱스 수)

Color Table
(색상 테이블)

DIB Bit Image

모노 DIB 2개의 32비트 엔트리
4bpp DIB 16개 또는 그 이하의 32비트 엔트리
8bpp DIB 256개 또는 그 이하의 32비트 엔트리
이미지를 구성하는 실제 데이터
(픽셀은 행(row) 내의 열(column)에 의해 정렬된다.
행(row)은 4바이트 경계로 이루어진다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? BMP 파일 내의 DIB의 구조 ( DevStudio\Vc\include\<Wingdi.h> 500라인)

3
8

CHAPTER 10
? BMP 파일 내의 DIB의 구조
? 클립보드로부터 DIB를 얻는 경우 DIB의 BITMAPFILEHEADER가 존재하지
않는다. BITMAPINFOHEADER 구조체에서 색상 테이블을 계산할 수
있지만 색상 테이블에서 이미지를 계산할 수는 없다.
? BITMAPINFOHEADER와 색상 테이블을 합친 BITMAPINFO 구조체
?DevStudio\Vc\include\<Wingdi.h> 546라인

typedef struct tagBITMAPINFO{
BITMAPINFOHEADER

bmiHeader;

RGBQUAD

bmiColors[1];
(C) 1998 Sang Il Kim

} BITMAPINFO;

Visual C++ Programming

3
8

CHAPTER 10

? StretchDlBits
?StretchBlt()와 유사한 방식으로 화면이나 프린터에 DIB를 직접 출력한다.
? GetDlBits
?할당한 메모리에 지정된 GDI 비트맵으로 부터 DIB의 비트를 구한다.
?픽셀당 색상 비트의 수와 압축을 지정하여 DIB 포맷을 어느 정도 제어할 수 있다.
?압축을 사용하는 경우 GetDlBits()를 두 번 호출하게 되는데, 한 번은 필요한 메모리를
계산하기 위해서 호출하고, 또 한 번은 DIB 데이터를 생성하기 위해 호출한다.
? CreateDlBitmap
?DIB로 부터 GDI 비트맵을 만든다.
?다른 DIB 함수들처럼 파라미터로 디바이스 컨텍스트 포인터를 제공해야 한다.
? CreateDlBSection
?새로운 Win32 함수로 DIB 섹션이라는 특수한 DIB를 생성하고 GDI 비트맵 핸들을
리턴한다.
?DIB의 메모리를 직접 접근해서 비트맵 핸들과 메모리 디바이스 컨텍스트를 가지고
GDI 함수들을 호출하여 DIB에 그리기를 할 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? DIB 액세스 함수
? SetDlBitsToDevice
?화면이나 프린터에 DIB를 직접 출력한다.
?비트맵의 한 비트는 화면의 1픽셀이나 프린터의 1도트에 대응한다.

3
8

CHAPTER 10
? DIB 출력 퍼포먼스
? 최적화된 DIB 처리는 윈도우의 주요 기능이다.
? 비디오 카드들은 표준 DIB 이미지 포맷에 따른 프레임 버퍼를 가지고 있다.
? 프로그램에서 DIB 처리 속도를 높여주는 윈도우의 DIB엔진을 이용할 수 있다.
? 16bpp/24bpp 비트맵을 출력하는 경우, 처리 속도는 매우 느리다.
? 분리된 8bpp GDI 비트맵을 만들고 나서 StretchBlt()를 호출하면 비트맵이 보다
빠르게 출력된다.
? 비트맵을 만들어 그리기(drawing)전에 팔레트를 리얼라이즈(Realize) 해야 한다.
? BMP 파일에서 CDib 객체를 로딩(Loading)한 후 삽입할 코드
m_pDib -> UsePalette(&dc);
m_hBitmap = m_pDib -> CreateBitmap(&dc);
::SelectObject(m_dcMem.GetSafeHdc(), m_hBitmap);
(C) 1998 Sang Il Kim

? 뷰 클래스의 OnDraw()에서 CDib::Draw() 대신 사용할 수 있는 코드
m_pDib -> UsePalette(&dc);
CSize sizeDib = m_pDib -> GetDimensions();
pDC -> StretchBlt( 0, 0, sizeDib.cx, sizeDib.cy, &m_dcMem,
0, 0, sizeToDraw.cx, sizeToDraw.cy, SRCCOPY);
Visual C++ Programming

3
8

CHAPTER 10
? CBitmap 클래스 메소드
메소드

설명

CreateBitmap()

지정된 너비와 높이, 비트 패턴을 갖는 장치 종속 메모리 비트맵을 생성한다.

CreateBitmapIndirect()

BITMAP 구조에 정의된 너비와 높이, 비트 패턴을 갖는 비트맵을 생성한다.

CreateCompatibleBitmap()

지정된 장치 컨텍스트와 호환성이 있는 비트맵을 생성한다.

FromHandle()

지정된 윈도우 비트맵 핸들로부터 CBitmap 객체에 대한 포인터를 얻는다.

GetBitmap()

특정 CBitmap 객체에 대한 포인터를 얻는다.

GetBitmapBits()

비트맵의 비트들을 지정된 버퍼로 복사한다.

GetBitmapDimension()

SetBitmapDimension() 메소드로 앞에서 설정된 비트맵의 너비와 높이를 구한다.

LoadBitmap()

자원 데이터로부터 비트맵을 로드해서 CBitmap 객체에 부착한다.

LoadMappedBitmap()

자원 데이터로부터 비트맵을 로드해서 색상을 현재의 시스템 색상으로 맵핑한다.

LoadOEMBitmap()

미리 정의된 윈도우 비트맵을 로드해서 CBitmap 객체에 부착한다.

SetBitmapBits()

비트맵의 비트들을 특정 비트 값으로 설정한다.

SetBitmapDimension()

0.1mm 단위를 사용하여 비트맵의 너비와 높이를 지정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CreateDiscardableBitmap() 지정된 장치 컨텍스트와 호환성이 있는 버릴 수 있는 비트맵을 생성한다.

3
8

CHAPTER 10
? CBitmap::LoadBitmap
? 프로그램의 실행 파일에서 이름이 붙은 비트맵 리소스를 로드하여
CBitmap 오브젝트에 붙인다.

? CDC::CreateCompatibleDC
? 기술한 디바이스 컨텍스트에 호환되는 메모리 디바이스 컨텍스트를 생성한다.
? virtual BOOL CreateCompatibleDC( CDC* pDC );
? Parameters
?pDC 생성하는 디바이스 컨텍스트가 호환되는 디바이스 컨텍스트에 대한 포인터.
Visual C++ Programming

(C) 1998 Sang Il Kim

? BOOL LoadBitmap( LPCTSTR lpszResourceName );
? BOOL LoadBitmap( UINT nIDResource );
? Parameters
?lpszResourceName 로드하는 비트맵 리소스의 이름을 포함하는 널로 끝나는
문자열에 대한 포인터.
?nIDResource
로드하는 비트맵 리소스를 나타내는 정수.

3
8

CHAPTER 10
? CDC::GetSafeHdc
? CDC에 현재 붙어 있는 윈도우 디바이스 컨텍스트 핸들을 리턴한다.
? HDC GetSafeHdc( ) const;
? Return Value
CDC에 현재 붙어 있는 윈도우 디바이스 컨텍스트 핸들

(C) 1998 Sang Il Kim

? CPoint::Offset
? x, y좌표에 개별적인 값을 추가한다.
? void Offset( int xOffset, int yOffset );
? void Offset( POINT point );
? void Offset( SIZE size );
? Parameters
?xOffset 위치의 x 좌표에 옵셋(offset)인 크기
?yOffset 위치의 y 좌표에 옵셋(offset)인 크기
?point
CPoint 객체의 x, y 멤버에 의해 기술된 위치에 대한
옵셋 (POINT or CPoint) 의 크기
?size
CPoint 객체의 cx, cy 멤버에 의해 기술된 위치에 대한
옵셋 (SIZE or CSize) 의 크기
?예) CPoint point(5,5); // 위치를 x=5, y=5로 초기화한다.
point.Offset(4,3); // x좌표에 4, y좌표에 3을 추가한다.
Visual C++ Programming

3
8

CHAPTER 10
? CDC::SelectClipRgn
? 디바이스 컨텍스트의 클리핑 영역을 기술한 영역으로 설정하거나 기술한 영역을
현재의 영역에 조합한다.
? virtual int SelectClipRgn( CRgn* pRgn );
? int SelectClipRgn( CRgn* pRgn, int nMode );
? The region’s type
?COMPLEXREGION
?ERROR
?NULLREGION
?SIMPLEREGION
? Parameters
?pRgn 새로운 클리핑

새로운 클리핑 영역은 오버랩 경계를 갖는다.
디바이스 컨텍스트 또는 영역은 유효하지 않다.
새로운 클리핑 영역이 비어 있다.
새로운 클리핑 영역은 오버랩 경계를 갖지 않는다.
영역으로 사용하거나 현재 영역에 조합하는 영역에 대한 포인터

RGN_AND
RGN_COPY
RGN_DIFF
RGN_OR
RGN_XOR

두 영역 중 겹치는 부분을 사용한다.(교집합)
첫번째 영역의 복사본을 만든다.
영역1에는 있지만 영역2에는 없는 부분으로 구성된 영역을 만든다.
두 영역을 합한다.(합집합)
두 영역을 합하지만 겹치는 부분은 뺀다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?nMode 기술한 영역이 현재 클리핑 영역에 어떻게 조합되는가를 기술한다.

3
8

? CDC::IntersectClipRect
? 현재 클리핑 영역에 기술한 사각형을 교차하여 새로운 클리핑 영역을 만든다.
? 윈도우는 모든 출력을 현재 클리핑 영역으로 클립한다.
? virtual int IntersectClipRect( int x1, int y1, int x2, int y2 );
? virtual int IntersectClipRect( LPCRECT lpRect );
? The new clipping region's type.
?COMPLEXREGION 새로운 클리핑 영역은 오버랩 경계를 갖는다.
?ERROR
디바이스 컨텍스트는 유효하지 않다.
?NULLREGION
새로운 클리핑 영역이 비어 있다.
?SIMPLEREGION
새로운 클리핑 영역은 오버랩 경계를 갖지 않는다.
? Parameters
?x1 현재 클리핑 영역에 교차하는 사각형의 왼쪽 상단의 x좌표(논리 단위)
?y1 현재 클리핑 영역에 교차하는 사각형의 왼쪽 상단의 y좌표(논리 단위)
?x2 현재 클리핑 영역에 교차하는 사각형의 오른쪽 하단의 x좌표(논리 단위)
?y2 현재 클리핑 영역에 교차하는 사각형의 오른쪽 하단의 y좌표(논리 단위)
?lpRect 현재 클리핑 영역에 교차하는 사각형을 포함하는 RECT 구조체나
CRect 객체에 대한 포인터

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 10

3
8

CHAPTER 10
? CBitmap::CreateCompatibleBitmap
? 기술한 디바이스 컨텍스트의 색상 형식과 호환되는 크기의 비트맵을 생성한다.
? BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );
? Parameters
?pDC
색상 형식이 복사되는 디바이스 컨텍스트에 대한 포인터
?nWidth
비트맵의 폭 (픽셀 단위)
?nHeight
비트맵의 높이 (픽셀 단위)
? nWidth, nHeight 파라미터가 0이면, CreateCompatibleBitmap은 1x1 픽셀 모노
비트맵을 생성한다.
? CDC::GetClipBox
? 현재 클리핑 영역의 바운딩 사각형을 얻는다.
? 바운딩 사각형은 클리핑 영역을 완전히 포함할 수 있는 가장 작은 사각형이다.
? virtual int GetClipBox( LPRECT lpRect ) const;
? The clipping region's type.
?COMPLEXREGION
클리핑 영역은 오버랩 경계를 갖는다.
?ERROR
디바이스 컨텍스트는 유효하지 않다.
?NULLREGION
클리핑 영역이 비어 있다.
?SIMPLEREGION
클리핑 영역은 오버랩 경계를 갖지 않는다.
? Parameters
?lpRect 바운딩 사각형의 좌표로 채워지는 RECT 구조체나 CRect 객체에 대한 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

3
8

CHAPTER 10
? CDC::PatBlt
? 디바이스에 기술한 사각형에 패턴을 칠한다.
? 패턴은 현재의 브러시와 디바이스에 이미 있는 패턴의 조합이다.
? BOOL PatBlt( int x, int y, int nWidth, int nHeight, DWORD dwRop );
? Parameters
?x

패턴으로 채워지는 사각형의 왼쪽 상단의 x좌표 (논리 단위)

?y

패턴으로 채워지는 사각형의 왼쪽 상단의 y좌표 (논리 단위)

?nWidth

패턴으로 채워지는 사각형의 폭 (논리 단위)

?nHeight

패턴으로 채워지는 사각형의 넓이 (논리 단위)

?dwRop

브러시와 패턴이 어떻게 조합되는가를 제어하는 래스터 처리
대상 비트맵에 패턴을 복사한다.

PATINVERT

XOR 연산자를 사용하여 대상 비트맵과 패턴을 조합시킨다.

DSTINVERT

대상 비트맵을 반대로 한다.

BLACKNESS

모든 출력을 검정색으로 한다.

(C) 1998 Sang Il Kim

PATCOPY

WHITENESS 모든 출력을 흰색으로 한다.

Visual C++ Programming

3
9

? CDC::GetDeviceCaps
? 디바이스의 성능에 관한 여러 가지 정보에 대한 디바이스 컨텍스트에 관련되는
디바이스를 쿼리한다.
? int GetDeviceCaps( int nIndex ) const;
? Parameters
?nIndex 쿼리되는 기능
DRIVERVERSION 디바이스 드라이버 버전
TECHNOLOGY
디바이스 기술(technology)
Value
Meaning
DT_PLOTTER
Vector plotter
DT_RASDISPLAY
Raster display
DT_RASPRINTER
Raster printer
DT_RASCAMERA
Raster camera
DT_CHARSTREAM
Character stream
DT_METAFILE
Metafile
DT_DISPFILE
Display file
HORZSIZE 물리적인 디스플레이의 폭 (밀리미터)
VERTSIZE 물리적인 디스플레이의 높이 (밀리미터)
HORZRES
디스플레이의 폭 (픽셀 단위)
VERTRES
디스플레이의 높이 (래스터 라인)
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 10

3
9

? Parameters
?nIndex
LOGPIXELSX
LOGPIXELSY
BITSPIXEL
PLANES
NUMBRUSHES
NUMPENS
NUMFONTS
NUMCOLORS
ASPECTX
ASPECTY
ASPECTXY
PDEVICESIZE

디스플레이 폭의 논리 인치마다의 픽셀 수
디스플레이 높이의 논리 인치마다의 픽셀 수
각 픽셀에 대한 색상 비트의 수
색상 판의 수
디바이스의 특정 브러시의 수
디바이스 특정 펜의 수
디바이스 특정 폰트의 수
디바이스의 색상 표에 있는 엔트리의 수
라인그리기에 사용되는 디바이스 픽셀의 상대 폭
라인그리기에 사용되는 디바이스 픽셀의 상대 높이
라인그리기에 사용되는 디바이스 픽셀의 대각선의 폭
PDEVICE 내부 데이터 구조체의 크기

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 10

3
9

CHAPTER 10
? CCmdTarget::BeginWaitCursor
? 커맨드나 처리에 많은 시간 소요가 예상될 때 커서를 모래 시계로 표시하기
위하여 이 함수를 사용한다.
? void BeginWaitCursor( );
? CCmdTarget::EndWaitCursor
? BeginWaitCursor 함수의 반대이고, 모래 시계 커서가 이전의 커서로
리턴하기 위하여 멤버 함수 다음에 호출되어야 한다.
? void EndWaitCursor( );

(C) 1998 Sang Il Kim

? void CMyView::OnSomeCommand()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
EndWaitCursor();
// remove the hourglass cursor
}
Visual C++ Programming

3
9

? CPoint::Cpoint
? CPoint 클래스는 윈도우 POINT 구조체를 감싸는 아주 기본적인 클래스이다.
? CPoint 클래스의 생성자
? CPoint( );
? CPoint( int initX, int initY );
? CPoint( POINT initPt );
? CPoint( SIZE initSize );
? CPoint( DWORD dwPoint );
? Parameters
?initX
위치의 x 좌표의 초기 값
?initY
위치의 y 좌표의 초기 값
?initPt
POINT 구조체나 위치를 초기화하는 데 사용되는 CPoint 객체
x좌표는 initPoint 구조체나 객체의 cx 멤버에 초기화되고,
y좌표는 initPoint 구조체나 객체의 cy 멤버에 초기화된다.
?initSize
SIZE 구조체나 위치를 초기화하는 데 사용되는 CSize 객체
x좌표는 initSize 구조체나 객체의 cx 멤버에 초기화되고,
y좌표는 initSize 구조체나 객체의 cy 멤버에 초기화된다.
?dwPoint
x 좌표는 이 파라미터의 LOWORD(low-order word of dwPoint)로,
y 좌표는 이 파라미터의 HIWORD(high-order word of dwPoint)로
초기화된다.

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 10

3
9

CHAPTER 10
? 조건부 컴파일
? #ifdef 매크로명
문장1
#endif

#ifdef는 매크로가 정의되어 있으면 문장1을 컴파일 한다.
매크로가 정의되어 있지 않으면 문장1을 컴파일하지
않는다.

? #ifndef 매크로명 #ifndef는 매크로가 정의되어 있지않으면 문장1을 컴파일 한다.
#endif

매크로가 정의되어 있으면 문장1을 컴파일하지
않는다.

(C) 1998 Sang Il Kim

문장1

Visual C++ Programming

3
9

따로 떼어 두세요

(C) 1998 Sang Il Kim

생각하는 시간을 따로 떼어 두세요.
그것은 힘의 원천이지요.
노는 시간을 따로 떼어 두세요.
그것은 지혜의 산물이랍니다.
기도하는 시간을 따로 떼어 두세요.
그것은 지상 최대의 힘이지요.
사랑하고 그리고 사랑받는 시간을 따로 떼어 두세요.
그것은 신에게서 주어진 특권이지요.
친절을 베풀 시간을 따로 떼어 두세요.
그것은 행복에의 길이랍니다.
웃는 시간을 따로 떼어 두세요.
그것은 영혼의 음악이랍니다.
주는 시간을 따로 떼어 두세요.
이기적이기에는 하루가 너무 짧지요.

Visual C++ Programming

3
9

CHAPTER 11

(C) 1998 Sang Il Kim

윈도우 메시지 처리와
멀티스레드 프로그래밍

Visual C++ Programming

3
9

CHAPTER 11
? 단일 스레드 프로그램에서는 메시지를 어떻게 처리하는가?
? MSG message;
while (::GetMessage(&message, NULL, 0, 0)) {
::TranslateMessage(&message);
::DispatchMessage(&message);
}
? 윈도우는 프로그램에 속해 있는 메시지를 판단한다.
? GetMessage() 함수는 메시지 처리가 필요할 때 리턴한다.
? 메시지가 접수되면 중지된 프로그램이 다시 실행된다.
? TranslateMessage() 함수는 WM_KEYDOWN이 발생했을 때 그 키가
ASCII 문자를 포함하는 키일 경우 WM_CHAR 메시지로 변경된다.
? DispatchMessage() 함수는 MFC 메시지 펌프에 제어권을 전달한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 접수된 메시지가 없으면 프로그램은 중지되고, 다른 프로그램들이 실행된다.

3
9

CHAPTER 11
? 제어권 양보
? Win16, Win32는 해당 프로그램의 핸들러 함수가 리턴될때까지 DispatchMessage()
함수가 리턴되지 않는다.

? 이러한 문제점을 해결하기 위해 핸들러의 메인 루프 내에 다음과 같은 명령들을
삽입해서 핸들러 함수가 제어권을 양보하도록 만든다.

? MSG message;
if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
::TranslateMessage(&message);
::DispatchMessage(&message);
}
? 이 경우 핸들러 함수(PeekMessage()을 포함하는 함수)는 계속해서 CPU를 차지하고
있다가 처리할 메시지가 있으면 이 핸들러 (PeekMessage()을 포함하는 함수)는 중지
되고, 처리할 메시지에 대응하는 핸들러가 호출된다.

? 처리할 메시지에 대응하는 핸들러가 종료된 후에 다시 이 핸들러 (PeekMessage()을
포함하는 함수) 가 시작된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? PeekMessage() 함수는 프로그램에 대한 메시지가 없어도 즉시 리턴한다.

3
9

CHAPTER 11
? GetMessage
? 호출 스레드의 메시지 큐로부터 메시지를 받는다.
? BOOL GetMessage(
LPMSG lpMsg,
// 메시지 구조체의 주소
HWND hWnd,
// 윈도우의 핸들
UINT wMsgFilterMin,

// 첫번째 메시지

UINT wMsgFilterMax
);

// 마지막 메시지

? Parameters
스레드의 메시지 큐로부터 메시지 정보를 받는 MSG 구조체에 대한 포인터

?hWnd 메시지를 받는 윈도우를 기술한다.
Value Meaning
NULL GetMessage retrieves messages for any window that belongs to the
calling thread and thread messages posted to the calling thread via
PostThreadMessage.
?wMsgFilterMin

전달 받은 메시지 값 중 가장 적은 정수 값을 기술한다.

?wMsgFilterMax

전달 받은 메시지 값 중 가장 큰 정수 값을 기술한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?lpMsg

4
0

? PeekMessage
? 메시지를 위하여 스레드 메시지 큐를 검사한다.
? 메시지가 위치한 곳의 구조체를 기술한다.
? BOOL PeekMessage(
LPMSG lpMsg,
// 메시지에 대한 구조체를 가리키는 포인터
HWND hWnd,
// 윈도우 핸들
UINT wMsgFilterMin, // 첫 번째 메시지
UINT wMsgFilterMax // 마지막 메시지
UINT wRemoveMsg
// 제거 플래그
);
? Parameters
?lpMsg 윈도우 기반 어플리케이션 큐로부터 메시지 정보를 포함하는
MSG 구조체를 가리킨다.
?hWnd 메시지에 대한 윈도우를 기술한다.
?wMsgFilterMin 검사된 메시지의 범위 내에서 첫 번째 메시지의 값을 기술한다.
?wMsgFilterMax 검사된 메시지의 범위 내에서 마지막 메시지의 값을 기술한다.
?wRemoveMsg
메시지를 처리하는 방법을 기술한다.
Value
Meaning
PM_NOREMOVE 메시지가 PeekMessage에 의해 처리된후 큐에서 제거되지 않는다.
PM_REMOVE
메시지가 PeekMessage에 의해 처리된후 큐에서 제거된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 11

4
0

CHAPTER 11
? TranslateMessage
? 가상 키(virtual-key) 메시지들을 문자로 변환한다.
? BOOL TranslateMessage(
CONST MSG *lpMsg
);

// 메시지 구조체의 주소

? Parameters
?lpMsg

GetMessage나 PeekMessage사용에 의해 호출 스레드의 메시지 큐로부터
받은 메시지 정보를 담고 있는 MSG구조체를 가리킨다.

? DispatchMessage
? 메시지를 윈도우 프로시저로 디스패치 한다.
? LONG DispatchMessage(
// 메시지 구조체에 대한 포인터

(C) 1998 Sang Il Kim

CONST MSG *lpmsg
);
? Parameters
?lpmsg

메시지를 포함하고 있는 MSG구조체를 가리킨다.
Visual C++ Programming

4
0

CHAPTER 11
? The WM_CHAR message is posted to the window with the keyboard focus when a
WM_KEYDOWN message is translated by the TranslateMessage function.
WM_CHAR contains the character code of the key that was pressed.
? WM_CHAR
chCharCode = (TCHAR) wParam; // character code
lKeyData = lParam;
// key data
? Parameters
?chCharCode Value of wParam. Specifies the character code of the key.
?lKeyData
Value of lParam. Specifies the repeat count, scan code, extended-key flag,
context code, previous key-state flag, and transition-state flag,
Value
Description
0-15
Specifies the repeat count. The value is the number of times the keystroke is
repeated as a result of the user holding down the key.
16-23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24
Specifies whether the key is an extended key, such as the right-hand ALT and CTRL
keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an
extended key; otherwise, it is 0.
25-28 Reserved; do not use.
29
Specifies the context code. The value is 1 if the ALT key is held down while the
key is pressed; otherwise, the value is 0.
30
Specifies the previous key state. The value is 1 if the key is down before the
message is sent, or it is 0 if the key is up.
31
Specifies the transition state. The value is 1 if the key is being released, or it is 0 if
the key is being pressed.

Visual C++ Programming

(C) 1998 Sang Il Kim

? WM_CHAR

4
0

CHAPTER 11
? 타이머
? 타이머는 간격 파라미터를 이용하여 CWnd 멤버 함수 SetTimer()를 호출한 후
발생되는 WM_TIMER에 대한 메시지 핸들러 함수를 ClassWizard를 이용해서
작성하면 된다.
? 타이머는 정수로 식별된다.
? 타이머 메시지가 이미 존재하고 있는 경우 윈도우는 타이머 메시지를 메시지 큐에
넣지 않는다.
? 예제 EX11A

? 계산 처리 과정에서 제어권을 양보하지 않으면 WM_TIMER 메시지는 처리되지
않는다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 계산 루프 내에서 제어권을 양보함으로써 메시지가 처리되도록 허용하고 타이머
핸들러는 계산 파라미터를 토대로 Progress Control을 갱신한다.

4
0

CHAPTER 11
? CWnd::SetTimer
? 콜백 프로시저를 호출하는 타이머를 설정하거나 WM_TIMER 메시지를 지정한
간격으로 윈도우에 보낸다.
? UINT SetTimer( UINT nIDEvent, UINT nElapse,
void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );
? Parameters
?nIDEvent 타이머 식별자(Timer의 ID)
?nElapse

타이머 메시지를 보내는 간격 (1/1000초, 1000millisecond=1초)

?lpfnTimer 지정한 시간에 호출되는 타이머 콜백 함수에 대한 포인터.
이 파라미터가 NULL이면, WM_TIMER 메시지는 어플리케이션의

? ASSERT
? ASSERT( booleanExpression )
? Parameters
?booleanExpression
Specifies an expression (including pointer values) that
evaluates to nonzero or 0.
Visual C++ Programming

(C) 1998 Sang Il Kim

메시지 큐에 위치하게되고, CWnd 객체에 의해 처리된다.

4
0

CHAPTER 11
? CWnd::EnableWindow
? 윈도우를 사용할 수 있게 하거나 사용할 수 없게 한다.
? 이 윈도우는 리턴 되기 전에 윈도우에 WM_ENABLE 메시지를 보낸다.
? BOOL EnableWindow( BOOL bEnable = TRUE );
? Parameters
?bEnable TRUE, 윈도우가 사용할 수 있게 한다.
FALSE, 윈도우가 사용할 수 없게 한다.
? volatile
? volatile 키워드는 수행중인 프로그램뿐만 아니라 인터럽트에 의해 액세스 될 수 있는
변수의 임시성에 대해 컴파일러에게 알려준다.
? volatile declarator
? int volatile nVint;
(C) 1998 Sang Il Kim

? CWnd::OnTimer
? WM_TIMER 메시지에 대한 핸들러
? afx_msg void OnTimer( UINT nIDEvent );
? Parameters
?nIDEvent 타이머의 식별자
Visual C++ Programming

4
0

CHAPTER 11
? WM_TIMER
? The WM_TIMER message is posted to the installing thread’s message queue
when a timer expires.
? WM_TIMER
wTimerID = wParam;
// 타이머 식별자
tmprc = (TIMERPROC *) lParam; // 타이머 콜백(callback) 함수의 주소
? Parameters
?wTimerID
?tmprc

Value of wParam.
Value of lParam.

? SetTimer 함수로 생성된 타이머를 파괴한다.
? BOOL KillTimer( int nIDEvent );
? Parameters
?nIDEvent 파괴되는 타이머의 ID.
이 ID는 타이머를 생성한 SetTimer 호출에서 리턴되는 ID.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::KillTimer

4
0

CHAPTER 11
? On-Idle 처리
? On-Idle 처리는 어플리케이션의 메시지 큐가 사용중인 상태에서 큐가
비워질 때마다 수행된다.
? 사용자가 아무것도 하지 않는 상태에서는 어떤 메시지도 발생하지 않으므로
On-Idle 처리가 수행되지 않는다.
? OnIdle() 함수를 override 하면 메시지 큐가 비워질 때마다 작성된 코드가
호출은 되지만, 메시지들의 상수 stream이 없으면 코드가 연속적으로 호출되지
않는다.
? OnIdle()을 override할 때는 기초 클래스의 OnIdle()을 호출해야 한다.

? 사용자가 모달 다이얼로그 박스를 사용하거나 메뉴를 사용하고 있을 때
OnIdle()은 호출되지 않는다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 기초 클래스의 OnIdle()을 호출하지 않으면 툴바 버튼이 갱신되지 않고,
임시 객체도 제거되지 않는다.

4
0

CHAPTER 11
? 스레드(Thread)
? 프로세스 스케줄링의 부담을 줄여 성능을 향상시키기 위한 프로세스의 다른
표현방식
? 실행 스레드는 Win32가 CPU 시간을 부여하는 기본적인 요소이다.
? 각각의 스레드는 여러 개의 구조들을 사용해서 다음 프로세서 time slice를
기다리는 동안 자신의 컨텍스트를 저장해 둔다.
? 스레드의 컨텍스트
?스레드의 하드웨어 레지스터
?커널 스택
?환경 블록

? Process - 실행중인 프로그램
? 모든 프로세스는 Thread라는 개별적인 실행 경로를 갖는다.
? 한 프로세스에 속하는 모든 스레드는 그 프로세스의 코드와 자원,
가상 주소 공간, 전역 변수들을 공유한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?소유자 프로세서의 주소 공간 내의 사용자 스택

4
0

CHAPTER 11
? 스레드의 종류
? Worker thread
?윈도우를 갖지 않으므로 메시지를 처리할 필요가 없다.
?배경에서 어떤 작업을 수행하는데 사용한다.
?많은 시간을 필요로 하는 계산 처리에 적합하다.
? User interface thread
?윈도우를 가지고 있어 자신의 고유한 메시지 루프가 있다.
?사용자 입력을 처리하는 경우와 사용자에 의해서 발생된 이벤트와
메시지에 대해서 응답하는데 사용한다.

? 단일 스레드 어플리케이션은 한 개의 스레드(메인 스레드)를 갖는다.
? MFC에서는 CWinThread로 부터 CWinApp가 파생된다.
(어플리케이션이 바로 스레드이다.)
Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC 라이브러리(CWinThread)는 두 종류를 모두 지원한다.

4
1

CHAPTER 11
? 작업자 스레드 작성과 스레드 시작하기
? 작업자 스레드를 사용하기 위해서는 먼저 스레드의 메인 프로그램을 위한
전역 함수를 작성해야 한다.
? 전역 함수는 UINT를 리턴 해야 하며 파라미터로 LPVOID 형 값을 가져야 한다.
? 스레드가 계산처리를 수행한 후 전역함수가 리턴될 때 스레드는 종료되며
프로세스가 종료될 때도 종료된다.
전역 함수에게
? 프로그램에서 스레드 호출
전달되는 32비트 값
CWinThread* pThread =
AfxBeginThread( ComputeThreadProc, GetSafeHwnd(),
THREAD_PRIORITY_NORMAL);
? 스레드의 코드
UINT ComputeThreadProc( LPVOID pParam)

스레드의
우선순위
(C) 1998 Sang Il Kim

{
// 스레드 처리작업
return 0;
}
Visual C++ Programming

4
11

CHAPTER 11
? CWinThread 클래스 데이터 멤버
설명

m_bAutoDelete

CWinThread 객체의 하위 스레드가 종료될 때 CWinThread
객체도 함께 종료될 것인지를 지정하는 BOOL Flag

m_hThread

현재 스레드에 대한 핸들

m_nThreadID

현재 스레드의 ID

m_pMainWnd

응용 프로그램의 중심 창을 가리키는 포인터

m_pActiveWnd

OLE 서버가 인플레이스(in-place) 활성화되어 있을 때(자신이
직접 창을 생성했을 때) 컨테이너 응용 프로그램의 중심 창을
가리키는 포인터
(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
1

CHAPTER 11
메소드

설명

GetMainWnd()

스레드의 중심 창을 가리키는 포인터를 취한다.

GetThreadPriority()

현재 스레드의 우선순위를 취한다.

ResumeThread()

스레드의 계수(suspend count)를 감소시킨다.

SetThreadPriority()

현재 스레드의 우선 순위를 설정한다.

SuspendThread()

스레드의 계수(suspend count)를 증가시킨다.

(C) 1998 Sang Il Kim

? CWinThread 클래스 메소드

Visual C++ Programming

4
1

CHAPTER 11
메소드

설명

ExitInstance()

스레드가 종료되었을 때 정리하기 위한 재정의

InitInstance()

스레드 인스턴스 초기화를 수행하기 위한 재정의

OnIdle()

스레드 특정 유휴 시간 처리를 수행하기 위한 재정의

PreTranslateMessage()

Win32 API 함수인 TranslateMessage() 및 DiapatchMessage()
로 메시지를 전달하기 전에 미리 메시지를 여과한다.

IsIdleMessage()

특수 메시지를 점검한다.

ProcessWndProcException()

스레드의 메시지 및 명령 처리기에 의해서 던져진 모든
처리되지 않는 예외들을 가로챈다.

ProcessMessageFilter()

일부 메시지가 응용 프로그램에 도달하기 전에 그 메시지를
가로챈다.

Run()

메시지 펌프를 포함하는 스레드에 대한 제어 함수.
기본 메시지 루프를 사용자 정의하기 위한 재정의
Visual C++ Programming

(C) 1998 Sang Il Kim

? 가상 CWinThread 클래스 메소드

4
1

CHAPTER 11
? 전역 스레드 보조 함수
설명

AfxBeginThread()

새로운 스레드를 생성한다.

AfxGetThread()

현재 실행되고 있는 스레드를 포함하는 CWinThread 객체를
가리키는 포인터를 취한다. 포인터를 가리키고자 하는
스레드 내부로부터 이 함수를 호출해야 한다.

AfxEndThread()

스레드의 실행을 종료한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
1

CHAPTER 11
? AfxBeginThread()
? 동적으로 CWinThread 객체를 구축하고 스레드를 시작한다.
? Worker thread 생성
?CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc,

LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
? User interface thread 생성
?CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,

UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

Visual C++ Programming

(C) 1998 Sang Il Kim

int nPriority = THREAD_PRIORITY_NORMAL,

4
1

CHAPTER 11
? AfxBeginThread()
매개변수

설명
Worker 스레드를 제어하는 함수를 가리키는 포인터. 값이 NULL일 수 없다.

pThreadClass

CWinThread로부터 파생된 객체의 RUNTIME_CLASS

pParam

Worker 스레드를 제어하는 함수로 전달되는 매개변수

nPriority

새로운 스레드의 우선 순위 수준. 이 값이 ‘0’(NULL)이라면, 새로운
스레드는 자신을 생성한 스레드와 동일한 우선 순위를 가진다.
스레드의 프로세스의 우선 순위 클래스와 함께 이 값은 스레드의
기본 우선 순위 수준을 결정한다.

nStackSize

새로운 스레드의 스택 크기(단위:byte)를 지정한다. 이 값이 ‘0’(NULL)
이라면, 새로운 스레드는 자신을 호출한 스레드와 동일한 크기의
스택 크기를 가진다.

dwCreateFlags

스레드의 생성을 제어하는 추가적인 플래그를 지정한다. 이 플래그는 다음의
두 가지 값 중에서 한 가지를 값으로 가진다. CREATE_SUSPENDED (이 경우에
스레드는 서스펜드 계수가 1이기 때문에 ResumeThread()가 호출될 때까지
실행되지 않는다.) 또는 ‘0’(NULL, 생성되자마자 스레드를 실행한다.)

스레드에 대한 보안 속성들을 지정하는 Win32 SECURITY_ATTRIBUTES
lpSecurityAttrs 구조를 가리키는 포인터. 이 값이 ‘0’(NULL)이라면, 새로운 스레드는 자신을
생성한 스레드와 동일한 보안 속성을 가진다.
Visual C++ Programming

(C) 1998 Sang Il Kim

pfnThreadProc 다음과 같이 선언한다. UINT MyControllingFunction( LPVOID pParam );

4
1

CHAPTER 11
? SetThreadPriority
? 스레드의 우선순위를 설정한다.
? BOOL SetThreadPriority( int nPriority );
? Parameters
?nPriority

스레드의 우선순위

? CWinThread::ResumeThread
? 정지된 스레드의 실행을 다시 시작한다.
? 스레드에 대한 정지 카운트를 하나씩 줄인다.
? 정지 카운트가 0이면, 스레드는 실행을 다시 시작한다.
? DWORD ResumeThread( );
(C) 1998 Sang Il Kim

? Return Value
성공하면 이전 정지 카운트. 실패하면 0xFFFFFFFF

Visual C++ Programming

4
1

CHAPTER 11
우선순위 수준

설명

THREAD_PRIORITY_ABOVE_NORMAL

우선 순위 클래스에 대한 정상 우선 순위보다 1점 높은 것을
가리킨다.

THREAD_PRIORITY_BELOW_NORMAL

우선 순위 클래스에 대한 정상 우선 순위보다 1점 낮은 것을
가리킨다.

THREAD_PRIORITY_HIGHEST

우선 순위 클래스에 대한 정상 우선 순위보다 2점 높은 것을
가리킨다.

THREAD_PRIORITY_LOWEST

우선 순위 클래스에 대한 정상 우선 순위보다 2점 낮은 것을
가리킨다.

THREAD_PRIORITY_IDLE

IDLE_PRIORI TY_CLASS, NORMAL_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS 프로세스에 대해서는 기본
우선 순위 수준 1을 가리키며, REALTIME_PRIORITY_CLASS
프로세스에 대해서는 기본 우선 순위 수준 16을 가리킨다.

THREAD_PRIORITY_NORMAL

우선 순위 클래스에 대한 정상 우선 순위를 가리킨다.

THREAD_PRIORITY_TIME_CRITICAL

IDLE_PRIORI TY_CLASS, NORMAL_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS 프로세스에 대해서는 기본
우선 순위 수준 15을 가리키며, REALTIME_PRIORITY_CLASS
프로세스에 대해서는 기본 우선 순위 수준 31을 가리킨다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 스레드 우선 순위 수준

4
1

CHAPTER 11
? 메인 스레드(User interface thread)는 작업자 스레드와 어떻게 통신하는가?
? 전역 변수를 사용한다. (모든 스레드는 전역 변수를 액세스 할 수 있다.)
? UINT ComputeThreadProc( LPVOID pParam )
{
g_nCount = 0;
while( g_nCount < 100 ) {
// 계산을 수행한다.
::InterlockedIncrement((long*) &g_nCount);
}
}
? InterlockedIncrement() 함수는 변수가 증가되는 동안 액세스하려는 다른
스레드를 묶으므로 메인 스레드는 작업자 스레드를 안전하게 중지시킬 수 있다.
Visual C++ Programming

(C) 1998 Sang Il Kim

return 0;

4
2

CHAPTER 11
? 작업자 스레드는 메인 스레드(User interface thread)와 어떻게 통신하는가?
? 메인 스레드는 윈도우를 갖는다.
? 작업자 스레드는 윈도우의 핸들을 갖는다.
? 작업자 스레드가 윈도우 핸들을 얻는 방법
?AfxBeginThread() 호출시 32비트 파라미터에 윈도우 핸들을 전달한다.

(C) 1998 Sang Il Kim

? 메인 스레드에 메시지를 보낼 때 PostMessage()로 메시지를 보낸다.

Visual C++ Programming

4
2

CHAPTER 11
? 예제 EX11B
? 계산이 메인 스레드 대신 작업자 스레드에서 이루어진다.
? 카운트 값은 전역 변수 g_nCount에 저장되며 다이얼로그 윈도우의
Cancel 버튼 핸들러에서 최대값으로 설정된다.
? 스레드가 종료될 때 다이얼로그 윈도우로 메시지를 보내면(PostMessage())
DoModal()이 종료되도록 한다.
? 소스 코드에서 g_nCount가 상수 최대값보다 커지면 함수(스레드)가
종료된다

? 예제 EX11C
? 두 개의 이벤트를 사용하여 메인 스레드와 작업자 스레드간을 동기화 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 함수는 종료되기 전에 다이얼로그 윈도우에 사용자 정의 메시지를 보낸다.

4
2

CHAPTER 11
? 스레드 스케줄링(Scheduling)
? 각각 서로 구별될 수 있도록 조치를 취하지 않는 한, 한 프로세스 내에서
실행되고 있는 각 스레드들이 서로를 구별하는 일은 거의 불가능하다.
? 프로세스 자원을 공유하는 스레드들의 경우 서로 다른 시간에 그 자원에
액세스할 수 있도록 프로세스간 통신의 한 형태를 사용해서 서로 스케줄링
해야 한다.
? 스레드의 활동을 적절히 스케줄링하는 데 실패할 경우에는 프로세스가
잠기는 dead lock 상황이 초래될 수도 있다.
? 이러한 상황을 방지하기 위해서 공유 자원에 액세스하는 스레드는 동기화
사용해서 자신의 실행을 다른 스레드의 실행과 동기화할 수 있다.
? 대기 함수는 스레드가 자신의 실행을 차단할 수 있도록 하며, 함수의
매개변수에 의해서 지정된 어떤 조건이 만족될 때까지는 반환되지 않는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

객체를 사용하는 대기함수(wait function)라고 하는 특별한 Win32 함수를

4
2

CHAPTER 11
? 스레드 동기화(Synchronization)
? 동기화란? 둘 또는 그 이상의 프로세스가 동시에 존재할 때, 프로세스에 대한
처리 순서를 결정
? 스레드는 잠자기(sleeping)를 통해 프로세스 내에서 다른 스레드들과 자신의
행동 사이에서 동기를 맞출 수 있다.
? 잠자기 전에 자신이 기다릴 특정 이벤트에 관하여 윈도우 시스템에 알린다.
? 잠자고 있는 스레드를 위해 이벤트를 찾는 것은 윈도우가 해야 할 일이다.
? 스레드가 요청한 이벤트가 발생할 때까지 스레드는 잠자게 된다.

스레드는 다시 실행을 계속하게 된다.
? 이때 스레드와 스레드 사이에 동기화가 이루어졌다고 이야기한다.
? 스레드 동기화는 특수 동기화 객체에 의해 이루어진다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 이벤트가 발생하면, Win32는 스레드에게 일어나라는 신호를 보내게 되고,

4
2

CHAPTER 11
실행 상태

깨어 있음
(awake)

봉쇄(block)

디스패치
(dispatch)
타이머 종료
(timer runout)

준비 상태

봉쇄 상태

잠자고 있음
(asleep)
(C) 1998 Sang Il Kim

깨어 있음
(awake)

깨움(wakeup)

◐ 프로세스의 상태전이(State Transition) ◑
Visual C++ Programming

4
2

CHAPTER 11
? 스레드 동기화 객체(Synchronization Object)
? 한 프로세스 내에서 실행되고 있는 복수의 스레드의 실행을 제어한다.
? 두 가지 상태 중에서 한 상태를 그 값으로 가진다.
?Signaled : 대기 함수가 반환할 수 있도록 한다.
?Nonsignaled : 대기 함수가 반환되지 않도록 한다.
? 하나 이상의 프로세스가 동일한 객체에 대해서 핸들을 가질 수 있으며,
그것 덕분에 프로세스간 동기화가 가능해진다.
? 동기화 객체에 의해서 제어되는 자원에 액세스하기 위해서 MFC는 “lock”
클래스에서 파생된 두 개의 CObject를 제공한다.
(C) 1998 Sang Il Kim

?CSingleLock, CMultiLock

Visual C++ Programming

4
2

CHAPTER 11
? 스레드 동기화 객체 (Synchronization Object)
? 상호배제(Mutex, Mutual exclusion)
?상호배제는 코드를 실행하기 위해 몇몇 공유 데이터에 대해 순간적으로 배타적인
제어권을 가지는 조그만 코드 조각이다.
?한번에 하나의 스레드만 데이터를 액세스 하도록 한다.
?임계영역 밖에 있는 프로세스가 임계영역에 들어가려는 다른 프로세스를 막아서는
안된다.
?임계영역에 들어가는 것이 무한정 연기되어서는 안된다.
? 세마포어(Semaphore)
?여러 개의 스레드가 자신의 데이터를 동시에 액세스하도록 허용하고 있다.
?Win32는 어느 스레드가 세마포어를 소유하고 있는지 알지 못하며, 세마포어 사용자의
자원 카운트만 유지하고 있다.
?하나의 프로세스에 속하는 스레드들에 의해서만 사용할 수 있다.
?한번에 하나의 스레드만 데이터를 액세스 하도록 한다.
? 이벤트(Event)
?이벤트는 스레드에게 언제 특정 작업을 수행할 것인가를 알려 주며, 다중 스레드가
부드럽게 흘러갈 수 있도록 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 임계영역(Critical Section)

4
2

CHAPTER 11
? 스레드 동기화를 위해 이벤트 사용하기
? 이벤트는 윈도우가 스레드 동기화를 위해 제공해 주는 커널 객체 타입이다.
? 프로세스 내에서 고유한 32비트 핸들로 정의된다.
? 프로세스와 스레드도 커널 객체이다.
? 이벤트의 종류
?수동(manual) 리셋 이벤트
?자동(automatic) 리셋 이벤트

? 이벤트의 상태
?시그널(signaled) 상태 (TRUE)
?비시그널(nonsignaled) 상태 (FALSE)

? 두 프로세스의 동기화를 위해서는 자동 리셋 이벤트가 적합하다.

? 이벤트를 전역 객체로 선언하면 다른 스레드에서도 이벤트에 쉽게 액세스
할 수 있다.
? 메인 스레드에서 작업자 스레드를 시작/종료하고자 할 경우 메인 스레드는
CEvent::SetEvent() 함수를 호출하여 적합한 이벤트를 “signal” 상태로 만들면
된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 메인 스레드가 “Signal”에 의해 작업자 스레드를 시작/정지 시키려면
“start”이벤트와 “kill”이벤트가 필요하다.

4
2

CHAPTER 11
? CEvent 클래스 메소드
메소드

설명

SetEvent()

이벤트를 사용 가능한 상태(시그널 상태)로 설정하며, 대기 스레드를
모두 release 한다.

PulseEvent()

이벤트를 사용 가능한 상태(시그널 상태)로 설정한 다음에 대기
스레드를 모두 release 하고,
이벤트를 다시 사용 가능하지 않은 상태(비시그널 상태)로 설정한다.

ResetEvent()

이벤트를 사용 가능하지 않은 상태(비시그널 상태)로 설정한다.

?수동(manual) 이벤트
CEvent 객체는 상대 메소드가 호출될 때까지 SetEvent() 또는 ResetEvent()에
의해서 설정된 현재의 상태에 머무른다.
?자동(automatic) 이벤트
CEvent 객체는 적어도 하나의 스레드가 release되면, 자동으로 사용 가능하지 않은
상태(비시그널 상태)로 되돌아간다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 이벤트의 종류

4
2

CHAPTER 11
? 스레드 블록킹
? 작업자 스레드가 이벤트의 시그널 상태가 될 때까지 단순히 실행을 일시 중지한다.
? 블록킹 호출은 메인 스레드(user interface thread)에 포함시키지 않도록 해야 한다.
? 메인 스레드가 블록킹되면 메시지를 처리할 수 없게 되고 프로그램은 느려진다.

? 임계구역 (Critical section)
? 두 프로세스 이상이 동시에 공유 데이터를 액세스 할 때 문제가 발생하는 부분
? 임계구역에 한 프로세스가 들어 있으면 다른 프로세스는 들어가면 안된다.(상호배제)
? 공유 데이터의 액세스를 통제하는데 적합하다.
? MFC에는 윈도우 임계구역 핸들을 랩(wrap)하는 CCriticalSection 클래스가 제공된다
? 생성자는 InitializeCriticalSection() 함수를 호출
(C) 1998 Sang Il Kim

? 제거자는 DeleteCriticalSection() 함수를 호출
? Lock() 멤버 함수와 Unlock() 멤버 함수는 EnterCriticalSection() 과
LeaveCriticalSection() 을 호출한다.
Visual C++ Programming

4
3

CHAPTER 11
? 전역 데이터를 보호하기 위한 CCriticalSection 클래스의 사용방법
? CCriticalSection g_cs;
int g_nCount;
void func()
{
g_cs.Lock();
g_nCount++;
g_cs.Unlock();

(C) 1998 Sang Il Kim

}

Visual C++ Programming

4
3

CHAPTER 11
? CMutex 객체 사용하기
? CMutex( BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL,

매개변수

설명

bInitiallyOwn

CMutex 객체를 생성하는 스레드가 초기에 뮤텍스가 제어할 자원에
대한 액세스 권한을 가지고 있는지의 여부를 지정한다.

lpszName

CMutex 객체의 이름.
뮤텍스를 복수의 프로세스가 사용해야 한다면, 이름을 반드시
부여해야 한다.

lpsaAttribute

Win32 SECURITY_ATTRIBUTES 구조에 정의되어 있는 바와 같은
뮤텍스 객체에 대한 보안 속성들

? CMutex, CSemaphore 클래스는 별도의 클래스 관련 메소드를 제공하지는 않지만,
CSyncObject 클래스로부터 Lock() 과 Unlock()은 그대로 상속해서 사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

LPSECURITY_ATTRIBUTES lpsaAttribute = NULL );

4
3

CHAPTER 11
? CSemaphore 객체 사용하기
? CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1,
LPCTSTR pstrName = NULL,

매개변수

설명

lInitialCount

세마포어에 대한 초기 사용 계수값. 이 값은 ‘0’과 같거나 커야 하며,
lMaxCount 보다는 작거나 같아야 한다.

lMaxCount

세마포어에 대한 최대 사용 계수값이며, ‘0’보다 커야 한다.

pstrName

세마포어의 이름.
세마포어를 복수의 프로세스가 사용해야 한다면, 반드시 이름을
부여해야 한다.

lpsaAttribute

Win32 SECURITY_ATTRIBUTES 구조에 정의되어 있는 바와 같은
세마포어 객체에 대한 보안 속성들
Visual C++ Programming

(C) 1998 Sang Il Kim

LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );

4
3

CHAPTER 11
? Win32 대기 함수(Wait Function)
함수

설명

WaitForSingleObject()

지정된 객체가 시그널 상태에 있을 경우나 지정된 시간
제한 기간이 초과되었을 경우에 반환된다.

WaitForStringObjectEx()

WaitForSingleObject()의 경우와 동일하지만, 시스템이
호출 스레드에 의해서 실행될 I/O 완료 루틴을 대기열에

저장할 때도 반환된다.
WaitForMultipleObjects()

WaitForMultipleObjectsEx()

하나 또는 모든 지정된 객체가 시그널 상태에 있을 경우
또는 지정된 시간 제한 기간이 초과되었을 경우에
반환된다.
WaitForMultipleObjects()의 경우와 동일하지만, 시스템이
호출 스레드에 의해서 실행될 I/O 완료 루틴을 대기열에

하나 또는 모든 지정된 객체가 시그널 상태에 있을 경우,
스레드의 입력 대기열에 지정된 타입의 입력이 들어온
MsgWaitForMultipleObjects()
경우, 또는 지정된 시간 제한 기간이 초과되었을 경우에
반환된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

저장할 때도 반환된다.

4
3

CHAPTER 11
? CSingleLock 클래스
? CSingleLock 객체는 다중 스레드 응용 프로그램 내의 자원이나 코드 부분에 대한
액세스 제어를 제공한다.
? CSingleLock이나 CMultiLock 객체는 CSyncObject 클래스로부터 파생된 동기화
객체를 기다리거나 release하는데 사용해야 한다.
? CSingleLock 객체는 한 번에 하나의 객체만 서비스해야 하는 경우에 사용한다.

메소드

설명

IsLocked()

지정된 동기화 객체가 잠겨 있는지의 여부를 결정한다.

Lock()

동기화 객체를 기다린다.

Unlock()

동기화 객체를 release한다.

(C) 1998 Sang Il Kim

? CSingleLock 클래스 메소드

Visual C++ Programming

4
3

CHAPTER 11
? CSingleLock 객체를 사용하기 위한 순서
1. 제어할 자원의 클래스 메소드에서 CSingleLock 생성자를 호출한다.
2. 그 자원이 사용 가능한지(시그널 상태인지)의 여부를 결정하기 위해서
Lock() 메소드를 호출한다.
3. 자원이 사용 가능하다면, 메소드의 나머지 부분을 계속해서 실행하지만,
그렇지 않을 경우에는 자원이 release될 때까지 지정된 시간 초과 기간동안
대기하든지 아니면 실패를 반환한다.
4. 스레드가 자원의 사용을 마치면, Unlock() 메소드를 호출하거나
(C) 1998 Sang Il Kim

(CSingleLock 객체를 다시 사용해야 한다면) CSingleLock 객체가 소멸되는
것을 허락한다.

Visual C++ Programming

4
3

CHAPTER 11
? CMultiLock 클래스
? CMultiLock 객체는 다중 스레드 응용 프로그램 내의 자원이나 코드 부분에 대한
액세스 제어를 제공한다.
? CSingleLock이나 CMultiLock 객체는 CSyncObject 클래스로부터 파생된 동기화
객체를 기다리거나 release하는데 사용해야 한다.
? CMultiLock 객체는 복수의 객체를 서비스해야 하는 경우에 사용한다.
? CMultiLock 클래스 메소드
설명

IsLocked()

배열 내의 지정된 동기화 객체가 잠겨 있는지의 여부를 결정한다.

Lock()

동기화 객체들로 이루어진 배열을 기다린다.

Unlock()

소유된 동기화 객체를 release한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
3

CHAPTER 11
? CMultiLock 객체를 사용하기 위한 순서
1. 기다릴 동기화 객체들의 배열을 생성한다.
2. 제어할 자원의 클래스 메소드 내로부터 CMultilock() 생성자를 호출한다.
3. 그 자원이 사용 가능한지(시그널 상태인지)의 여부를 결정하기 위해서
Lock() 메소드를 호출한다.
4. 자원이 사용 가능하다면, 메소드의 나머지 부분을 계속해서 실행하지만,
그렇지 않을 경우에는 자원이 release될 때까지 지정된 시간 초과 기간동안
대기하든지 아니면 실패를 반환한다.
(CMultilock 객체를 다시 사용해야 한다면) CMultilock 객체가 소멸되는
것을 허락한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

5. 스레드가 자원의 사용을 마치면, Unlock() 메소드를 호출하거나

4
3

CHAPTER 11
? CSyncObject 클래스
? CSingleLock 및 CMultiLock 클래스는 모두 그들의 생성자 내에서 CSyncObject
유형의 동기화 객체를 사용한다.

클래스

설명

CCriticalSection

Win32 임계영역 객체를 포함한다.

CEvent

Win32 이벤트 객체를 포함한다.

CMutex

Win32 뮤텍스 객체를 포함한다.

CSemaphore

Win32 세마포어 객체를 포함한다.
(C) 1998 Sang Il Kim

? MFC 동기화 클래스

Visual C++ Programming

4
3

CHAPTER 11
? 지정된 객체가 시그널 상태에 있을 경우나 지정된 시간 제한 기간이 초과되었을
경우에 반환된다.
? DWORD WaitForSingleObject(
HANDLE hHandle,
// handle of object to wait for
DWORD dwMilliseconds
// time-out interval in milliseconds
);
? Parameters
?hHandle
객체를 식별한다.
?dwMilliseconds 타이머 메시지를 보내는 간격 (1/1000초, 1000millisecond=1초).
이 함수는 객체가 비시그널 상태에 있을 경우라도, 시간이 경과되면
반환된다.
이 함수는 dwMilliseconds가 0이면, 객체의 상태를 검사하고 즉시 반환된다.
dwMilliseconds가 INFINITE이면, 이 함수의 time-out 간격이 경과되지
않는다.
Value
Meaning
WAIT_ABANDONED The specified object is a mutex object that was not released by the
thread that owned the mutex object before the owning thread
terminated. Ownership of the mutex object is granted to the calling
thread, and the mutex is set to nonsignaled.
WAIT_OBJECT_0
0이면 객체의 상태는 시그널(signaled)이 된다.
WAIT_TIMEOUT
time-out 간격이 경과되면, 객체의 상태는 비시그널(nonsignaled)이 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? WaitForSingleObject()

4
4

CHAPTER 11
? CComMultiThreadModel::Increment
? static ULONG Increment( LPLONG p );
? Return Value
If the result of the increment is 0, then Increment returns 0.
If the result of the increment is nonzero, the return value is also
nonzero but may not equal the result of the increment.

(C) 1998 Sang Il Kim

? Parameters
?p
[in] Pointer to the variable to be incremented.

Visual C++ Programming

4
4

아담스의 편지

(C) 1998 Sang Il Kim

존 퀸시 아담스는
메사추세츠에 살고 있는
자신의 딸에게 이렇게 편지했다.
“내 딸아!
너의 남편감으로는 정직한 사람을 구하고,
계속 그가 정직하도록 해주어라.
편하게 살 수 있을 만큼
부유한가 하는 것은 중요한 것이 아니다.
다른 어떤 여건보다도
‘존경할만한 도덕적인 성품’이 가장 중요하다.
다른 어떤 위대함보다
영혼의 위대함을 생각하고,
다른 어떤 부함보다
마음의 부함을 생각하라.”

Visual C++ Programming

4
4

CHAPTER 12

(C) 1998 Sang Il Kim

메뉴, 키보드 가속기,
리치 에디트 컨트롤, 속성 시트

Visual C++ Programming

4
4

CHAPTER 12
? 메인 프레임 윈도우와 도큐먼트 클래스
? 어플리케이션 프레임워크는 프레임에서 뷰로 메시지를 전달함으로써
프레임과 뷰 간의 상호작용을 제어한다.
타이틀바
메뉴바
툴바
SDI 메인
프레임 윈도우

차일드
윈도우

(C) 1998 Sang Il Kim


뷰 윈도우
윈도우

상태바
◐ SDI 메인 프레임 윈도우에 위치하는 차일드 윈도우 ◑
Visual C++ Programming

4
4

CHAPTER 12
? 메인 프레임 윈도우와 도큐먼트 클래스
? MainFrm.h, MainFrm.cpp - CFrameWnd 클래스에서 파생된 메인 프레임 윈도우
클래스(CMainFrame)의 코드가 포함되어 있다.
? ex12aDoc.h, ex12aDoc.cpp - CDocument클래스에서 파생된 어플리케이션의
도큐먼트 클래스(CEx12aDoc)의 코드가 포함되어 있다.
? 뷰 객체
?반드시 하나의 도큐먼트 객체를 가지고 있다.
?CView에서 상속된 GetDocument() 멤버 함수는 뷰와 연결된 도큐먼트 객체의
포인터를 리턴한다.
? 윈도우 메뉴 ( DevStudio\Vc\mfc\include\afxres.h )
? 메뉴 아이템이 보조 팝업 메뉴와 결합되면 메뉴 아이템에 오른쪽 방향을 가리키는
? 메뉴 아이템은 속성 다이얼로그에서 모든 특성을 정의하고 정의된 결과는
어플리케이션의 리소스 스크립트(RC) 파일에 저장된다.
? 메뉴 아이템은 resource.h 파일에 정의된 ID_FILE_OPEN 등과 같은 ID와 결합된다.
? 프롬프트 - 문자열 리소스의 공통 ID에 의해 메뉴 아이템과 연결된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

화살표가 표시된다.

4
4

CHAPTER 12
? 키보드 가속기
? 키보드 가속기 리소스는 명령 ID와 연결된 조합키 테이블로 구성된다.
?Edit메뉴의 Copy메뉴 아이템 (명령 ID로 ID_EDIT_COPY를 가진)은 키보드 가속기
엔트리를 통해 ? Ctrl+C? 키와 연결된다.

SDI어플리케이션

MDI어플리케이션

①뷰
② 도큐먼트
③ SDI 메인 프레임 윈도우
④ 어플리케이션

①뷰
② 도큐먼트
③ MDI 자식 프레임 윈도우
④ MDI 메인 프레임 윈도우
⑤ 어플리케이션

(C) 1998 Sang Il Kim

? 명령 처리
? 명령 메시지는 메뉴 선택, 키보드 가속기, 툴바와 다이얼로그 버튼 클릭 등에 의해서
발생된다.
? CWnd::SendMessage()나 PostMessage() 함수의 호출에 의해서 명령 메시지를
보낼 수 있다.
? 각 메시지는 리소스 에디터에 의해 부여되는 #define 상수로 정의된다.
? 프로젝트의 resource.h 파일에는 어플리케이션의 고유한 ID들이 포함되어 있다.
? 어플리케이션 프레임워크가 메시지 핸들러를 찾는 순서

Visual C++ Programming

4
4

CHAPTER 12
? 명령 처리
? 명령 핸들러 함수를 만들기 위해서 필요한것
?함수 본체와 그 에 대응하는 메시지 맵 엔트리, 그리고 함수 원형 등이 필요하다.
? 메시지 맵
BEGIN_MESSAGE_MAP( CMyView, CView )
ON_COMMAND( IDM_ZOOM, OnZoom )
END_MESSAGE_MAP()
? 함수 본체
void CMyView::OnZoom()
{
// 명령 메시지 처리 코드
}

? 파생 클래스에서 명령 메시지 처리하기
? 명령 전달 시스템은 명령 메시지 처리가 일차적이고, 클래스 계층구조는 이차적이다.
? 기초 클래스 메시지 맵 함수 중의 하나를 오버라이드(Override)하려면 파생 클래스에
함수와 메시지 맵 엔트리 모두를 추가해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 함수 원형 ( CMyView 클래스 헤더 파일 ) // DECLARE_MESSAGE_MAP 매크로 앞에
?afx_msg void OnZoom();

4
4

CHAPTER 12
? 갱신 명령 사용자 인터페이스 핸들러
? 어플리케이션이 Edit 메뉴에 Clear All 아이템을 가진 경우, 지울 내용이 없을 때는
이 메뉴 아이템을 불가능하게 만들어야 한다.
? 어플리케이션의 내부적인 상태를 변경하는 모든 코드에 메뉴를 갱신하는 문장이
포함되어야 한다.
? MFC 라이브러리는 팝업 메뉴가 출력될 때마다 특수한 갱신 명령 UI 핸들러 함수를
호출하는 색다른 방법을 갖는다.
? 핸들러 함수의 파라미터는 해당하는 메뉴 아이템 포인터를 포함하는 CCmdUI 객체로,
이를 이용해서 메뉴 아이템의 상태를 변경한다.
?팝업 메뉴의 메뉴 아이템에만 적용된다.
?탑-레벨(top-level) 메뉴에는 적용되지 않는다.
? 함수 본체, 메시지 맵 엔트리, 함수 원형 등이 필요하다.
? 연결되어 있는 ID는 앞의 명령 메시지에 대해 사용한 것과 동일한 상수이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 갱신 명령 UI 핸들러

4
4

CHAPTER 12
? 갱신 명령 사용자 인터페이스 핸들러
? 메시지 맵
BEGIN_MESSAGE_MAP( CMyView, CView )
ON_UPDATE_COMMAND_UI( IDM_ZOOM, OnUpdateZoom )
END_MESSAGE_MAP()
? 함수 본체
void CMyView::OnUpdateZoom( CCmdUI* pCmdUI )
{
pCmdUI -> SetCheck( m_bZoomed ); // m_bZoomed - 뷰 클래스의 데이터 멤버
}
? 함수 원형 ( CMyView 클래스 헤더 파일 )
?DECLARE_MESSAGE_MAP 매크로 앞에 추가한다.
(C) 1998 Sang Il Kim

?afx_msg void OnUpdateZoom( CCmdUI* pCmdUI );

Visual C++ Programming

4
4

CHAPTER 12
? 다이얼로그에서 발생하는 명령 ( 버튼이 있는 팝업 다이얼로그의 경우 )
? 버튼에 의해 명령 메시지가 발생하려면
?버튼의 명령 ID값 : 0-8000과 0-DFFF 사이에 존재해야 한다.
? 리소스 에디터는 메뉴 아이템에 대해서 이와 동일한 ID범위를 적용한다.
? 뷰가 버튼 명령의 핸들러를 가지고 있다면 이 명령은 뷰에서 처리된다.
? ID가 0-8000에서 0-DFFF 사이의 범위에 있게 하려면
① Developer Studio의 심볼 에디터를 이용하여 ID를 입력한 다음,
② 버튼에 입력한 ID를 부여해야 한다.
? 어플리케이션 프레임워크의 내장 메뉴 항목
? 프린트는 선택적이므로 메시지 맵 엔트리가 CView 클래스에 정의되지 않고 CView에서
?ON_COMMAND ( ID_FILE_PRINT, CView::OnFilePrint )
?ON_COMMAND ( ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview )

Visual C++ Programming

(C) 1998 Sang Il Kim

파생된 뷰 클래스에 만들어진다.

4
5

CHAPTER 12
? 메뉴 아이템의 가능/불가능 상태
? 어플리케이션 프레임워크는 현재의 명령 경로상에서 명령 메시지 핸들러를 발견하지
못하면 메뉴 아이템을 불가능 상태로 만든다.
? CFrameWnd 클래스의 데이터 멤버 m_bAutoMenuEnable을 False로 설정하면 위의
기능을 없앨 수 있다. (the default)
? 한 도큐먼트에 두 개의 뷰가 연결되어 있는 상태에서 첫번째 뷰 클래스만이
IDM_ZOOM에 대한 명령 메시지 핸들러를 가지고 있다면 Zoom 메뉴 아이템은 첫번째
뷰가 활성화될 때만 가능한 상태가 된다.
? MFC 텍스트 편집 옵션
? 윈도우는 두 가지 텍스트 편집툴을 제공한다.
(C) 1998 Sang Il Kim

?에디트 컨트롤
?리치 에디트 컨트롤

Visual C++ Programming

4
5

CHAPTER 12
? MFC 텍스트 편집 옵션
? CEditView 클래스
?텍스트 크기는 64KB로 제한
?폰트를 혼합하여 사용할 수 없다.
?윈도우 서브 클래싱(subclassing)과 같은 다중 상속은 존재 하지 않는다.
?Edit 메뉴의 Cut, Copy, Paste 메뉴 아이템이 활성화 되어 있다.
? CRichEditView 클래스
?혼합 포맷들과 많은 양의 텍스트들을 입력할 수 있도록 지원해 준다.
ActiveX 컨테이너 어플리케이션을 구현할 수 있도록 설계되어 있다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?CRichEditDoc, CRichEditCntrItem 클래스와 함께 사용되어 완전한

4
5

CHAPTER 12
? CRichEditCtrl(서식 있는 편집 컨트롤) 클래스 (EX12A)

? CView에서 파생된 뷰 클래스를 사용하며 뷰의 클라이언트 영역에 뷰의 크기가
변함에 따라 크기가 조정되는 리치 에디트 컨트롤을 출력한다.
? CRichEditCtrl 클래스 구조

? MFC는 CRichEditCtrl 객체가 생성될 때 그 객체에 자동으로 윈도우 서식 있는 편집
공용 컨트롤을 붙인다.

? 메소드 프로토타입을 포함한 CRichEditCtrl 객체를 정의하는 모든 클래스 구조
(DevStudio\Vc\mfc\include\Afxcmn.h 812라인에 정의되어 있다.)
? CRichEditCtrl의 클래스 메소드
행 관련 메소드
문자 선택 메소드
문자 서식 메소드

(C) 1998 Sang Il Kim

?
?
?
?
?
?

편집 메소드
클립보드 메소드
일반적인 목적의 메소드
Visual C++ Programming

4
5

CHAPTER 12

메소드

설명

GetLineCount()

CRichEditCtrl 객체에서 줄의 수를 얻는다.

GetLine()

CRichEditCtrl 객체로부터 문자의 줄을 얻는다.

GetFirstVisibleLine()

CRichEditCtrl 객체에서 최상위의 보이는 줄을 결정한다.

LineIndex()

CRichEditCtrl 객체에서 특정 줄의 문자 색인을 얻는다.

LineFromChar()

어느 줄에 특정 문자가 있는지 결정한다.

LineLength()

CRichEditCtrl 객체에서 특정 줄의 길이를 얻는다.

LineScroll()

CRichEditCtrl 객체에서 문자를 스크롤한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CRichEditCtrl의 행 관련 메소드

4
5

CHAPTER 12
? CRichEditCtrl의 텍스트 선택 메소드
설명

Clear()

현재 선택된 것을 지운다.

GetSel()

현재 선택된 텍스트의 시작 위치와 끝 위치를 얻는다.

GetSelectionType()

현재 선택된 텍스트에서 내용의 유형을 얻는다.

GetSelText()

현재 선택된 텍스트를 얻는다.

HideSelection()

현재 선택된 텍스트를 보이거나 숨긴다.

ReplaceSel()

현재 선택된 텍스트를 지정된 텍스트로 대체한다.

SetSel()

선택한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
5

CHAPTER 12

메소드

설명

GetDefaultCharFormat()

현재의 기본 문자 형식 특성을 얻는다.

GetParaFormat()

현재 선택한 문자의 문단 형식 특성을 얻는다.

GetSelectionCharFormat()

현재 선택한 문자에서 문자 형식 특성을 얻는다.

SetDefaultCharFormat()

현재의 기본 문자 형식 특성을 설정한다.

SetParaFormat()

현재 선택한 문자의 문단 형식 특성을 설정한다.

SetSelectionCharFormat()

현재 선택한 문자에서 문자 형식 특성을 설정한다.

SetWordCharFormat()

현재의 단어에서 문자 형식 특성을 설정한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CRichEditCtrl의 텍스트 서식 메소드

4
5

CHAPTER 12
? CRichEditCtrl의 편집 메소드
설명

CanUndo()

편집 작업이 취소될지 안될지를 결정한다.

EmptyUndoBuffer()

CRichEditCtrl 객체의 취소 플래그를 새로이 설정한다.

StreamIn()

입력 스트림으로부터 텍스트를 삽입한다.

StreamOut()

출력 스트림에서 CRichEditCtrl 객체의 텍스트를 저장한다.

Undo()

마지막으로 편집된 작업을 취소한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
5

CHAPTER 12
? CRichEditCtrl의 클립보드 메소드
설명

CanPaste()

클립보드의 내용이 서식 있는 편집 컨트롤로 전달될지 아닐지를
검사한다.

Copy()

현재 선택된 텍스트를 클립보드로 복사한다.

Cut()

현재 선택된 텍스트를 클립보드로 잘라낸다.

Paste()

클립보드의 내용을 서식 있는 편집 컨트롤에 삽입한다.

PasteSpecial()

클립보드의 내용을 지정된 데이터 포맷을 사용하여 서식 있는
편집 컨트롤에 삽입한다.
(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
5

CHAPTER 12
메소드

설명

DisplayBand()

CRichEditCtrl 객체의 내용의 일부를 출력한다.

FindText()

CRichEditCtrl 객체 내의 문자의 위치를 잡는다.

FormatRange()

대상 출력 장치를 위해 일정 범위 문자의 형식을 맞춘다.

GetCharPos()

CRichEditCtrl 객체 내에서 특정 문자의 위치를 얻는다.

GetEventMask()

CRichEditCtrl 객체에 대한 이벤트 마스크를 얻는다.

GetLimitText()

사용자가 CRichEditCtrl 객체에 입력할 수 있는 텍스트의
양에 대한 한계 값을 얻는다.

GetModify()

마지막으로 저장한 이후에 CRichEditCtrl 객체의 내용을
수정했는지 여부를 결정한다.

GetRect()

CRichEditCtrl 객체에 대한 포맷 직사각형을 얻는다.

GetTextLength()

CRichEditCtrl 객체의 텍스트의 길이를 얻는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CRichEditCtrl의 일반적인 목적의 메소드

4
5

CHAPTER 12
? CRichEditCtrl의 일반적인 목적의 메소드
메소드

설명

LimitText()

사용자가 CRichEditCtrl 객체에 입력할 수 있는 텍스트의 양을
제한한다.

RequestResize()

CRichEditCtrl 객체의 크기를 재조정하기를 요청하는 통보를
그 객체가 부모 창에게 보내도록 만든다.

SetEventMask()

CRichEditCtrl 객체의 이벤트 마스크를 설정한다.

SetModify()

CRichEditCtrl 객체의 수정 플래그를 설정하거나 지운다.

SetOptions()

CRichEditCtrl 객체의 옵션을 설정한다.

SetReadOnly()

CRichEditCtrl 객체의 읽기 전용 옵션을 설정한다.

SetRect()

CRichEditCtrl 객체의 포맷 직사각형을 설정한다.

SetTargetDevice()

CRichEditCtrl 객체의 대상 출력 장치를 설정한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

SetBackgroundColor() CRichEditCtrl 객체의 배경색을 설정한다.

4
6

CHAPTER 12
? CRichEditCtrl 생성하고 초기화하기
1. 클래스 생성자 CRichEditCtrl::CRichEditCtrl() 를 호출하여 객체를 할당한다.
2. CRichEditCtrl::Create() 메소드를 호출하여 CRichEditCtrl 객체를 초기화하고,
그 객체에 윈도우 서식 있는 편집 공용 컨트롤을 붙인다.
? CRichEditCtrl::Create()
? BOOL Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID);
? Parameter
?dwStyle

: 컨트롤에서 사용하는 스타일의 조합을 지정한다.

?rect

: 컨트롤의 크기와 위치를 지정한다.

?nID

(C) 1998 Sang Il Kim

?nParentWnd : 컨트롤의 부모 창을 지정한다.
: 컨트롤의 컨트롤 식별자를 지정한다.

Visual C++ Programming

4
6

CHAPTER 12
? CRichEditCtrl 사용하기
1. 문단 형식 및 문자 형식을 정의하기 위해 PARAFORMAT과 CHARFORMAT 구조를
준비한다.
2. 이 구조들을 사용하는 CRichEditCtrl 메소드를 호출하여 원하는 작업을 수행한다.
? CRichEditCtrl 사용하기
void CMainWnd::SetStyleHeading1(CHARFORMAT& cf)
{
cf.cbsize

= sizeof(CHARFORMAT);

cf.dwMask

= CFM_COLOR | CFM_FACE | CFM_SIZE |

cf.dwEffects

= CFE_BOLD | CFE_ITALIC;

cf.yHeight

= 500;

cf.crTextColor

= crRed;

cf.bCharSet

= ANSI_CHARSET;

(C) 1998 Sang Il Kim

CFM_ITALIC | CFM_BOLD;

cf.bPitchAndFamily = FF_ROMAN;
}
Visual C++ Programming

4
6

CHAPTER 12
? 문자 형식 구조(CHARFORMAT)
? GetDefaultCharFormat(), GetSelectionCharFormat(),
SetDefaultCharFormat(), SetSelectionCharFormat(),
SetWordCharFormat() 모두 CHARFORMAT 유형의 매개 변수를 가진다.
? 이것은 서식 있는 편집 컨트롤에서 문자 형식에 대한 정보를 담고 있는

(C) 1998 Sang Il Kim

Win32 데이터 유형이다.

Visual C++ Programming

4
6

CHAPTER 12
? CHARFORMAT 구조
typedef struct _charformat
{
cbSize;

// 이 구조의 바이트 단위 크기

_WPAD

_wPad1;

DWORD

dwMask;

// 설정될 유효한 정보나 속성을 가지는 멤버

DWORD

dwEffects;

// 문자 효과

LONG

yHeight;

// 문자 높이

LONG

yOffset;

// 기준선으로부터의 문자 옵셋. +:위첨자, -:아래첨자

COLORREF

crTextColor;

// 텍스트 색

BYTE

bCharSet;

// 문자 집합 값

BYTE

bPitchAndFamily; // 글꼴 집합과 크기

TCHAR

szFaceName[LF_FACESIZE]; // 글꼴 이름을 가리키는 널로 끝나는 문자

_WPAD

_wPad2;

} CHARFORMAT;
Visual C++ Programming

(C) 1998 Sang Il Kim

UINT

4
6

CHAPTER 12
? CHARFORMAT dwMask 값

설명

CFM_BOLD

dwEffects 멤버의 CFE_BOLD 값이 유효하다.

CFM_COLOR

dwEffects 멤버의 crTextColor 멤버와 CFE_AUTOCOLOR 값이 유효하다.

CFM_FACE

szFaceName 멤버가 유효하다.

CFM_ITALIC

dwEffects 멤버의 CFE_ITALIC 값이 유효하다.

CFM_OFFSET

yOffset 멤버가 유효하다.

CFM_SIZE

yHeight 멤버가 유효하다.

CFM_STRIKEOUT dwEffects 멤버의 CFE_STRIKEOUT 값이 유효하다.
CFM_UNDERLINE dwEffects 멤버의 CFE_UNDERLINE 값이 유효하다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CFM_PROTECTED dwEffects 멤버의 CFE_PROTECTED 값이 유효하다.

4
6

CHAPTER 12
? 서식 있는 편집 컨트롤의 가능한 문자/효과 값

설명

CFE_BOLD

문자는 굵은 글씨체

CFE_ITALIC

문자는 이탤릭체

CFE_STRIKEOUT

문자는 취소선

CFE_UNDERLINE

문자는 밑줄체

CFE_PROTECTED

문자는 보호된다. 문자를 수정하려고 시도하면, EN_PROTECTED
통보 메시지를 발생시킨다.

Visual C++ Programming

(C) 1998 Sang Il Kim

CFE_AUTOCOLOR 텍스트 색은 GetSysColor(COLOR_WINDOWTEXT)의 반환 값

4
6

CHAPTER 12
? 속성 시트(Property Sheet)
? 많은 종류의 정보를 조그만 다이얼로그에 집약할 수 있도록 해준다.
? 윈도우95는 다이얼로그 내에 삽입할 수 있는 탭 컨트롤을 제공해 준다.
? MFC 라이브러리는 속성 시트라고 하는 결과물과 속성 페이지라고 하는 개개의
다이얼로그를 지원한다.
? 속성 시트 만들기
1. 리소스 에디터를 이용하여 동일한 크기의 다이얼로그 템플릿들을 만든다.
2. ClassWizard를 이용하여 각 템플릿을 위한 클래스를 만든다.
기초 클래스로서 CPropertyPage를 선택한다. 컨트롤을 위한 데이터 멤버들을 추가한다.
3. ClassWizard를 이용하여 CPropertySheet에서 파생된 클래스를 하나 생성한다.
4. 페이지 클래스 각각에 대해 데이터 멤버를 파생된 속성 시트 클래스에 추가한다.
각 페이지에 대해 AddPage() 멤버 함수를 호출한다.
6. 어플리케이션에서는 CPropertySheet에서 파생된 클래스의 객체를 생성한 다음,
DoModal()을 호출한다. 생성자 호출시에 캡션을 지정해도 되지만,
나중에 CPropertySheet::SetTitle()를 호출하여 캡션을 변경할 수도 있다.
7. Apply 버튼의 코드를 작성한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

5. 파생된 속성 시트 클래스의 생성자에서 포함된 페이지 객체의 주소를 지정하여

4
6

CHAPTER 12
? 속성 시트 데이터 교환
? 프레임워크는 사용자가 속성 페이지를 전환할 때마다 해당 속성 페이지의 DDX
코드를 호출한다.
? 프레임워크는 모든 버튼 클릭에 대해 WM_NOTIFY 메시지를 얻는다.
? 프레임워크는 OK, Cancel, Apply 버튼이 클릭되면 페이지의 DDX 코드를 호출하고나서
모든 페이지들에 대해 가상 함수 OnApply()를 호출하며, 변경된 플래그를 재설정하여
Apply 버튼을 불가능 상태로 만든다.
? 사용자가 한 페이지의 내용 변경 후, 다른 페이지로 이동한 다음에 Cancel 버튼을
클릭하면 변경된 내용이 적용되어 데이터 멤버가 갱신된다.
? Apply(적용) 버튼

?직접 코드를 작성하지 않으면 아무 일도 하지 않고 버튼도 불가능 상태로 나타난다.
Override해서 페이지 클래스에서 Apply 버튼에 대한 핸들러 함수를 작성해야 한다.

?버튼이 사용 가능해졌다면 사용자가 페이지 내용을 변경할 때 SetModified(TRUE)를
호출하여 페이지의 변경 플래그를 설정해야 한다.

?하나의 페이지 클래스에서만 Override하면 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?버튼을 가능한 상태로 만들려면 가상 함수 CPropertyPage::OnApply()를

4
6

CHAPTER 12
? CMenu 클래스
? CMenu 객체는 탑-레벨 항목과 그와 연결된 팝업 메뉴를 포함해서 모든 윈도우 메뉴를
나타낼 수 있다.
? CWnd::GetMenu()는 임시적인 CMenu 포인터를 리턴한다.
? 포인터를 얻은 다음에는 메뉴 객체를 마음대로 액세스하고 갱신할 수 있다.
? GetSubMenu() 멤버 함수를 사용하면 메인 CMenu 객체에 포함된 팝업 메뉴의 포인터
(CMenu 포인터)를 얻을 수 있다.
? 플로팅 팝업(Pop-up)메뉴 만들기
? CMenu::TrackPopupMenu() 함수를 이용하면 쉽게 팝업 메뉴를 만들 수 있다.
1. 메뉴 에디터를 이용하여 프로젝트의 리소스 파일에 새로운 메뉴를 삽입한다.
3. ClassWizard를 이용하여 뷰 클래스 또는 마우스 클릭 메시지를 접수할 윈도우
클래스에 WM_CONTEXTMENU 메시지 핸들러를 추가한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

2. 왼쪽의 탑-레벨 항목에 문자들을 입력한 후, 팝업 메뉴에 메뉴 아이템들을 추가한다.

4
6

CHAPTER 12
? CPage1 클래스에 팝업(Pop-up)메뉴 만들기
void CPage1::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
menu.GetSubMenu(1) -> TrackPopupMenu(
TPM_LEFTALIGN | TPM_RIGHTBUTTON, // 플래그
point.x, point.y,

// 위치

this);

// 소유자

(C) 1998 Sang Il Kim

}

Visual C++ Programming

4
7

CHAPTER 12
? 플로팅 팝업(Pop-up)메뉴 만들기
void CMyView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu menu;
menu.LoadMenu(IDR_MYFLOATMENU);
menu.GetSubMenu(0) -> TrackPopupMenu(
TPM_LEFTALIGN | TPM_RIGHTBUTTON, // 플래그
point.x, point.y,

// 위치

this);

// 소유자

(C) 1998 Sang Il Kim

}

Visual C++ Programming

4
7

CHAPTER 12
? 네 개의 Win32 API 메뉴 메시지를 두 개의 MFC 메뉴 메시지와 맵핑하기
Win32 API 메시지

대응되는 MFC 메시지

WM_COMMAND

WM_COMMAND 메시지에 맵핑된다.

WM_INITMENU

없음; MFC는 이 메시지를 무시한다.

WM_INITPOPUPMENU

UPDATE_COMMAND_UI 메시지에 맵핑된다. MFC는 어떤
메뉴 핸들러가 메시지를 전달할 것인지를 결정하고,
WM_COMMAND 메시지를 받을 수 없는 메뉴 항목은 자동으로
회색으로 만든다.

WM_MENUSELECT 없음; CFrameWnd에 의해 자동으로 설정된다.
? CMenu 클래스 메소드
(C) 1998 Sang Il Kim

? 생성 메소드
? 메뉴 연산 메소드
? 메뉴 항목 연산 메소드
? 가상 메소드
Visual C++ Programming

4
7

CHAPTER 12
? CMenu 생성 메소드
메소드

목적

Attach()

CMenu 객체에 표준 윈도우 메뉴 핸들을 붙인다.

CreateMenu()

빈 메뉴를 생성하고, 그것을 CMenu 객체에 붙인다.

CreatePopupMenu()

빈 팝업 메뉴를 생성하고, 그것을 CMenu 객체에 붙인다.

DestroyMenu()

CMenu 객체에 결합된 메뉴를 없애고, 메뉴가 차지한 메모리를 비운다.

Detach()

CMenu 객체로부터 창의 메뉴 핸들을 제거하고, 핸들을 반환한다.

FromHandle()

창의 메뉴 핸들을 받으면, CMenu 객체의 포인터를 반환한다.

GetSafeMenu()

CMenu 객체에 의해 보호되는 메뉴 핸들 멤버(m_hMenu)를 반환한다.

LoadMenu()

실행 파일로부터 메뉴 자원을 적재하고, 그것을 CMenu 객체에 결합한다.

LoadMenuIndirect() 메모리의 메뉴 템플릿에서 메뉴를 적재하고, 그것을 CMenu 객체에 결합한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

DeleteTempMap() FromHandle() 멤버함수에 의해 생성된 임시 CMenu 객체를 삭제한다.

4
7

CHAPTER 12
? 메뉴 연산 메소드
? DeleteMenu()
?메뉴에서 지정된 항목을 삭제한다.
?삭제된 메뉴 항목에 관련된 팝업 메뉴가 있다면, 팝업 메뉴의 핸들 역시 삭제되고
메모리는 해제된다.
? TrackPopupMenu()
?POINT 구조체에서 지정된 장소에 팝업 메뉴를 나타낸다.
? 가상 메소드
? DrawItem()
? MeasureItem()
?소유자가 그리는 메뉴가 생성될 때 메뉴의 크기를 얻기 위해서 MFC가 호출한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?소유자가 그리는 메뉴의 시각적인 면이 변경되었을 때 MFC가 호출한다.

4
7

CHAPTER 12
? 메뉴 항목 연산에 이용하는 CMenu 클래스 메소드
메소드

목적

AppendMenu()

특정 메뉴의 끝에 새로운 항목을 추가한다.

CheckMenuItem() 팝업 메뉴의 메뉴 항목에 체크 표시를 하거나 삭제한다.
CheckMenuRadioItem()

메뉴 항목에 라디오 단추를 넣거나 그룹의 다른 모든 메뉴에서
존재하는 라디오 단추를 삭제한다.

EnableMenuItem() 메뉴 항목을 실행 가능하게, 실행 불가능하게, 또는 흐릿하게 만든다.
GetMenuContextHelpId()

메뉴와 관련된 도움말 컨텍스트 ID를 가져온다.

GetMenuItemID() 특정 위치에 존재하는 메뉴 항목을 위한 메뉴 항목 ID를 가져온다.
GetMenuState()

특정 메뉴 항목의 상태를 가져오거나 팝업 메뉴의 항목 수를 가져온다.

Visual C++ Programming

(C) 1998 Sang Il Kim

GetMenuItemCount() 팝업 메뉴나 최상위 메뉴의 항목 개수를 가져온다.

4
7

CHAPTER 12
? 메뉴 항목 연산에 이용하는 CMenu 클래스 메소드
목적

GetMenuString()

지정한 메뉴 항목의 이름표를 가져온다.

GetSubMenu()

팝업 메뉴의 포인터를 가져온다.

InsertMenu()

메뉴의 다른 항목을 아래로 옮기고 지정된 위치에 새로운 메뉴
항목을 삽입한다.

ModifyMenu()

지정한 위치에 존재하는 메뉴 항목을 변경한다.

RemoveMenu()

연관된 팝업 메뉴와 함께 지정된 메뉴의 메뉴 항목을 삭제한다.

SetMenuContextHelpId()

메뉴에 연관된 도움말 컨텍스트 ID를 설정한다.

SetMenuItemBitmaps()

메뉴 항목에 지정된 체크 표시 비트맵을 적용한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

4
7

CHAPTER 12
? CPropertyPage
? CPropertyPage();
? CPropertyPage( UINT nIDTemplate, UINT nIDCaption = 0);
? CPropertyPage(LPCTSTR lpszTemplateName, UINT nIDCaption = 0);
? Parameters
?nIDTemplate
페이지에 관련되는 다이얼로그 템플릿의 정수 리소스 ID
?lpszTemplateName 페이지에 관련되는 다이얼로그 템플릿의 이름을 포함하는
?nIDCaption

널로 끝나는 문자열 버퍼에 대한 포인터
페이지에 대한 캡션으로 사용되는 문자열의 문자열 리소스 ID.
0이거나 생략되면, 캡션은 다이얼로그 템플릿 자체에서 얻어진다.

?pWnd

?pos

Handle to the window in which the user right clicked themouse.
This can be a child window of the window receiving the message.
For more information about processing this message, see the
Remarks section.
Position of the cursor, in screen coordinates, at the time of the
mouse click.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::OnContextMenu
? afx_msg void OnContextMenu( CWnd* pWnd, CPoint pos );
? Parameters

4
7

CHAPTER 12
? CWnd::SetMenu
?
?
?
?

윈도우에 대한 메뉴를 특정 메뉴로 변경한다.
SetMenu는 새로운 메뉴를 반영하기 위하여 윈도우를 자동적으로 다시 그린다.
SetMenu는 윈도우와 관련 있는 이전의 메뉴를 파괴하지 않는다.
CWnd::GetMenu 함수로 이전의 메뉴를 얻고, CMenu::DestroyMenu 함수로 이전의
메뉴를 파괴하여야 한다.
? BOOL SetMenu( CMenu* pMenu );
? Parameters
?pMenu
새로운 메뉴에 대한 포인터.
파라미터가 NULL이면, 현재 메뉴가 윈도우로 부터 제거된다.
? CMenu::GetSubMenu
메뉴의 팝업 메뉴에 관련되는 CMenu 객체를 얻는다.
팝업메뉴의 식별자는 이 함수를 사용할 수 없다.
CMenu* GetSubMenu( int nPos ) const;
Return Value
팝업메뉴에 관련되는 CMenu 객체에 대한 포인터
? Parameters
?nPos 메뉴에 포함되어 있는 팝업 메뉴의 위치.
Position values start at 0 for the first menu item.

(C) 1998 Sang Il Kim

?
?
?
?

Visual C++ Programming

4
7

CHAPTER 12
? CMenu::TrackPopupMenu
? BOOL TrackPopupMenu( UINT nFlags,

// 플래그

int x, int y,

// 위치

CWnd* pWnd,

// 소유자

LPCRECT lpRect = NULL );

// 범위

? Screen-position flag
?TPM_CENTERALIGN
?TPM_LEFTALIGN
?TPM_RIGHTALIGN
? Mouse-button flag

(C) 1998 Sang Il Kim

?TPM_LEFTBUTTON
?TPM_RIGHTBUTTON
? x 팝업메뉴의 스크린 좌표상의 수평 위치
? y 팝업메뉴의 스크린 좌표상의 수직 위치
? pWnd

팝업메뉴 자신의 윈도우를 기술한다.
Visual C++ Programming

4
7

우리에게 필요되는 것은 무엇이든 해낼 수 있다는 “Can do” 정신이다.
샘물처럼 마르지 않는 왕성한 학습 의욕이 그 생명이며 부정적인
현재보다 긍정적인 미래가 그 지향 목표이다.
“컵에 물이 반밖에 차지 않았다.”는 소극적인 자세보다
“컵에 물이 반이나 찼다.”는 적극적인 자세가 매사를 혁신으로 이끈다.

(C) 1998 Sang Il Kim

( 실리콘 밸리의 정신 )

Visual C++ Programming

4
8

CHAPTER 13

(C) 1998 Sang Il Kim

툴바와 상태바

Visual C++ Programming

4
8

CHAPTER 13
? 툴바와 상태바
? AppWizard Step4에서 Docking toolbar와 Initial status bar 옵션을 디폴트로
설정하면 AppWizard는 선택된 요소들에 대해 초기화 기본 코드를 만든다.
? 컨트롤바와 어플리케이션 프레임워크
? 툴바 - CToolBar 클래스의 객체
? 상태바 - CStatusBar 클래스의 객체
? CControlBar 클래스 - 메인 프레임 윈도우 내에 위치한 컨트롤바 윈도우들이
부모 프레임 윈도우가 이동하거나 크기 조정에 따라 스스로 그 위치와 크기를
변경시킨다.
? 어플리케이션 프레임워크 - 컨트롤바 객체의 생성, 소멸 그리고 해당 객체의 윈도우를
? AppWizard - 메인 프레임 윈도우 내에 위치한 컨트롤바 코드를 MainFrm.cpp,
MainFrm.h 파일에 생성한다.
? SDI 어플리케이션
?CToolBar 객체 - CMainFrame 클라이언트 영역의 상단에 위치
?CStatusBar 객체 - CMainFrame 클라이언트 영역의 하단에 위치
?뷰 - 프레임의 나머지 공간(툴바와 상태바 중간)을 차지한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

만드는 일을 담당

4
8

CHAPTER 13
? 툴바
? 버튼의 그래픽 이미지들은 어플리케이션의 리소스 파일에 연결된
단일 비트맵으로 저장된다.
? 메뉴와 가속키처럼 툴바 버튼도 클릭될 때 명령 메시지를 보낸다.
? 갱신 명령 UI 메시지 핸들러에 의해 버튼의 상태가 갱신되면 어플리케이션
프레임워크는 버튼의 그래픽 이미지를 변경시킨다.
? 툴바 비트맵
? 툴바 비트맵은 각 버튼에 대해서 16(폭)x15(높이) 픽셀의 타일(tile)을 가지고 있다.
? 어플리케이션 프레임워크는 각 버튼의 경계선을 제공하여 현재의 버튼 상태
변경한다.
? 툴바 비트맵은 어플리케이션의 \res 서브 디렉토리의 Toolbar.bmp 파일에 저장된다.
? 비트맵은 리소스 스크립트 파일( .rc)에서 IDC_MAINFRAME으로 식별된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

(눌려진 상태와 눌려지지 않은 상태)에 따라 버튼의 비트맵 색상과 경계선을

4
8

CHAPTER 13
? 버튼의 상태
버튼의 상태

설 명

0
TBBS_PRESSED
TBBS_CHECKED
TBBS_DISABLED
TBBS_INDETERMINATE

눌려져 있지 않은 정상 상태(up)
마우스를 이용해서 현재 선택된(눌려진) 상태
체크된(down) 상태
사용이 불가능한 상태
사용이 가능하지만, up도 down도 아닌 상태

TBBS_CHECKED | TBBS_DISABLED 체크된(down) 상태이지만, 사용이 불가능한 상태

? 표준 어플리케이션의 툴바에서 사용되는 버튼들은 모두 푸시 버튼 형태로 작동된다.

? 툴바와 명령 메시지
? 어플리케이션의 메뉴 아이템과 대응하는 툴바 버튼의 유무와 상관없이
ClassWizard를 사용하여 명령과 갱신명령 UI 메시지 핸들러를 정의할 수 있다.
? 툴바는 비트맵 리소스, 버튼과 조합된 메뉴 명령을 정의하는 TOOLBAR 리소스를 갖는다.
? 비트맵 리소스와 TOOLBAR 리소스는 동일한 ID(ID_MAINFRAME)를 갖는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 대부분의 경우 툴바 버튼은 메뉴 명령과 일치된다.

4
8

CHAPTER 13
IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15
BEGIN
BUTTON ID_FILE_NEW
BUTTON ID_FILE_OPEN
BUTTON ID_FILE_SAVE
SEPARATOR
BUTTON ID_EDIT_CUT
BUTTON ID_EDIT_COPY
BUTTON ID_EDIT_PASTE
SEPARATOR
BUTTON ID_FILE_PRINT
BUTTON ID_APP_ABOUT
END
? 툴바 비트맵 패인(pane)의 수가 리소스 요소의 수보다 더 많을경우 초과된 버튼들은
출력되지 않는다.
? 버튼 이미지를 선택한 다음, 왼쪽 패널을 double click하면 버튼의 ID등의 속성을
편집할 수 있는 상태가 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? AppWizard가 생성한 툴바 리소스의 텍스트

4
8

CHAPTER 13
? 툴바 갱신 명령 UI 메시지 핸들러
? 갱신 명령 UI 메시지 핸들러가 False 파라미터를 이용하여 CCmdUI::Enable() 멤버함
수를 호출하게 되면 이와 대응하는 버튼이 불가능 상태(회색)로 설정되어 마우스 클릭
에 대해서 반응하지 않게 된다.
갱신 명령 UI 메시지 핸들러는
? CCmdUI::SetCheck()
어플리케이션의 idle처리중에
?메뉴 아이템의 경우 - 메뉴 아이템에 체크 표시를 한다. 호출된다.
?툴바의 경우 - 체크 박스 버튼을 구현한다.

? CButton::SetCheck - 버튼의 체크 상태를 설정한다.
(라디오 버튼, 체크 박스에서만 유효)
? void SetCheck( int nCheck );
? Parameters
?nCheck
버튼의 체크 상태
Value
Meaning
0
버튼이 체크되지 않게 한다. (라디오 버튼은 선택되지 않는다.)
1
버튼이 체크된다. (라디오 버튼은 선택된다.)
2
버튼이 중간 상태가 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CCmdUI::SetCheck - 사용자 인터페이스 객체에 체크 표시를 하거나 해제한다.
? virtual void SetCheck( int nCheck = 1 );
? Parameters
?nCheck
체크되지 않은 상태 : 0, 체크 상태 : 1, 중간 상태 : 2

4
8

CHAPTER 13
? 툴팁 ( 풍선 도움말 )
? 툴팁을 만들려면 (p439)
?메뉴 프롬프트의 끝 부분에 (\n)문자와 함께 팁 텍스트를 추가하면 된다.
? 메인 프레임 윈도우 찾기
? 툴바 객체와 상태바 객체는 어플리케이션의 메인 프레임 윈도우에 부착된다.
? SDI와 MDI어플리케이션 모두에 적용되게 하려면 어플리케이션 객체를 통해서
메인 프레임 윈도우를 찾아야 한다.
?AfxGetApp()를 이용 - 어플리케이션 객체 포인터를 리턴
?CWinApp 클래스의 데이터 멤버인 m_pMainWnd를 이용 - 어플리케이션 객체 포인터
?CMainFrame* pFrame = ( CMainFrame*)AfxGetApp()->m_pMainWnd;
? m_wndToolBar는 유도 클래스의 멤버이므로 CFrameWnd * 에서 CMainFrame*로
m_pMainWnd를 형변환시켜야 한다.
? SDI 어플리케이션의 경우 - m_pMainWnd의 값은 뷰의 OnCreate() 함수에서
메인 프레임 윈도우를 액세스 해야 할 경우 GetParentFrame() 함수를 이용해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CToolBar* pToolBar = &pFrame->m_wndToolBar;

4
8

CHAPTER 13

메소드

설명

CommandToIndex()
Create()
GetItemID()
GetItemRect()
GetPaneInfo()
GetPaneStyle()
GetPaneText()
GetStatusBarCtrl()

특정 지시자 ID의 인덱스를 얻는다.
상태 표시줄을 생성하고, 그것을 CStatusBar 객체에 붙인다.
특정 인덱스에 대한 지시자 ID를 얻는다.
특정 인덱스에 대한 출력 직사각형을 얻는다.
특정 인덱스에 대한 지시자 ID, 스타일, 너비를 얻는다.
특정 인덱스에 대한 지시자 스타일을 얻는다.
특정 인덱스에 대한 지시자 문자를 얻는다.
CStatusBarCtrl 객체 참조로 상태 표시줄 공용 컨트롤에 대한
직접적인 액세스를 허락한다.
지시자 ID를 설정한다.
특정 인덱스에 대한 지시자 ID, 스타일, 너비를 설정한다.
특정 인덱스에 대한 지시자 스타일을 설정한다.
특정 인덱스에 대한 지시자 텍스트를 설정한다.

SetIndicators()
SetPaneInfo()
SetPaneStyle()
SetPaneText()

Visual C++ Programming

(C) 1998 Sang Il Kim

? CToolBar 클래스 메소드

4
8

CHAPTER 13
? 예제 EX13A - 툴바
메뉴 아이템

기능

Circle
Square
Pattern

뷰 윈도우에 원을 그린다.
뷰 윈도우에 사각형을 그린다.
새로운 사각형과 원 내부를 대각선 패턴으로 채운다.

? 사용자가 원을 그린 경우 Circle 메뉴 아이템과 툴바 버튼이 불가능하게
되고, 사각형을 그린 경우 Square 메뉴 아이템과 툴바 버튼이 불가능하게
된다.

아이템은 체크 표시가 되며, 이에 대응하는 툴바 버튼은 대각선 패턴이
활성화 되면 다운(down)으로 표시되고 활성화되지 않았을 경우 업(up)으로
표시된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 어플리케이션의 Draw 메뉴에서 대각선 패턴이 활성화될 때 Pattern 메뉴

4
8

CHAPTER 13
? 상태바
? 프로그램의 제어로 패인(pane)에 텍스트를 출력하는 역할만 한다.
? 상태바는 메시지 라인 패인과 상태 표시자 패인 두 가지 형태의 텍스트 패인을 지원한다.
? 상태바 정의

정적 배열 indicators[]은
어플리케이션의
상태바 패인(pane)을 정의

? CStatusBar::SetIndicators - 상태바에 대한 창 지시자를 설정한다.
? BOOL SetIndicators( const UINT* lpIDArray, int nIDCount );
? Return Value
?성공하면 TRUE, 실패하면 FALSE
? Parameters
?lpIDArray 상태바 창에 대한 커맨드 ID를 나타내는 UINT 배열에 대한 포인터
?nIDCount
창의 수. lpIDArray 배열에 있는 요소의 수와 동일하다.
Visual C++ Programming

(C) 1998 Sang Il Kim

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

4
9

CHAPTER 13
? 메시지 라인 패인 (pane)
? 프로그램이 동적으로 제공하는 문자열을 출력한다.
? 인덱스 파라미터를 사용 - 0번 패인 : 맨 왼쪽 패인, 1번 패인 : 다음 패인(CAP)
? CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CStatusBar* pStatus = &pFrame->m_wndStatusBar;
pStatus->SetPaneText( 0, “message line for first pane” );
? 일반적으로 메시지 라인 패인의 길이는 전체 상태바 폭의 1/4이다.
? 메시지 라인이 첫번째 패인(인덱스 0)인 경우 경계선이 없는 확장된 패인이 되어
최소 길이는 전체 표시 폭의 1/4이 된다.

? Return Value
?성공하면 TRUE, 실패하면 FALSE
? Parameters
?nIndex

특정 상태바 창을 나타내는 0에서 시작하는 인덱스

?lpszNewText 새로운 창 텍스트에 대한 포인터
?bUpdate

상태바가 갱신되어야 하면 TRUE, 그렇지 않으면 FALSE

Visual C++ Programming

(C) 1998 Sang Il Kim

? CStatusBar::SetPaneText - 특정 상태바 창에 대해 텍스트를 설정한다.
? BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE );

4
9

CHAPTER 13
? 상태 표시자(Status Indicator) 패인
? 단일 리소스에 의해 제공되는 문자열과 연결된다.
? 문자열은 갱신 명령 UI 메시지 핸들러 함수에 의해 표시되거나 사라진다.
? 각 표시자는 문자열 리소스 ID에 의해서 식별된다.
? CapsLock 표시자는 프레임 클래스의 메시지 맵 엔트리와 핸들러 함수에서 처리된다.
? ON_UPDATE_COMMAND_UI ( ID_INDICATOR_CAPS, OnUpdateKeyCapsLock )
void CMainFrame::OnUpdateKeyCapsLock ( CCmdUI* pCmdUI )
{

인덱스 파라미터
pCmdUI->Enable(::GetKeyState(VK_CAPITAL) & 1));

}
(C) 1998 Sang Il Kim

? 상태바의 갱신 명령 UI 메시지 함수는 idle 처리중에 호출되므로 어플리케이션이
메시지를 접수할 때마다 상태바가 갱신된다.

Visual C++ Programming

4
9

CHAPTER 13
? 상태바의 제어 얻기
? 상태바를 제어하기 위해서는 디폴트 ID(AFX_IDW_STATUS_BAR)대신
다른 차일드 윈도우 ID를 사용해야 하고 다른 표시자 ID 상수를 사용해야 한다.
? CFrameWnd::OnUpdateKeyIndicator(CCmdUI* pCmdUI) 에서 상태바의
상태 표시자가 갱신된다.(..\vc\mfc\src\Winfrm.cpp - 1733라인)
? 상태바의 차일드 윈도우 ID를 변경하는 이유는 프레임워크가 0번 패인에
메뉴 프롬프트를 표시하지 못하도록 하기 위함이다.
? 고유한 윈도우 ID를 부여하려면
m_wndStatusBar.Create(this); 를 다음과 같이 변경한다.
m_wndStatusBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,
? 표준 어플리케이션의 View 메뉴에는 사용자가 상태바를 show/hide 할 수 있도록
해준다.

Visual C++ Programming

(C) 1998 Sang Il Kim

ID_MY_STATUS_BAR);

4
9

CHAPTER 13
? CStatusBar::Create - 상태바를 생성한다.
? 상태바는 AFX_IDW_STATUS_BAR 자식 윈도우 ID로 주어진다.
이것은 MFC 프레임워크가 프레임 윈도우의 어느 자식 윈도우가 상태바인가를
알 수 있는 방법
? BOOL Create( CWnd* pParentWnd, DWORD dwStyle =
WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,
UINT nID = AFX_IDW_STATUS_BAR );
? Return Value
?성공 : TRUE, 실패 : FALSE
?pParentWnd 부모 윈도우에 대한 포인터
?dwStyle
상태바와 표준 윈도우 스타일
CBRS_TOP
Control bar is at top of frame window.
CBRS_BOTTOM
Control bar is at bottom of frame window.
CBRS_NOALIGN Control bar is not repositioned when the parent is resized.
?nID
툴바의 자식 윈도우 ID.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters

4
9

CHAPTER 13
? RecalcLayout
? 이 멤버는 프레임 윈도우의 크기가 변경되거나 컨트롤바가 표시되거나
숨겨질 때 호출된다. 프레임 윈도우의 레이아웃 행위를 Customize하기
위하여 중복될 수 있다.
? virtual void RecalcLayout( BOOL bNotify = TRUE );
? Parameters
?bNotify TRUE이면, 프레임에 대한 활성화 인플레이스 항목이

(C) 1998 Sang Il Kim

레이아웃 변경에 대해 통보 받는다.

Visual C++ Programming

4
9

CHAPTER 13
? 예제 EX13B - 상태바
패인 인덱스 문자열 ID
0
1
2
3

ID_SEPARATOR(0)
ID_SEPARATOR(0)
ID_INDICATOR_LEFT
ID_INDICATOR_RIGHT

Type

설명

메시지 라인
메시지 라인
상태 표시자
상태 표시자

x 커서 좌표
y 커서 좌표
왼쪽 마우스 버튼 상태
오른쪽 마우스 버튼 상태

? CStatusBar::SetPaneInfo - 특정 상태바 창에 대한 창 정보를 설정한다.
? void SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxWidth );
? Parameters
?nIndex
특정 상태바 창을 나타내는 0에서 시작하는 인덱스
?nID
창에 대한 커맨드 ID
?nStyle
창의 스타일

?cxWidth

경계가 없다.
Popout 경계
텍스트를 그리지 않는다.
창을 남아 있는 영역까지 확장한다.
기본 창.

(C) 1998 Sang Il Kim

SBPS_NOBORDERS
SBPS_POPOUT
SBPS_DISABLED
SBPS_STRETCH
SBPS_NORMAL
창의 폭

Visual C++ Programming

4
9

CHAPTER 14

(C) 1998 Sang Il Kim

재사용 가능한 프레임
윈도우 기초 클래스

Visual C++ Programming

4
9

CHAPTER 14
? 프레임 윈도우
? 프레임 윈도우는 MFC가 제공하는 가장 편리한 클래스 중의 하나이다.
? 관련 윈도우 API 함수에 대한 단순한 캡슐화를 제공하는 것뿐만 아니라,
윈도우 어플리케이션에 표준화된 확장 기능을 지원한다.
? 클래스 요약
설명

CFrameWnd
CMDIFrameWnd
CMDIChildWnd
CMiniFrameWnd

모든 프레임 윈도우에 대한 기초 클래스
다중 도큐먼트 어플리케이션에 사용되는 프레임 클래스
다중 도큐먼트 자식 윈도우
보통 툴바에 사용되는 프레임 윈도우
(C) 1998 Sang Il Kim

클래스 이름

Visual C++ Programming

4
9

CHAPTER 14
? CPersistentFrame 클래스
? CPersistentFrame 클래스는 영구적인 SDI프레임 윈도우를 지원한다.
?윈도우 크기
?윈도우 위치
?최대화된 상태
?최소화된 상태 ( Iconized status )
?툴바와 상태바의 가능화와 위치
? CFrameWnd 클래스와 ActivateFrame() 멤버 함수
? MFC SDI 어플리케이션에서 메인 프레임 윈도우는 항상 뷰 윈도우의
부모 윈도우가 된다.
? 어플리케이션 프레임워크는 사용자가 메인 프레임 윈도우의 크기를
변경함에 따라 차일드 윈도우들도 적절하게 축소, 확대시킨다.
(C) 1998 Sang Il Kim

? 메인 프레임 윈도우의 크기를 제어하는 함수
?CFrameWnd::ActivateFrame()

Visual C++ Programming

4
9

CHAPTER 14
? CFrameWnd::ActivateFrame
? 이 함수는 프레임 윈도우를 보이게(현재 아이콘화되었으면 복원)하고
최상위 Z순위 윈도우 위치에 오게 한다.
? 또한 사용자 상호작용의 결과로 윈도우를 표시하는 데 사용되거나
? virtual void ActivateFrame( int nCmdShow = -1 );
? Parameters
?nCmdShow 프레임 윈도우의 결과 보기 상태.
이 값이 -1이면, 윈도우는 아이콘화가 되어 있는 경우
복원되고(SW_RESTORE), 그렇지 않으면
SW_SHOWNORMAL이 사용된다.
값이 -1이 아니면, nCmdShow의 명시적인 값이 사용된다.
CWnd::ShowWindow를 참조

Visual C++ Programming

(C) 1998 Sang Il Kim

기본 윈도우 활성화 행위를 Customize하기 위하여 중복시킬 수 있다.

5
0

CHAPTER 14
? CFrameWnd 클래스와 ActivateFrame() 멤버 함수
? 어플리케이션 프레임워크는 SDI 메인 프레임 윈도우 생성 과정에서
가상함수 ActivateFrame()을 호출한다.
? 프레임워크
?nCmdShow 파라미터를 사용하여 CWnd::ShowWindow() 함수를 호출
? ShowWindow()
?프레임 윈도우를 화면에 보이도록 한다.
? nCmdShow 파라미터

? 파생클래스에서 ActivateFrame() 을 Override하면 nCmdShow 파라미터가
CFrameWnd::ActivateFrame() 함수에 전달되기 전에 파라미터 값을 변경
할 수 있다.
? CWnd::SetWindowPlacement()
?메인 프레임 윈도우의 크기와 위치, 컨트롤 바의 표시상태 설정
Visual C++ Programming

(C) 1998 Sang Il Kim

?윈도우를 최대화할 것인지 최소화할 것인지, 아니면 두 경우 모두에 대응할
것인지의 여부를 결정한다.

5
0

CHAPTER 14

Nonzero if the window was previously visible; 0 if the CWnd was previously hidden.
? Parameters
?nCmdShow
SW_HIDE
이 윈도우를 숨기고 다른 윈도우로 활성화를 전달한다.
SW_MINIMIZE
윈도우를 아이콘화하고 윈도우 시스템의 리스트에 최상위 윈도우를
활성화한다.
SW_RESTORE
윈도우를 활성화하고 표시한다. 윈도우가 아이콘화나
최대화면이면, 윈도우는 원래 크기와 위치로 복원된다.
SW_SHOW
윈도우를 활성화하고 현재 크기와 위치에 표시한다.
SW_SHOWMAXIMIZED
윈도우를 활성화하고 최대 화면으로 표시한다.
SW_SHOWMINIMIZED
윈도우를 활성화하고 아이콘으로 표시한다.
SW_SHOWMINNOACTIVE 윈도우를 아이콘으로 표시한다.
현재 활성화된 윈도우가 활성화된다.
SW_SHOWNA
윈도우를 현재 상태로 표시한다.
현재 활성화된 윈도우가 활성화된다.
SW_SHOWNOACTIVATE 윈도우를 가장 최근의 크기와 위치로 표시한다.
현재 활성화된 윈도우가 활성화된다.
SW_SHOWNORMAL
윈도우를 활성화하고 표시한다. 윈도우가 아이콘화나
최대화면이면, 윈도우는 원래 크기와 위치로 복원된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::ShowWindow - 윈도우의 보이기와 상태를 제어한다.
? BOOL ShowWindow( int nCmdShow );
? Return Value

5
0

CHAPTER 14
? CWnd::SetWindowPlacement
? 윈도우의 표시 상태와 위치를 설정한다.
? 이 함수는 보통과 아이콘화된 상태의 위치를 설정하는 데 사용된다.
? BOOL SetWindowPlacement( const WINDOWPLACEMENT*lpwndpl );
? Parameters
?lpwndpl 윈도우의 표시 상태와 위치를 기술하는 WINDOWPLACEMENT
구조체에 대한 포인터
? CWnd::GetWindowPlacement
? 윈도우의 표시 상태와 위치 정보로 WINDOWPLACEMENT 구조체를 채운다.
? BOOL GetWindowPlacement( WINDOWPLACEMENT* lpwndpl ) const;
?lpwndpl

윈도우의 표시 상태(보이기, 숨기기, 최대 화면, 아이콘 화면)와
위치 정보로 채워지는 WINDOWPLACEMENT 구조체에 대한 포인터.
플래그 멤버는 항상 0으로 설정된다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters

5
0

CHAPTER 14
? WINDOWPLACEMENT Structure
? The WINDOWPLACEMENT structure contains information about the
placement of a window on the screen
? typedef struct tagWINDOWPLACEMENT {
UINT length;
UINT flags;
UINT showCmd;
POINT ptMinPosition;
POINT ptMaxPosition;
RECT
rcNormalPosition;

/* wndpl */

(C) 1998 Sang Il Kim

} WINDOWPLACEMENT;

Visual C++ Programming

5
0

? WINDOWPLACEMENT Structure
? Members
?length Specifies the length, in bytes, of the structure.
?flags Specifies flags that control the position of the minimized
window and the method by which the window is restored.
This member can be one or both of the following flags:
WPF_SETMINPOSITION Specifies that the x- and y-positions of the
minimized window can be specified. This flag must be specified if the
coordinates are set in the ptMinPosition member.
WPF_RESTORETOMAXIMIZED Specifies that the restored window
will be maximized, regardless of whether it was maximized before it
was minimized. This setting is valid only the next time the window is
restored. It does not change the default restoration behavior.
This flag is valid only when the SW_SHOWMINIMIZED value is
specified for the showCmd member.
?showCmd Specifies the current show state of the window.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 14

5
0

CHAPTER 14
? PreCreateWindow() 멤버 함수
? 윈도우가 화면에 출력되기 전에 윈도우의 특성을 변경시키기 위해
override 한다.
? 프레임워크는 ActivateFrame()을 호출하기 전에 PreCreateWindow() 함수
를 호출한다.
? CREATESTRUCT 구조체를 파라미터로 갖는다.
?style 윈도우에 경계선, 스크롤바, 최소화 박스 등을 갖게 할 것인지를 결정
?dwExStyle 상태바를 항상 상단에 있게 설정
? CWnd::PreCreateWindow
? virtual BOOL PreCreateWindow( CREATESTRUCT& cs );
? Parameters
?cs 생성되는 윈도우를 기술하는 CREATESTRUCT 구조체에 대한 포인터.
Visual C++ Programming

(C) 1998 Sang Il Kim

?lpszClass 윈도우의 배경 브러시, 커서, 아이콘을 변경

5
0

CHAPTER 14
? 윈도우 레지스트리

? TEXTPROC
// 프로그램명, Root Key
Text formatting
// Heading name,
Font = Times Roman
// Entry name, Value
Points = 10
// Entry name, Value
? MFC 는 INI 파일에 사용했던 4개의 CWinApp 멤버 함수로 레지스트리에
접근한다.

?SetRegistryKey(_T(“Local AppWizard-Generated Applications”));
이 라인을 제거하면 어플리케이션은 더 이상 레지스트리를 사용하지 않고,
윈도우 디렉토리(c:\Windows)에 INI 파일을 생성하여 사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? Registry는 윈도우에 의해서 운영되는 시스템 파일들의 집합체
? Registry는 문자열 데이터와 정수 데이터로 이루어진 키에 의해 액세스되는
계층적 데이터베이스로 구성되어 있다.
? 사용자와 관련된 정보 - USER.DAT
? 하드웨어와 컴퓨터와 관련된 셋팅 - SYSTEM.DAT
? 모든 레지스트리 함수들은 파라미터로 헤딩명(heading name)과
엔트리명(entry name)을 갖는다.

5
0

CHAPTER 14
? 윈도우 레지스트리
? 헤딩명과 엔트리명을 정의하는 레지스트리 함수
?GetProfileInt
?GetProfileString
?WriteProfileInt
?WriteProfileString
? 레지스트리 함수를 사용하려면 어플리케이션 객체 포인터가 필요하므로
글로벌 함수 AfxGetApp()를 이용한다.
?AfxGetApp()->WriteProfileString(“Text formatting”, “Font”,
?AfxGetApp()->WriteProfileString(“Text formatting”, “Point”, 10);

Visual C++ Programming

(C) 1998 Sang Il Kim

“Times Roman”);

5
0

CHAPTER 14
? CWinApp::SetRegistryKey
? 레지스트리 키를 설정하고 프로파일 액세스 멤버(WriteProfileInt,
GetProfileString)가 호출될 때, 레지스트리를 사용하기 위하여 MFC에
알려준다.
? 레지스트리 키는 보통 회사 이름이다.
? 이 함수는 다른 레지스트리 멤버가 호출되기 전에 호출되어야 한다.
? void SetRegistryKey( LPCTSTR lpszRegistryKey );
? Parameters
?lpszRegistryKey 레지스트리 키
?nIDRegistryKey 레지스트리 키를 지정하는 문자열 리소스 ID.

Visual C++ Programming

(C) 1998 Sang Il Kim

? void SetRegistryKey( UINT nIDRegistryKey );

5
0

CHAPTER 14
? CWinApp::GetProfileInt
? 레지스트리나 어플리케이션 이름의 .INI 파일에서 정수 값을 얻는다.
? GetProfileInt는 프로그래머가 먼저 SetRegistryKey()를 호출하는 경우에만
그 레지스트리를 사용할 수 있다.
?UINT GetProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault );
?Parameters
?lpszSection
섹션이름
?lpszEntry
엔트리 이름
?nDefault
엔트리가 없을 때 리턴되는 값
unsigned value : 0 - 65,535, signed value : -32,768 - 32,767
? 레지스트리나 어플리케이션 이름의 .INI 파일에서 문자열 값을 얻는다.
? GetProfileString은 프로그래머가 먼저 SetRegistryKey()를 호출하는 경우에만
그 레지스트리를 사용할 수 있다.
? CString GetProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPCTSTR lpszDefault = NULL);
? Parameters
?lpszSection 섹션 이름
?lpszEntry
엔트리 이름
?lpszDefault
엔트리가 없을 때 리턴되는 값.
NULL은 빈 문자열이 리턴되었다는 것을 나타낸다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CWinApp::GetProfileString

5
1

CHAPTER 14
? CWinApp::WriteProfileInt
? 레지스트리나 어플리케이션 이름의 .INI 파일에 정수 값을 쓴다.
? WriteProfileInt는 프로그래머가 먼저 SetRegistryKey()를 호출한 다음에만
레지스트리를 사용할 수 있다.
? BOOL WriteProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue );
? Parameters
?lpszSection 섹션 이름
?lpszEntry
엔트리 이름
?nValue
쓰기할 정수 값

레지스트리를 사용할 수 있다.
? BOOL WriteProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPCTSTR lpszValue );
? Parameters
?lpszSection 섹션 이름
?lpszEntry
엔트리 이름
?lpszValue
쓰기할 문자열 값. NULL이면 엔트리는 제거된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CWinApp::WriteProfileString
? 레지스트리나 어플리케이션 이름의 .INI 파일에 문자열 값을 쓴다.
? WriteProfileString은 프로그래머가 먼저 SetRegistryKey()를 호출한 다음에만

5
11

CHAPTER 14
? Example
CString strSection
= "My Section";
CString strStringItem = "My String Item";
CString strIntItem
= "My Int Item";
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileString(strSection, strStringItem, "test");

pApp->WriteProfileInt(strSection, strIntItem, 1234);
int nValue;
nValue = pApp->GetProfileInt(strSection, strIntItem, 0);
ASSERT(nValue == 1234);
Visual C++ Programming

(C) 1998 Sang Il Kim

CString strValue;
strValue = pApp->GetProfileString(strSection, strStringItem);
ASSERT(strValue == "test");

5
1

CHAPTER 14
? CString 클래스 사용하기
? CString 클래스의 가장 중요한 특징
?동적 메모리 할당
? CString 객체의 사용 방법
CString strFirstName(“Elvis”);

char *buf;
buf = (char *) calloc( 20, sizeof(char) );
ASSERT( buf != NULL );
strcpy( buf, "Hello, World" );
free( buf );

CString strLastName(“Presley”);
CString strTruth = strFirstName + “ “ + strLastName;

// 연결

strTruth += “ is alive”;
ASSERT( strTruth == “Elvis Presley is alive” );
ASSERT( strTruth[2] == ‘v’);

// 서브 스크립트 연산자

? ASSERT
?하나의 불 값 매개변수를 계산하여 결과가 FALSE이면, 진단 메시지를
출력하고(MFC의 디버그 버전에서), 프로그램을 중단시키게 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

ASSERT( strTruth.Left(5) == strFirstName );

5
1

CHAPTER 14
? CString 클래스 사용하기
? 프로그램은 그 함수들의 문자열 표현 방식에 맞춰 일치시켜야 한다.
? CString 클래스가 CString 객체를 문자 포인터로 전환하는 const char*
연산자를 제공한다.
? LPCTSTR은 CString 객체 포인터가 아니라 const char*를 표현한 것

? CWinApp에서 파생한 클래스의 DoMessageBox 함수를 호출하는 Helper 함수
? int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );
? int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK,
UINT nIDHelp = (UINT) -1 );
? Parameters
?lpszText
메시지의 텍스트
?nType
메시지 상자의 모양과 옵션을 기술하는 SDK에 정의되어 있는 하나 또는
그 이상의 메시지의 조합
?nIDHelp
nIDHelp 도움말 텍스트의 인덱스.
사용되지 않으면 0, 문자열 리소스의 ID의 값이 사용되면 -1.
?nIDPrompt 메시지의 텍스트에 대한 문자열 리소스 ID
Visual C++ Programming

(C) 1998 Sang Il Kim

? AfxMessageBox

5
1

CHAPTER 14
? CWnd::MessageBox
? int MessageBox( LPCTSTR lpszText, LPCTSTR lpszCaption = NULL,
UINT nType = MB_OK );

?lpszCaption
?nType

메시지박스에 표시하려는 텍스트를 포함하는 널로 끝나는
문자열에 대한 포인터
메시지박스의 캡션으로 표시하려는 텍스트를 포함하는 널로 끝나는
문자열에 대한 포인터
플래그의 조합

? Message_Box Types
?MB_ABORTRETRYIGNORE
?MB_OK
?MB_OKCANCEL
?MB_RETRYCANCEL
?MB_YESNO
?MB_YESNOCANCEL
? 아이콘 플래그
?MB_ICONSTOP
?MB_ICONEXCLAMATION

Abort, Retry, and Ignore.
OK.
OK and Cancel.
Retry and Cancel.
Yes and No.
Yes, No, and Cancel.
?MB_ICONQUESTION
?MB_ICONINFORMATION
Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?lpszText

5
1

CHAPTER 14
? CString 클래스 사용하기
? const char* 연산자는 CString 객체를 상수 문자 포인터로 변환해 주는 역할을 한다.
? 상수 문자 포인터를 CString 객체로 변환하려면?
?상수 문자 포인터를 CString 객체로 변환해 주는 생성자는 CDC::TextOut()
등과 같이 CString 참조 파라미터를 갖는 함수와 함께 실행된다.
?pDC->TextOut( 0, 0, “Hello, World!”, 13 );
? 문자열 파라미터를 갖는 함수를 만들 경우 선택할 사항
?함수가 문자열의 내용을 변경하지 않고, 이 함수 내의 strcpy() 와 같은
C 런타임 함수를 사용할 경우 const char* 파라미터를 사용하도록 한다.
사용할 경우 const CString& 파라미터를 사용하도록 한다.
?함수가 문자열의 내용을 변경하는 경우 CString& 파라미터를 사용하도록 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?함수가 문자열의 내용을 변경하지 않고, 이 함수 내에서 CString 멤버 함수를

5
1

CHAPTER 14
? 최대화된 윈도우의 위치
? 윈도우 우측 상단 코너에 있는 버튼(최대화 버튼)
?최대화된 윈도우가 자신의 원래 크기와 위치를 기억하고 있다는 것을 의미.
? GetWindowRect - 윈도우의 스크린 좌표를 구한다.
? GetWindowPlacement - 현재 윈도우가 최대화/최소화 되어 있는 상태인지,
아니면 두 경우 모두 해당되는 상태인지를 나타내는 플래그와 함께 윈도우가
최대화되지 않은 상태의 좌표를 구해준다.
? SetWindowPlacement - 윈도우의 최대화/최소화된 상태,
윈도우의 위치/크기를 설정한다.

? void GetWindowRect( LPRECT lpRect ) const;
? Parameters
?lpRect 윈도우 좌표로 채워지는 RECT 구조체나 CRect 객체에 대한 포인터

Visual C++ Programming

(C) 1998 Sang Il Kim

? CWnd::GetWindowRect - 윈도우 사각형의 좌표를 얻는다.

5
1

CHAPTER 14
? 컨트롤바의 상태와 레지스트리
? SaveBarState(), LoadBarStatw()를 제공
? 정적 데이터 멤버
? CPersistentFrame 클래스는 레지스트리 키 이름을 static const char 배열
데이터 멤버에 저장한다.
? 전역변수를 이용하는 경우는 Encapsulation에 역행하므로 사용하지 않는다.
? 정적 데이터멤버를 선택하도록 한다.
?정적 데이터 멤버는 상수로서 프로그램의 읽기전용 데이터 섹션에 분리하여
넣을 수 있고 동일한 프로그램의 여러 인스턴스에 맵핑될 수 있다.
? 디폴트 윈도우 사각형
? CPersistentFrame 클래스는 고정된 크기와 위치를 갖는 디폴트 윈도우 사각
형을 나타내는 rectDefault 를 정적 데이터 멤버로 선언하여 기초 클래스
멤버를 은닉한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CRect rect( CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 );

5
1

CHAPTER 14
? RECT Structure
? The RECT data structure has the following form:
? typedef struct tagRECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
The RECT structure defines the coordinates of the upper-left and
lower-right corners of a rectangle.
?left
?Top
?Right
?Bottom

Specifies the x-coordinate of the upper-left corner of a rectangle.
Specifies the y-coordinate of the upper-left corner of a rectangle.
Specifies the x-coordinate of the lower-right corner of a rectangle.
Specifies the y-coordinate of the lower-right corner of a rectangle.

Visual C++ Programming

(C) 1998 Sang Il Kim

? Members

5
1

FISHING TIPS

(C) 1998 Sang Il Kim

Go where the “fish” are.
Use the right “bait”.
Be patient!

Visual C++ Programming

5
2

CHAPTER 15

(C) 1998 Sang Il Kim

뷰로부터 도큐먼트 분리

Visual C++ Programming

5
2

CHAPTER 15
? 도큐먼트 / 뷰 상호작용 함수
? 도큐먼트 객체 - 데이터를 저장
? 뷰 객체
?도큐먼트 객체의 데이터를 출력하거나 편집할 수 있도록 해준다.
?자신과 연결된 하나의 도큐먼트 객체만을 가지고 있다.

? SDI 어플리케이션
?CDocument 에서 파생된 하나 이상의 뷰 클래스를 갖는다.

? CView::GetDocument() 함수
도큐먼트 포인터를 제공하여 뷰에서 도큐먼트를 조정할 수 있도록 해준다.
? 사용자가 에디트 컨트롤에 새로운 데이터를 입력할 때 뷰 객체가 메시지를
받는다면 새로운 데이터가 입력됨에 따라 뷰는 도큐먼트 객체에게 기존
데이터를 갱신하도록 알려야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 도큐먼트 클래스의 멤버 함수 또는 public 데이터 멤버를 접근할 수 있도록

5
2

CHAPTER 15
? CView::GetDocument() 함수
? CView 에서 파생된 클래스를 생성할 때 CDocument 포인터가 아닌 파생된
클래스의 객체 포인터를 리턴한다.
? CMyDoc* GetDocument()
{
return (CMyDoc*) m_pDocument;
}
? 컴파일러는 뷰 클래스 코드에서 GetDocument() 함수를 호출할 때
CDocument의 객체 포인터가 아닌 파생된 클래스의 객체 포인터를 리턴하는
(C) 1998 Sang Il Kim

함수를 사용하므로 리턴된 값을 형변환시킬 필요가 없다.
? CView::GetDocument
? CDocument* GetDocument( ) const;
Visual C++ Programming

5
2

CHAPTER 15
? CDocument::UpdateAllViews() 함수
? 도큐먼트 데이터가 변경되면 모든 뷰는 변경된 사실을 통보받아 각각의 뷰가
표시하고 있는 데이터를 갱신할 수 있어야 한다.
? UpdateAllViews() 함수가 호출되면 뷰에서는 OnUpdate()가 호출된다.

? 도큐먼트와 관련된 모든 뷰들을 갱신하는데 사용된다.
? 주어진 파라미터로 각각의 CView::OnUpdate 멤버를 호출한다.
? void UpdateAllViews( CView* pSender, LPARAM lHint = 0L,
CObject* pHint = NULL );
? Parameters
?pSender 갱신을 시작하는 CView 객체
NULL이면 모든 뷰가 갱신(update)된다.
?lHint 변경한 데이터 내용에 대한 정보를 제공할 수 있는 프로그래머의 지시 내용
?pHint lHint에 의해 기술되는 지시 내용에 좀더 세부적인 내용을 포함하고
있는 CObject에서 파생한 클래스
Visual C++ Programming

(C) 1998 Sang Il Kim

? CDocument::UpdateAllViews

5
2

CHAPTER 15
? CView::OnUpdate() 함수
? 파생된 뷰 클래스의 OnUpdate() 함수는 일반적으로 도큐먼트 객체에 접근하여
데이터를 얻은 다음 변경된 내용을 뷰의데이터 멤버나 컨트롤에 반영하여 갱신한다
? 뷰의 일부를 무효화하여 OnDraw() 함수에 의해 도큐먼트 데이터를 윈도우에
다시 그리도록 한다.
? 디폴트 OnUpdate()는 윈도우 사각형 전체를 무효화하여 윈도우 영역 전체를
다시 그린다.
? 도큐먼트에 있는 정보가 변경될 때 호출되고, 뷰는 이 새로운 정보를 반영하기
위하여 갱신된다.
? 전체 뷰 윈도우가 갱신되게 무효화한다.
? virtual void OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint );
? Parameters
?pSender 갱신을 시작하는 뷰. NULL이면 모든 뷰가 갱신(update)된다.
?lHint
어떤 도큐먼트 정보가 변경되었는가를 나타내는 프로그래머가
제공하는 코드
?pHint
특정 지시 내용(Hint)을 포함하는 프로그래머가 제공하는 객체
Visual C++ Programming

(C) 1998 Sang Il Kim

? CView::OnUpdate

5
2

CHAPTER 15
? CView::OnInitialUpdate() 함수
? 어플리케이션이 시작될 때, 사용자가 메뉴를 선택했을 때 호출되는 함수
? OnInitialUpdate() 함수는 OnUpdate()함수만을 호출한다.
? 파생된 뷰 클래스에서 OnInitialUpdate() 함수를 override할 경우 기초 클래
스의 OnInitialUpdate() 함수나 파생된 뷰 클래스의 OnUpdate() 함수를
호출해야 한다.
? 어플리케이션이 실행되는 동안 OnCreate() 함수는 한 번 호출되지만
OnInitialUpdate()는 여러 번 호출될 수 있다.

(C) 1998 Sang Il Kim

? CView::OnInitialUpdate
? virtual void OnInitialUpdate( );

Visual C++ Programming

5
2

CHAPTER 15
? CDocument::OnNewDocument() 함수
? 도큐먼트가 처음 생성될 때, 사용자가 메뉴를 선택했을 때 프레임워크는
OnNewDocument() 를 호출한다.
? Override된 OnNewDocument() 함수에는 CDocument::OnNewDocument()
함수 호출이 포함된다.
? CDocument::OnNewDocument
? virtual BOOL OnNewDocument( );
? 도큐먼트가 여러 개의 뷰를 필요로 하지 않고 어플리케이션 프레임워크의
파일 지원을 이용하고자 할 경우 UpdateAllViews() 함수와 OnUpdate()
함수에 대해서는 신경쓰지 않아도 된다.
? 어플리케이션을 만드는 방법
1. 파생된 도큐먼트 클래스 헤더 파일에 도큐먼트의 데이터 멤버들을 선언한다.
2. 파생된 뷰 클래스에서 가상 함수 OnInitialUpdate()를 override한다.
3. 파생된 뷰 클래스의 윈도우 메시지 핸들러, 명령 메시지 핸들러, OnDraw()
함수는 도큐먼트 객체를 접근하기 위해 GetDocument() 함수를 이용하여
도큐먼트 데이터 멤버를 직접 읽거나 갱신한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 간단한 도큐먼트 - 뷰 어플리케이션

5
2

CHAPTER 15
? 간단한 도큐먼트-뷰의 상호작용에 대한 이벤트 순서
어플리케이션 시작 CMyDocument 객체가 생성된다.
CMyView 객체가 생성된다.
뷰 윈도우가 만들어진다.
CMyView::OnCreate() 함수가 호출된다.
CMyDocument::OnNewDocument() 함수가 호출된다.
CMyView::OnInitialUpdate() 함수가 호출된다.
뷰 객체가 초기화 된다.
뷰 윈도우가 무효화된다.
CMyView::OnDraw() 함수가 호출된다.

(C) 1998 Sang Il Kim

사용자 데이터 편집 CMyView 클래스 함수들은 CMyDocument 데이터
멤버를 갱신한다.
어플리케이션 종료 CMyView 객체가 소멸된다.
CMyDocument 객체가 소멸된다.

Visual C++ Programming

5
2

CHAPTER 15
CFormView : public CScrollView

? CFormView 클래스
? 다이얼로그 박스처럼 여러 가지 컨트롤들을 포함시킬 수 있는 뷰

? 다른 뷰들과 마찬가지로 동시에 여러 개의 폼 뷰를 생성할 수 없다.
? DDX, DDV 함수들을 지원한다.
? AppWizard Step6에서 뷰의 기초 클래스로 CFormView를 선택한다.
? CFormView 객체
?통보 메시지 - 폼 뷰 내의 컨트롤로 부터 받는다.
?명령 메시지 - 어플리케이션 프레임워크로 부터 받는다.
? 통보 메시지나 명령 메시지에 대응하여 필요에 따라 직접 UpdateData()
함수를 호출해야 한다.
? GotoDlgCtrl() 또는 NextDlgCtrl() 과 같은 CDialog 멤버 함수를 사용할 수 있다.
? ( (CDialog*) this ) -> GotoDlgCtrl(GetDlgItem(IDC_NAME));
? CFormView 포인터를 CDialog 포인터로 형변환하여 사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CScrollView에서 파생되므로 CDialog 클래스의 멤버 함수들은 지원하지 않는다.

5
2

CHAPTER 15
? TRACE 매크로
? Debug 모드로 설정될 때, 전역변수 afxTraceEnabled가 True로 설정될 때
활성화된다.
? 일반적인 TRACE 문의 형태
int nCount = 9;
CString strDesc(“total”);
TRACE(“Count = %d, Description = %s\n”, nCount, strDesc);
? TRACE 매크로를 사용하여 디버거의 Output 윈도우에 결과를 출력하기
위해서는 MFC Trace Options 다이얼로그의 Enable tracing 이 체크되어야
한다.
(C) 1998 Sang Il Kim

? afxTraceEnabled
? BOOL afxTraceEnabled;
? By default, output from the TRACE macro is disabled.

Visual C++ Programming

5
3

? afxDump
? CDumpContext afxDump;

? 전역 객체 afxDump
? afxDump는 cout과 유사한 문법을 갖는다.
? Overload된 연산자들이 출력 포맷을 제어한다.
? TRACE 문과 동일하게 디버거의 Output 윈도우에 출력된다.
? afxDump 문의 형태
int nCount = 9;
CString strDesc(“total”);
#ifdef _DEBUG
afxDump << “Count = “ << nCount << “ , Description = “ << strDesc << “\n”;
#endif // _DEBUG
? #ifdef 매크로명 #ifdef는 매크로가 정의되어 있으면 문장1을 컴파일 한다.
문장1
매크로가 정의되어 있지 않으면 문장1을 컴파일하지
#endif
않는다.
? #ifndef 매크로명 #ifndef는 매크로가 정의되어 있지않으면 문장1을 컴파일 한다.
문장1
매크로가 정의되어 있으면 문장1을 컴파일하지
#endif
않는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 15

5
3

CHAPTER 15
? 삭제되지 않는 객체의 자동 덤프
? Debug 모드인 경우 어플리케이션 프레임워크는 프로그램 종료시에 삭제되지
않는 모든 객체를 덤프한다.
? 메모리 블록에 디버깅 정보 추가
? 메모리 블록에 디버깅 정보 추가하는 코드는 CRT(C 런타임) 라이브러리의
Debug 버전에 있다.
? CPP파일의 상단부에 다음 라인을 추가하면
#define new DEBUG_NEW
CRT 라이브러리는 메모리 할당이 이루어진 위치의 파일명과 라인 번호를
? AppWizard는 모든 CPP 파일의 상단부에 #define new DEBUG_NEW를
생성한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

리스트 한다.

5
3

CHAPTER 15
? 보다 향상된 도큐먼트 - 뷰 상호작용
? 개발 과정
1. 파생된 도큐먼트 클래스 헤더 파일에 도큐먼트의 데이터 멤버들을 선언한다.
2. ClassWizard를 이용하여 파생된 뷰 클래스에 가상함수 OnUpdate()를 Override 한다.
도큐먼트 데이터가 변경될 때마다 어플리케이션 프레임워크는 OnUpdate() 함수를
호출한다.
3. 모든 명령 메시지들에 대해서 어느 클래스에 맵핑할 것인지를 판단한다.
각 명령 메시지가 도큐먼트 특성적인지, 뷰 특성적인지를 결정한다.
?도큐먼트 - Edit메뉴의 Cleaar All
4. 파생된 뷰 클래스의 명령 메시지 핸들러에서 도큐먼트 데이터를 변경할 수 있도록 만든다
5. 파생된 도큐먼트 클래스의 명령 메시지 핸들러에서 도큐먼트 데이터를 변경할 수
있도록 만든다.
이 메시지 핸들러는 리턴하기 전에 CDocument::UpdateAllViews() 함수를 호출해야 한다

Visual C++ Programming

(C) 1998 Sang Il Kim

이 메시지 핸들러는 리턴하기 전에 CDocument::UpdateAllViews() 함수를 호출해야 한다

5
3

CHAPTER 15
? 향상된 도큐먼트-뷰 상호작용에 대한 이벤트 순서

사용자가 뷰 명령을
실행

CMyDocument 객체가 생성된다.
CMyView 객체가 생성된다.
다른 뷰 객체들이 생성된다.
뷰 윈도우가 만들어진다.
CMyView::OnCreate() 함수가 호출된다.
CMyDocument::OnNewDocument() 함수가 호출된다.
CMyView::OnInitialUpdate() 함수가 호출된다.
CMyView::OnUpdate() 함수를 호출된다.
뷰를 초기화 한다.
CMyView 함수가 CMyDocument 데이터 멤버를 갱신한다.
CDocument::UpdateAllViews() 함수를 호출한다.
다른 뷰들의 OnUpdate() 함수가 호출된다.

사용자 도큐먼트
명령을 실행

CMyDocument 함수가 데이터 멤버를 갱신한다.
CDocument::UpdateAllViews() 함수를 호출한다.
CMyView::OnUpdate() 함수가 호출된다.
다른 뷰들의 OnUpdate() 함수가 호출된다.

어플리케이션 종료

뷰 객체가 소멸된다.
CMyDocument 객체가 소멸된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

어플리케이션 시작

5
3

CHAPTER 15
? CObList 콜렉션 클래스
? CObList 클래스
?CObject에서 파생된 클래스의 객체 포인터에 대한 리스트를 관리한다.
?혼합된 포인터들을 포함할 수 있다.
? CObject 클래스
?진단 덤핑과 직렬화에 대한 이점을 제공해 준다.
? CPtrList 클래스
?CObject 포인터 대신에 void 포인터를 관리한다.
?진단 덤핑과 직렬화에 대한 이점을 제공받지 못한다.
? CObList를 사용하는 방법
?리스트의 맨 끝(tail)에 새로운 요소를 추가하고, 리스트의 맨 앞(head)의
요소를 제거한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? First-In, First-Out(FIFO) 리스트의 CObList 사용하기

5
3

CHAPTER 15

? CObList::GetNext
? 기술한 위치에 근거한 리스트에 있는 다음 노드를 얻는다.
? 컴파일러는 사용하는 문맥에 따라 GetNext의 2개의 형식 중에서 어느 것을
사용하는가를 판단한다.
? CObject*& GetNext( POSITION& rPosition );
? CObject* GetNext( POSITION& rPosition ) const;
? Parameters
?rPosition
현재 노드의 위치

Visual C++ Programming

(C) 1998 Sang Il Kim

? CObList 순환 - POSITION 변수
? CObList 클래스는 “다음 번” 리스트 요소에 대한 포인터를 리턴하는
GetNext() 멤버 함수를 제공한다.
? GetNext() 는 32비트 POSITION 타입의 파라미터를 가지고 있다.
? GetNext() 의 파라미터는 POSITION&로 선언된다.
? POSITION 변수는 리스트에서 검색된 요소의 위치를 내부적으로 표현한 것
? GetNext()
1. POSITION 파라미터에 들어오는 값에 의해 식별되는 리스트 내의 “현재”
객체에 대한 포인터를 리턴해 준다.
2. POSITION 파라미터의 값을 다음 번 리스트 요소를 증가시킨다.

5
3

CHAPTER 15
? Example
? CAction* pAction;
POSITION pos = actionList.GetHeadPosition();
while( pos != NULL){
pAction = (CAction*) actionList.GetNext(pos);
pAction -> PrintTime();
}

? CObList::GetHeadPosition
? 리스트에 있는 첫번째(Head) 노드의 위치를 리턴한다.
? POSITION GetHeadPosition( ) const;
? CDocument::DeleteContents
? 도큐먼트가 갖게 되는 데이터를 제거하기 위하여 호출된다.
? 도큐먼트가 제거되기 전이나 도큐먼트 객체가 재사용되기 전에 호출된다.
? virtual void DeleteContents( );
Visual C++ Programming

(C) 1998 Sang Il Kim

? GetNext() 는 항상 POSITION 변수를 증가시키므로 GetNext() 를
이용하여 엔트리를 검색할 수가 없다.

5
3

CHAPTER 15
? 다음 번 리스트 요소를 얻는 명령 메시지 핸들러 함수
? m_actionList - CObList 객체로 CMyView 클래스에 포함된다.
? m_position - 현재의 리스트 위치를 저장하는 POSITION 변수
? void CMyView::OnCommandNext()

}

POSITION pos;
CAction* pAction;
if((pos = m_position) != NULL) {
m_actionList.GetNext(pos);
// 리스트의 위치를 증가시킨다.
if(pos != NULL) {
// 리스트의 끝에서 pos는 NULL이 된다.
pAction = (CAction*) m_actionList.GetAt(pos); // 엔트리를 검색한다.
pAction -> PrintTime();
m_position = pos;
}
else {
AfxMessageBox(“End of list reached”);
}
}
Visual C++ Programming

(C) 1998 Sang Il Kim

{

5
3

CHAPTER 15
? CObList::GetAt
? 기술한 위치에 근거한 노드의 데이터를 리턴한다.
? 컴파일러는 사용하는 문맥에 따라 GetAt의 2개의 형식 중에서 어느 것을
사용하는가를 판단한다.
? CObject*& GetAt( POSITION position );
? CObject* GetAt( POSITION position ) const;
? Parameters
?position
원하는 노드의 위치

? 혼합된 포인터를 콜렉션에 포함되도록 할 경우
?CObList 클래스를 이용한다.
? 한 가지 타입의 객체 포인터만을 포함하는 type-safe 콜렉션이 필요한 경우
?MFC 라이브러리 템플릿 콜렉션의 CTypedPtrList 클래스를 이용한다.
? CTypedPtrList - 지정된 클래스의 객체 포인터를 리스트로 관리한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CTypedPtrList 템플릿 콜렉션 클래스

5
3

CHAPTER 15
? CTypedPtrList 템플릿 콜렉션 클래스
? CAction 포인터를 위한 객체 선언
?CTypedPtrList<CObList, CAction*> m_actionList;
콜렉션의 기초클래스

파라미터 타입,
리턴값의 타입

? 기초 클래스로는 CPtrList, CObList 두 가지 만이 사용될 수 있다.
( 두 클래스만이 MFC 라이브러리 포인터 리스트 콜렉션 클래스이다.)
? CObject 에서 파생된 클래스의 객체를 저장하려면 CObList나 ,
CPtrList를 사용해야 한다.
? typedef CTypedPtrList<CObList, CAction*> CActionList; // 간결한 선언
? CActionList m_actionList;
Visual C++ Programming

(C) 1998 Sang Il Kim

? pAction = m_actionList.GetAt(pos); // 형 변환이 필요없다.

5
4

? 덤프 컨텍스트(Dump Context)와 콜렉션 클래스
? 콜렉션의 요소가 되는 객체가 DECLARE_DYNAMIC 과
IMPLEMENT_DYNAMIC 매크로를 사용할 경우 Dump() 함수는
각 객체의 클래스 이름을 출력해준다.
? 콜렉션 Dump() 함수는 요소가 되는 객체의 클래스 이름과 객체 주소만을
디폴트로 출력한다.
? #ifdef _DEBUG
afxDump.SetDepth(1); // Specifies deep dump
#endif
? CDumpContext::SetDepth
? #ifdef _DEBUG
? void SetDepth( int nNewDepth );
afxDump << actionList;
? Parameters
#endif
?nNewDepth The new depth value.
?결과
a CObList at $411832
with 4 elements
a CAction at $412CD6

time = 0

a CAction at $412632
a CAction at $4126EA
time = 1
time = 3
a CAction at $41268E

time = 2

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 15

5
4

CHAPTER 15
CWinApp
CWinApp
응용
응용 프로그램
프로그램 개체
개체

CDocTemplate
CDocTemplate
문서
문서 템플릿
템플릿

문서
문서

CFrameWnd
CFrameWnd
응용 프로그램 프레임 창
CView
보기 창

◐ 단순한 문서/보기 응용 프로그램 구조를 위한 클래스 관계 ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

CDocument
CDocument

5
4

CHAPTER 16

(C) 1998 Sang Il Kim

도큐먼트 읽기/쓰기
- SDI 어플리케이션

Visual C++ Programming

5
4

CHAPTER 16
? 직렬화(Serialization)란?
? 객체들을 영구화시킴으로써 프로그램이 종료할 때 디스크에 저장(save)하고
프로그램이 재 실행될 때 디스크로부터 복원(restore)하는 일련의
처리과정을 직렬화(serialization)라 한다.
? Serialize() 함수는 사용자가 File 메뉴의 Open 아이템이나 Save 아이템을
선택할 때 어플리케이션 프레임워크에 의해 호출된다.
? 도큐먼트와 결합된 모든 객체는 디스크 파일에 순차적으로 저장되고
읽혀지기 때문에 디스크 파일의 임의적인 주소에서 개별적인 객체를
접근할 수 없다.
(C) 1998 Sang Il Kim

? 직렬화는 데이터베이스 관리 시스템으로 대체될 수가 없다.
? 순차적 파일과 데이터베이스 사이에 적용할 수 있는 저장 방식
?OLE 구조화 저장(Structured Storage)
Visual C++ Programming

5
4

CHAPTER 16
? 디스크 파일과 보관소
? 디스크 파일 - CFile 클래스 객체로 표현
? CFile 객체
?Win32 함수 CreateFile() 을 통해 얻을 수 있는 이진 파일 핸들을 포함한다.
? 어플리케이션 프레임워크는 ReadFile(), WriteFile(), SetFilePointer() 등의
Win32 함수 호출시에 파일 핸들을 포함한다.
? CArchive 객체
?CFile 객체의 데이터를 위한 중간 보관소 역할을 한다.

?활성화된 하나의 Archive만이 파일과 연결된다.
? Serialize() 함수
?CArchive 객체에 데이터를 저장하거나 CArchive 객체로부터 데이터를
읽어들인다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?디스크에 저장되는지, 아니면 디스크로부터 읽혀지는지의 여부를 나타내는
내부 플래그를 가지고 있다.

5
4

CHAPTER 16
? 디스크 파일과 보관소

Serialization

CArchive 객체

CFile 객체

? Archive - 원본에서 만들어지며, 원본 재현에 충분한 데이터가 포함되어
있는 파일 (이진 포맷으로 저장)
Visual C++ Programming

(C) 1998 Sang Il Kim

영구적인
도큐먼트 오브젝트

? 어플리케이션 프레임워크
?CFile 객체와 CArchive 객체를 생성
?CFile 객체로 디스크 파일을 열고
?CArchive 객체를 열린 파일과 연결한다.

5
4

CHAPTER 16
? CObject에서 클래스를 파생하기
? CObject에서 클래스를 파생하는 것은 CObject 런타임 정보, 동적인 생성과
Serialize 서비스가 요구될 때 클래스의 선언(DECLARE_매크로)과
구현(IMPLEMENT_매크로)에 매크로를 삽입하는 것을 제외하고는
다른 클래스의 파생과 같다.
? CObject에서 파생한 클래스에 대한 매크로
용도

DECLARE_DYNAMIC
IMPLEMENT_DYNAMIC
DECLARE_DYNCREATE
IMPLEMENT_DYNCREATE
DECLARE_SERIAL
IMPLEMENT_SERIAL

런타임
런타임
런타임
런타임
런타임
런타임

위치
정보
클래스
정보
클래스
정보와 동적인 생성
클래스
정보와 동적인 생성
클래스
정보, 동적인 생성과 Serialize 클래스
정보, 동적인 생성과 Serialize 클래스

선언
구현
선언
구현
선언
구현

? 직렬화 클래스 만들기
? 클래스 선언 - DECLARE_SERIAL 매크로 호출을 포함해야 한다.
? 클래스 구현 파일 - IMPLEMENT_SERIAL 매크로 호출을 포함해야 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

매크로

5
4

CHAPTER 16

? IMPLEMENT_DYNAMIC
? 런타임 정보를 사용하는 CObject에서 파생한 클래스의 구현의 부분
? 확장될 때, 이 매크로는 그 클래스에 대한 static CRuntimeClass 구조체를 초기화한다.
? GetRuntimeClass() 멤버 함수를 구현한다.
? IMPLEMENT_DYNAMIC( class_name, base_class_name )
? Parameters
?class_name
클래스 이름 (어떤 인용문도 필요 없다).
?base_class_name
기초 클래스 이름 (어떤 인용문도 필요 없다).
Visual C++ Programming

(C) 1998 Sang Il Kim

? DECLARE_DYNAMIC
? 런타임 정보를 사용하는 CObject에서 파생한 클래스의 선언의 부분
? 확장될 때, 이 매크로는 적당한 CRuntimeClass 데이터 정보를 클래스에 추가한다.
? 이 구조체는 이 정보를 제공하는 데 필요한 부하를 소화하기 위하여 클래스의
static 멤버이다.
? 매크로는 static CRuntimeClass 구조체를 얻는데 사용되는 GetRuntimeClass()
멤버 함수를 포함한다.
? DECLARE_DYNAMIC( class_name )
? Parameters
?class_name
클래스 이름 (어떤 인용문도 필요 없다).

5
4

CHAPTER 16

? IMPLEMENT_DYNCREATE
? 동적인 생성을 사용하는 CObject에서 파생한 클래스의 구현의 부분
? 이 매크로는 IMPLEMENT_DYNAMIC 매크로로 확장되고, 이 클래스의 객체가
동적인 생성을 위해서 MFC에 의해 내부적으로 사용되는 static CreateObject()
멤버 함수를 구현한다.
? IMPLEMENT_DYNCREATE( class_name, base_class_name )
? Parameters
?class_name
클래스 이름 (인용부호는 필요 없다).
?base_class_name 기초 클래스 이름 (인용부호는 필요 없다).
Visual C++ Programming

(C) 1998 Sang Il Kim

? DECLARE_DYNCREATE
? 동적인 생성을 사용하는 CObject에서 파생한 클래스의 선언의 부분
? 이 매크로는 DECLARE_DYNAMIC 매크로로 확장되고, 이 클래스의 객체가
동적인 생성을 위해서 MFC에 의해 내부적으로 사용되는 static CreateObject()
멤버 함수를 추가한다.
? DECLARE_DYNCREATE( class_name )
? Parameters
?class_name
클래스 이름 (인용부호는 필요 없다).

5
4

CHAPTER 16
? DECLARE_SERIAL
? 시리얼라이즈를 사용하는 CObject에서 파생하는 클래스의 선언의 부분
? 이 매크로는 DECLARE_DYNAMIC 매크로로 확장되고, 시리얼라이즈를 위하여
MFC에 의해 내부적으로 사용되는 연산자 >> 멤버를 추가한다.
? DECLARE_SERIAL( class_name )
? Parameters
?class_name
클래스 이름 (인용부호는 필요 없다).
? IMPLEMENT_SERIAL
? 시리얼라이즈를 사용하는 CObject에서 파생하는 클래스의 구현의 부분
? 이 매크로는 IMPLEMENT_DYNAMIC 매크로로 확장되고, 시리얼라이즈를 위하여
MFC에 의해 내부적으로 사용되는 연산자 >> 멤버를 구현한다.
? 어플리케이션이 객체의 다른 버전을 지원할 필요가 있으면, 객체에 대한 스키마의
변경이 그 클래스의 Serialize() 멤버에 반영되어야 한다.
? IMPLEMENT_SERIAL( class_name, base_class_name, wSchema )
? Parameters
?class_name
클래스 이름 (인용부호는 필요 없다).
?base_class_name
기초 클래스 이름 (인용부호는 필요 없다).
?wSchema
클래스의 "version number" , UINT

Visual C++ Programming

(C) 1998 Sang Il Kim

? 스키마(schema) 파라미터는 동일한 객체의 다른 버전 사이에서 구분하는 데 사용된다.

5
5

CHAPTER 16
? DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC
? 클래스 이름, MFC계층 내에서의 위치와 같은 실행 시간 클래스 정보에
액세스할 수 있게 한다.
? DECLARE_SERIAL, IMPLEMENT_SERIAL
? 기본 수준 매크로의 기능을 모두 포함하고 있다.
? 객체들이 자신의 데이터를 Archive로 부터 읽거나 쓸 수 있도록 지원한다.
- 직렬화(serialization)
레벨2 매크로
레벨1 매크로

(C) 1998 Sang Il Kim

DECLARE_DYNAMIC
IMPLEMENT_DYNAMIC
DECLARE_SERIAL
IMPLEMENT_SERIAL
Visual C++ Programming

5
5

CHAPTER 16
? Serialize() 함수 작성

어플리케이션의 CArchive 객체를
식별하는 CArchive형 참조자

? void CStudent::Serialize(CArchive& ar)
{
TRACE (“Entering CStudent::Serialize\n”);
if( ar.IsStoring()) {
ar << m_strName << m_nGrade;

현재 요청된 작업이
저장하기 위한 작업인지,
로드하기 위한 작업인지를
알려준다.

}
else {
}
}
? Serialize() 함수는 CObject 클래스의 가상 함수이므로 리턴값과 파라미터
타입을 CObject 함수 원형과 일치시켜야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

ar >> m_strName >> m_nGrade;

5
5

CHAPTER 16
? Serialize() 함수 작성
? 삽입(<<), 추출(>>) 연산자
?삽입(<<) 연산자 - 객체 ar 에 순차적으로 데이터를 저장
?추출(>>) 연산자 - 객체 ar로부터 순차적으로 데이터를 읽어들인다.
? 데이터 멤버로 나열형 m_nType이 있을 경우
?ar << (int) m_nType;
?ar >> (int&) m_nType;

{

}

public:
CTranscript m_transcript;

if(ar.IsStoring()) {
ar << m_strName << m_nGrade;
}
else {
ar >> m_strName >> m_nGrade;
}
m_transcript.Serialize(ar); // CTranscript 클래스는 CObject 로부터 파생되어

자신만의 Serialize() 멤버 함수를 가진 클래스

Visual C++ Programming

(C) 1998 Sang Il Kim

? 아키이브로 부터 읽기 - 포함된 객체와 포인터
? void CStudent::Serialize(CArchive& ar)

5
5

CHAPTER 16
? 아키이브로 부터 읽기 - 포함된 객체와 포인터
? void CStudent::Serialize(CArchive& ar)
{

public:
CTranscript* m_Transcript;

if(ar.IsStoring()) {
ar << m_strName << m_nGrade;
}
else {
m_Transcript = new CTranscript;
ar >> m_strName >> m_nGrade;
m_Transcript.Serialize(ar); // CTranscript 객체 포인터를
}

데이터 멤버로 포함할 경우

Visual C++ Programming

(C) 1998 Sang Il Kim

}

5
5

CHAPTER 16
? 아키이브로 부터 읽기 - 포함된 객체와 포인터
CArchive 삽입(<<), 추출(>>)
? void CStudent::Serialize(CArchive& ar)
연산자는 CObject를 지원
{
if(ar.IsStoring())
ar << m_strName << m_nGrade << m_pTranscript;
else
ar >> m_strName >> m_nGrade >> m_pTranscript;
}
&m_Transcript;로
할 수는 없다.
? CTranscript 객체 생성
?CTranscript 클래스에 DECLARE_SERIAL, IMPLEMENT_SERIAL 매크로를 사용.

? CTranscript 객체가 CArchive 에 저장될 때 매크로에 의해 해당 클래스 이름과
? 읽어들일 때는 클래스 이름으로 읽혀진다.
? CStudent 객체가 생성되고 CArchive로부터 데이터가 로드되지 않았다면
포인터는 NULL이다.
Visual C++ Programming

(C) 1998 Sang Il Kim

데이터가 함께 저장된다.

5
5

CHAPTER 16
? 직렬화 콜렉션
? 모든 콜렉션 클래스는 CObject에서 파생되고, DECLARE_SERIAL 매크로로
호출이 포함되기 때문에 콜렉션 클래스를 이용하면 편리하게 직렬화 작업을
할 수 있다.
? 콜렉션 클래스의 로딩(Loading)
? 만약 콜렉션이 혼합된 클래스의 객체 포인터를 포함하는 경우
?개개의 클래스 이름이 CArchive에 저장되므로 해당 클래스 생성자가 호출되어
객체들이 생성된다.

?객체의
?객체를
?객체의
?새로운

(C) 1998 Sang Il Kim

? 만약 도큐먼트 등과 같은 컨테이너 객체가 포함된 객체로 콜렉션을 가지고 있으면
?로드된 데이터는 기존 콜렉션에 추가된다.
? 로딩하기 전에 콜렉션을 비워야 할 경우
?도큐먼트의 가상함수 DeleteContents()에서 수행된다.
? CObject 포인터의 콜렉션이 CArchive로부터 로드될 때
클래스가 정의된다.
위해 힙 메모리 영역이 할당된다.
데이터가 할당된 메모리 영역으로 로드된다.
객체의 포인터가 콜렉션에 저장된다.
Visual C++ Programming

5
5

CHAPTER 16
? Serialize() 함수와 어플리케이션 프레임워크
? 도큐먼트 객체가 CArchive 추출 연산자와 함께 사용되지 않고, 콜렉션에
포함되지 않았다면 DECLARE_SERIAL, IMPLEMENT_SERIAL 매크로가
필요 없다.(어플리케이션 프레임워크가 도큐먼트의 Serialize() 함수를 직접 호출한다.)
? SDI 어플리케이션
? 어플리케이션 객체
?CMyApp theApp; // 전역 객체

(C) 1998 Sang Il Kim

?548쪽 참조

Visual C++ Programming

5
5

CHAPTER 16
? 빈 도큐먼트(Empty Document) 생성하기 - CWinApp::OnFileNew()
? 어플리케이션 클래스의 InitInstance() 함수
?AddDocTemplate() 멤버 함수를 호출
OnFileNew()를 호출
? OnFileNew() - 내부적으로 연결된 클래스의 이름들을 정렬한다.
?다음의 과정을 수행
1. 도큐먼트 객체를 구성
2. CMainFrame 클래스의 객체를 구성, 메인 프레임 윈도우를 생성
3. 뷰 객체를 구성, 뷰 윈도우를 생성
4. 도큐먼트, 메인 프레임, 뷰 객체 간을 연결
5. 도큐먼트 오브젝트에 대해 CDocument::OnNewDocument 호출
6. CView::OnInitialUpdate() 멤버 함수 호출
7. 메인 프레임의 가상 함수 CFrameWnd::ActivateFrame()을 호출
? OnFileNew()는 항상 도큐먼트 내용을 지우기 위해
DeleteContents()를 호출
Visual C++ Programming

(C) 1998 Sang Il Kim

DeleteContents() 호출

5
5

CHAPTER 16
? 도큐먼트 클래스의 OnNewDocument() 함수
? 사용자가 File 메뉴의 New, Open 메뉴 아이템을 선택할 때마다 도큐먼트를
초기화하기 위해 OnNewDocument()함수를 Override 해야 한다.
? 실제로 SDI 어플리케이션은 기존 도큐먼트 객체를 재사용한다.
? OnNewDocument()이 제대로 수행되지 않으면 False 를 리턴한다.
? CDocument::GetFile
? CFile 객체에 대한 포인터를 얻는데 사용된다.
? 리턴된 CFile 객체는 반드시 도큐먼트와 관련되지 않는다. 단순한 Helper 함수이다.
? virtual CFile* GetFile( LPCTSTR lpszFileName, UINT nOpenFlags,
CFileException* pError );
파일 이름

?nOpenFlags

파일 열기 플래그

?pError

열기 파일 처리의 상태를 얻는 CFileException에 대한 포인터

Visual C++ Programming

(C) 1998 Sang Il Kim

? Parameters
?lpszFileName

5
5

CHAPTER 16
? 도큐먼트 클래스의 DeleteContents() 함수
? 도큐먼트 객체가 생성될 때, 도큐먼트를 닫을 때 DeleteContents()호출
? SDI 어플리케이션의 경우 DeleteContents() 함수는 현재까지 편집중인
도큐먼트 내용을 삭제할 때 사용한다.
? File Save 와 File Save As를 직렬화 코드에 연결하기
? File 메뉴의 New, Open
?CWinApp::OnFileNew(), CWinApp::OnFileOpen() 에 맵핑

(C) 1998 Sang Il Kim

? File 메뉴의 Save, Save As
? CDocument::OnFileSave(), CDocument::OnFileSaveAs() 에 맵핑

Visual C++ Programming

5
6

CObject 클래스
선언된 헤더 DevStudio\Vc\mfc\include\<afx.h>
용도

객체의 계열화(Serialization), 런타임 클래스 정보, 디버깅 진단 등.

설명

CObject 클래스는 MFC의 뿌리에 해당하는 기본적인 클래스
(거의 모든 MFC 클래스들이 CObject에서 파생된다.)

멤버 함수

IsSerializable(), Serialize(), GetRuntimeClass(), AssertValid(), Dump()

? 직렬화(Serialization)
? BOOL IsSerializable() const;
: 객체를 직렬화할 수 있는지 여부를 조사한다. TRUE, FALSE를 리턴.
(C) 1998 Sang Il Kim

?CAge a(21);
ASSERT(a.IsSerializable());

Visual C++ Programming

5
6

CObject 클래스
? 직렬화(Serialization)
? virtual void Serialize(CArchive& ar);
: CArchive(기록 저장 클래스) 안에 있는 객체의 내용을 읽거나 쓸 수 있다.
?void CAge::Serialize(CArchive& ar)
{
CObject::Serialize(Ar);
if(ar.IsStoring())

// CArchive에 저장을 원하면

ar << m_years;

// m_years를 ar에 저장한다.

ar >> m_years;

// 읽어들이려면
// m_years를 ar에서 읽어들인다.

}

Visual C++ Programming

(C) 1998 Sang Il Kim

else

5
6

CObject 클래스
? 런 타임 클래스 정보(Run-time class information)
? virtual CRuntimeClass* GetRuntimeClass() const;
현재 클래스에 대한 정보(CRuntimeClass 구조체)를 얻어낸다.
예) CAge a(21);
CRuntimeClass* prt = a.GetRuntimeClass();
ASSERT (strcmp (prt->m_lpszClassName, “CAge”)==0);

객체가 파생한 인스턴스인가, CObject에서 파생한 클래스인가를 판단한다.
?Parameter
pClass
기술한 클래스에 대한 CRuntimeClass에 대한 포인터
예) CAge a(21);
ASSERT (a.IsKindOf(RUNTIME_CLASS(CAge)));
ASSERT (a.IsKindOf(RUNTIME_CLASS(CObject)));
Visual C++ Programming

(C) 1998 Sang Il Kim

? BOOL IsKindOf(const CRuntimeClass* pClass) const;

5
6

CObject 클래스
? 출력 진단(Object Diagnostic output)
: 이 두 가지 함수들은 주로 디버깅 할 때 많이 쓰인다. 현재의 작업이 제대로
수행되는지 의심스러울 때 이러한 함수들을 사용한다.
? virtual void AssertValid() const;
: 현재 객체가 제대로 동작하는지 확인 작업을 수행.
디버깅할 때 많이 사용되고, const형이기 때문에 테스트 도중에 객체의
상태를 변화시킬 수 없다.
?void CAge::AssertValid() const
{

?void CAge:Dump(CDumpContext &dc) const
{

CObject::AssertValid();

CObject::Dump(dc);

ASSERT(m_years > 0);

dc << “Age = “ << m_years;
}
(C) 1998 Sang Il Kim

ASSERT(m_years > 105);
}

? virtual void Dump(CDumpContext &dc) const;
?CWinApp 객체에 대한 진단 함수
?지정된 객체의 내용을 CDumpContext 객체에 덤프한다.
Visual C++ Programming

5
6

CHAPTER 17

(C) 1998 Sang Il Kim

도큐먼트 읽기/쓰기
- MDI 어플리케이션

Visual C++ Programming

5
6

CHAPTER 17
? MDI 어플리케이션
? Developer Studio는 소스 코드 파일을 출력하는 윈도우에 대해
MDI 어플리케이션으로 작동하지만 프로젝트에 도큐먼트를 모으는
방식이므로 전형적인 MDI 어플리케이션은 아니다.
? 전형적인 MDI 어플리케이션, MFC 스타일
? 어플리케이션은 한 개의 메뉴와 한 개의 툴바를 가지고 있고
차일드 윈도우로 모든 명령이 전달된다.
? 메인 윈도우의 타이틀 바는 활성화된 차일드 윈도우의 도큐먼트 파일 이름을

? 차일드 윈도우가 없는 상태에서 어플리케이션을 시작되게 하려면
어플리케이션 클래스 파일에 있는 ProcessShellCommand() 의 파라미터를
변경하면 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

반영한다.

5
6

CHAPTER 17
? MDI 어플리케이션 객체
? MDI 나 SDI 어플리케이션은 동일하게 CWinAPP에서 파생된 어플리케이션
객체에 override된 InitInstance() 멤버 함수를 가지고 있다.
? InitInstance() 함수의 AddDocTemplate() 를 호출하는 부분이 MDI와
SDI가 서로 다르다.
? MDI 도큐먼트 템플릿 클래스
? InitInstance() 안의 MDI 템플릿 구성
CMultiDocTemplate* pDocTemplate;
IDR_EX17ATYPE,

// nIDResource

RUNTIME_CLASS(CStudentDoc),

// Doc Class

RUNTIME_CLASS(CChildFrame),

// MDI 차일드 프레임

RUNTIME_CLASS(CStudentView));

// View class

AddDocTemplate(pDocTemplate);
Visual C++ Programming

(C) 1998 Sang Il Kim

pDocTemplate = new CMultiDocTemplate(

5
6

CHAPTER 17

? CObject::GetRuntimeClass
? 호출한 객체의 클래스에 해당되는 CRuntimeClass 구조를 반환한다.
? virtual CRuntimeClass* GetRuntimeClass( ) const;
? Example
// example for CObject::GetRuntimeClass
CAge a(21);
CRuntimeClass* prt = a.GetRuntimeClass();
ASSERT( strcmp( prt->m_lpszClassName, "CAge" ) == 0 );
Visual C++ Programming

(C) 1998 Sang Il Kim

? RUNTIME_CLASS
? RUNTIME_CLASS( class_name )
? Parameters
?class_name 클래스 이름 (인용부호는 필요 없다).
? Example
// example for RUNTIME_CLASS
CRuntimeClass* prt = RUNTIME_CLASS( CAge );
ASSERT( lstrcmp( prt->m_lpszClassName, "CAge" ) == 0 );

5
6

CHAPTER 17
? MDI 도큐먼트 템플릿 클래스
? MDI 어플리케이션
?다중 도큐먼트 타입을 사용할 수 있고 도큐먼트 객체가 하나 이상
존재할 수 있다.
? AddDocTemplate() 함수
?각 도큐먼트 객체와 뷰 객체가 연결된 다중 차일드 윈도우를
MDI 어플리케이션에 지원한다.
? 도큐먼트 템플릿 객체
?어플리케이션이 실행중에 생성된 도큐먼트 객체의 리스트를 관리한다.
CMultiDocTemplate::GetFirstDocPosition() 과 GetNextDoc()를
사용한다.
?도큐먼트 클래스에서 해당 템플릿을 얻기 위해서
CDocument::GetDocTemplate() 를 사용한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?도큐먼트 객체 리스트를 검색하기 위해서

5
6

CHAPTER 17
? CDocTemplate::GetFirstDocPosition
? 템플릿에 관련되는 첫번째 도큐먼트의 POSITION을 얻는다.
? 템플릿에 관련된 모든 도큐먼트를 반복하기 위하여 GetNextDoc와
같이 사용된다.
? virtual POSITION GetFirstDocPosition( ) const = 0;
? CDocTemplate::GetNextDoc
? 템플릿에 관련된 다음 도큐먼트를 얻기 위하여 사용된다.
? GetFirstDocPosition을 처음 호출한 다음에만 사용되어야 한다.
? virtual CDocument* GetNextDoc( POSITION& rPos ) const = 0;
?rPos

(C) 1998 Sang Il Kim

? Parameters
현재 참조 도큐먼트 위치

Visual C++ Programming

5
7

CHAPTER 17
? MDI 프레임 윈도우와 MDI 차일드 윈도우
? SDI 어플리케이션
?하나의 프레임 윈도우 클래스와 하나의 프레임 윈도우 객체만을 가지고 있다.
? MDI 어플리케이션
?두 개의 프레임 윈도우 클래스와 다수의 프레임 윈도우 객체를 가진다.

CMDIFrameWnd

CMDIChildWnd

AppWizard에 의해
객체 수
생성된 클래스
CMainFrame

CChildFrame

1개

차일드
윈도우당
1개

뷰 포함
메뉴와
객체 생성
컨트롤 바 여부
Yes

No

No

어플리케이션
클래스에서
InitInstance 함수

Yes

어플리케이션
프레임워크에 의해
새로운
차일드 윈도우가
열렸을 때
Visual C++ Programming

(C) 1998 Sang Il Kim

기초 클래스

5
7

CHAPTER 17
? 프레임 윈도우 클래스들
? SDI 프레임 윈도우
?클래스 CFrameWnd로부터 파생된 것이다.
?Document/View 응용 프로그램에서 프레임 윈도우는 현재의 Document에
대한 View를 갖게 된다.
? MDI 프레임 윈도우
?클래스 CMDIFrameWnd로부터 파생된 것이다.
?CMDIFrameWnd 객체는 CMDIChildWnd 프레임 윈도우 객체들에 대한
?실제로 Document의 View를 담고 있는 것은 차일드 프레임 윈도우이다.

Visual C++ Programming

(C) 1998 Sang Il Kim

포인터들을 유지하고 있다.

5
7

CHAPTER 17
? MDI 프레임 윈도우와 뷰 윈도우의 관계
Title bar
Menu bar
Toolbar Window

MDI
child frame
window

(C) 1998 Sang Il Kim

View windows

MDI
main frame
window

Status window
Visual C++ Programming

5
7

CHAPTER 17
? MDI 어플리케이션
? CMainFrame* pMainFrame = new CMainFrame;
if( !pMainFrame -> LoadFrame(IDR_MAINFRAME))
return FALSE;
// 차일드 프레임을 생성하기 위해 ProcessShellCommand()를 호출한다.
m_pMainWnd = pMainFrame;
pMainFrame -> ShowWindow(m_nCmdShow);
pMainFrame -> UpdateWindow();
CWinApp 클래스의 데이터 멤버 m_pMainWnd에 설정한다.
? 메인 프레임 윈도우의 객체 포인터를 얻어야 할 경우
전역 함수 AfxGetApp()를 통해 m_pMainWnd에 접근하면 된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? MDI InitInstance() 함수는 메인 프레임 윈도우의 객체 포인터를

5
7

CHAPTER 17
? 메인프레임과 도큐먼트 템플릿 리소스
? MDI 어플리케이션은 IDR_MAINFRAME과 IDR_EX17ATYPE으로 정의된
문자열 리소스와 메뉴 리소스를 가지고 있다.
IDR_MAINFRAME

“.17a\n”
“Ex17a.Document\n”
“Ex17a Document”

// 어플리케이션 윈도우 캡션
// (사용되지 않는다).
// 디폴트 도큐먼트 이름의 루트 부분
// 도큐먼트 타입 이름
// 도큐먼트 타입 설명과 필터
(파일 열기 다이얼로그의 파일 필터)
// 도큐먼트 타입에 대한 확장자
(파일 열기 다이얼로그의 파일 확장자)
// 레지스트리 파일 타입 ID
// 레지스트리 파일 타입 설명
Visual C++ Programming

(C) 1998 Sang Il Kim

“ex17a”
IDR_MYDOCTYPE
“\n”
“Ex17a\n”
“Ex17a\n”
“Ex17a File (*.17a)\n”

5
7

CHAPTER 17
? OnFileNew (p590)
? ID_FILE_NEW 커맨드에 대한 기본 핸들러
? ID_FILE_NEW는 File New 메뉴 커맨드에 대한 AppWizard가 발생한
커맨드이다.
? OnFileNew()는 자신의 도큐먼트 템플릿의 OpenDocumentFile 멤버에
? 단 하나의 도큐먼트 템플릿이 등록되었으면, 등록된 타입의 새로운
도큐먼트가 생성된다.
? 하나 이상이 도큐먼트 템플릿이 등록되었으면, 등록된 도큐먼트 타입들을
표시하는 다이얼로그박스가 표시된다.
? 사용자가 도큐먼트 타입을 선택하면, 선택한 타입의 새로운 도큐먼트가
생성된다.
? ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
? 이 함수는 호출되는 어플리케이션의 메시지맵에 있어야 한다.
? public afx_msg void OnFileNew();
Visual C++ Programming

(C) 1998 Sang Il Kim

NULL을 전달하여 빈 문서를 생성한다.

5
7

CHAPTER 17
? OnFileOpen (p590)
? ID_FILE_OPEN 커맨드에 대한 기본 핸들러
? ID_FILE_OPEN은 File Open 메뉴 커맨드에 대한 AppWizard가 발생한
커맨드이다.
? OnFileOpen()은 DoPromptFileName()을 호출하여 사용자에게 열 파일을
지정하도록 한 다음에, OpenDocumentFile()을 호출하여 파일을 연다.
? ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
? 이 함수는 호출되는 어플리케이션의 메시지맵에 있어야 한다.

(C) 1998 Sang Il Kim

? public afx_msg void OnFileOpen();

Visual C++ Programming

5
7

CHAPTER 17
? DragAcceptFile
? 윈도우가 파일관리자에게 드래그되는 파일을 받는가를 나타내기 위하여 호출한다.
? 받는 것이 가능하면, 윈도우는 WM_DROPFILE 메시지를 받는다.
? void DragAcceptFiles ( BOOL bAccept = TRUE);
? Parameter
bAccept

윈도우가 드래그 파일을 받으면 TRUE, 그렇지 않으면 FALSE

? EnableShellOpen
? RegisterShellFileTypes와 관련되어 어플리케이션이 관련 파일을 열거나
인쇄하기 위하여 윈도우 파일 관리자에 의해 동작되게 한다.
? EnableShellOpen은 프로그램을 동작시킬 때 파일 관리자에게 DDE링크에
(C) 1998 Sang Il Kim

사용된 어플리케이션에 대한 단 하나뿐인 식별자를 만든다.
? protected void EnableShellOpen();

Visual C++ Programming

5
7

CHAPTER 17
? RegisterShellFileTypes
? 모든 어플리케이션의 문서에 대해 OS에 파일 타입을 등록한다.
? CWinApp에서 파생한 InitInstance 멤버에서 호출된다.
? 모든 도큐먼트 템플릿이 어플리케이션에 추가된 다음에 호출되어야 한다.
? protected void RegisterShellFileTypes (BOOL bWin95 = FALSE);
? Parameter
bWin95

윈도우 95에서 동작하면 TRUE, 그렇지 않으면 FALSE

? ProcessShellCommand
? 커맨드라인을 통해 전달된 Shell Command(파일열기/인쇄)를 처리한다.
? Parameter
rCmdInfo

커맨드에 기술한 CCommandLineInfo 객체에 대한 참조

Visual C++ Programming

(C) 1998 Sang Il Kim

? public BOOL ProcessShellCommand (CCommandLineInfo& rCmdInfo);

5
7

CHAPTER 17

(C) 1998 Sang Il Kim

? CCommandLineInfo::CCommandLineInfo
? CCommandLineInfo( );
? Remarks
This constructor creates a CCommandLineInfo object with default values.
The default is to show the splash screen (m_bShowSplash = TRUE)
and to execute the New command on the
File menu (m_nShellCommand = NewFile).
The application framework calls ParseParam to fill data members of
this object.

Visual C++ Programming

5
8

CHAPTER 18

(C) 1998 Sang Il Kim

프린트와 프린트 미리보기

Visual C++ Programming

5
8

CHAPTER 18
? 대화형 Print Page 선택
? 프로그램은 사용자의 페이지 선택에 따라 인쇄할 정보를 계산하고 나서
선택된 페이지를 프린트한다.
? 1000명의 학생 이름을 포함한 리스트에서 학생 리포트 5페이지를 인쇄하려면?
?한 페이지가 50라인이라면 5페이지에는 201에서 250까지의 레코드가 포함된다.
?MFC 리스트 콜렉션 클래스를 이용하면 201번째 학생 레코드에 직접 접근
하지 못해 프린트를 시작하기 전에 처음 레코드부터 200번째 레코드 요소
까지 검색하게 된다.

? 학생 데이터가 여러 라인의 텍스트 바이오 그래픽 필드를 포함한다면
?전체 파일을 검색하여 페이지 브레이크(page break)를 결정해야 한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?CObArray 클래스를 이용하면 학생 레코드의 201번째로 직접 접근할 수 있다.

5
8

CHAPTER 18
? 화면 페이지와 인쇄 페이지 비교
? full-size 용지에 인쇄되는 출력물을 프로그램에서 읽으려면 화면보다 큰
출력 윈도우가 필요하다.
? 이 경우에는 CScrollView 클래스와 같은 스크롤링 뷰가 이상적이다.
? 프린트 미리보기
? 프린트 미리보기는 윈도우의 기능이 아닌 MFC 라이브러리 기능이다.
? 프린트 미리보기 프로그램은 각각의 문자를 검사하여 프린트 디바이스

? 프린터를 위한 프로그램
? 프린트와 프린트 미리보기의 대부분 작업은 어플리케이션 프레임워크가 한다.
? 함수 호출 순서, 오버라이드되는 함수를 숙지해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

컨텍스트를 토대로 문자 위치를 결정하고 적당한 폰트를 선택한 후 프린트
미리보기 윈도우의 적당한 위치에 문자를 출력한다.

5
8

CHAPTER 18
? 프린터 디바이스 컨텍스트와 CView::OnDraw() 함수
? 프로그램은 데이터를 인쇄할 때 CDC 클래스의 디바이스 컨텍스트 객체를 사용한다.
? 어플리케이션 프레임워크
?디바이스 컨텍스트 객체를 생성하여 뷰의 OnDraw() 함수에 파라미터로 전달한다
? 화면에 출력중이면 OnPaint() 함수는 디스플레이 디바이스 컨텍스트 (화면 DC)를
OnDraw() 함수에 파라미터로 전달한다.
? 인쇄중이면 CView 가상 함수 OnPaint()는 프린터 디바이스 컨텍스트 (프린터 DC)를
OnDraw() 함수에 파라미터로 전달한다.
? OnPaint() 함수는 한 페이지를 프린트할 때마다 한번 호출한다.
? 프린터 미리보기 모드에서 OnDraw() 함수의 파라미터는 CPreviewDC 객체의 포인터가
(C) 1998 Sang Il Kim

되며 프린트 작업이나 미리보기 작업에 상관없이 OnDraw()와 OnPrint() 함수는 동일한
일을 수행한다.

Visual C++ Programming

5
8

CHAPTER 18
? CView::OnPrint() 함수
? Base class의 OnPrint() 함수는 OnDraw() 를 호출
? 맵핑 모드는 OnPrint()가 호출되기 전에 설정해야 한다.
? 타이틀 페이지, 머리글, 바닥글 등을 인쇄하기 위해 OnPrint() 를 Override 한다.
? OnPrint() 함수의 파리미터
?프린터 디바이스 컨텍스트 포인터
?페이지 디멘션, 현재 페이지 번호, 최대 페이지 수 등을 포함하는
프린트 정보 객체(CPrintInfo)포인터

(C) 1998 Sang Il Kim

? 어플리케이션 프레임워크는 CPrintInfo 구조체에 있는 현재 페이지 수를
사용하여 인쇄될 각 페이지에 대해 단 한 번만 OnPrint() 함수를 호출한다.

Visual C++ Programming

5
8

CHAPTER 18
? CView::OnPrepareDC() 함수
? 뷰 클래스가 CView에서 직접 파생되었다면 OnPrepareDC()를 Override 해야 한다.
? 뷰가 CScrollView에서 파생된 경우에는 이미 Override된 상태가 된다.
? 맵핑 모드는 뷰에 그려지기 전이나 프린터로 인쇄되기 전에 설정된다.
? 두 번째 파라미터는 CPrintInfo 구조체 포인터이다.
? 이 포인터는 인쇄되기 전에 OnPrepareDC() 함수가 호출되었을 때만 유효하다.
? CDC 멤버 함수 IsPrinting()을 호출하여 유효성 여부를 검사한다.
? CView::OnPrepareDC
? 프린트 컨텍스트를 초기화하기 위하여 OnDraw와 OnPrint 앞에 호출된다.
? 프린트하는 페이지는 pInfo 변수의 m_nCurPage 멤버에 의해 주어진다.
? OnPrint가 호출될 때, 디바이스 컨텍스트는 이미 OnPrepareDC를 호출하여
(C) 1998 Sang Il Kim

초기화되었다.
? virtual void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL );
? Parameters
?pDC
프린트 컨텍스트
?pInfo
프린트 작업에 대한 정보를 포함한다.
Visual C++ Programming

5
8

CHAPTER 18
? CView::OnDraw
? 뷰의 이미지가 그려질 필요가 있을 때, 어플리케이션 프레임워크에 의해 호출
? virtual void OnDraw( CDC* pDC ) = 0;
? Parameters
?pDC
디바이스 컨텍스트에 대한 포인터

?pDC
?pInfo

프린터 디바이스 컨텍스트에 대한 포인터
현재 프린트 작업에 대한 정보를 포함하는 CPrintInfo 구조체에
대한 포인터
Visual C++ Programming

(C) 1998 Sang Il Kim

? CView::OnPrint
? 한 페이지의 정보를 프린트하기 위하여 인쇄나 미리 보기 중에 호출된다.
? 프린트하는 페이지는 pInfo 변수의 m_nCurPage 멤버에 의해 주어진다.
? OnPrint()가 호출될 때, 디바이스 컨텍스트는 이미 OnPrepareDC를 호출하여
초기화되었다.
? virtual void OnPrint( CDC* pDC, CPrintInfo* pInfo );
? Parameters

5
8

CHAPTER 18
? 프린트 작업의 시작과 끝
? 프린트 작업이 시작되면 어플리케이션 프레임워크는 CView의 함수
OnPreparePrinting()과 OnBeginPrinting()을 호출한다.

? OnPreparePrinting()
?인쇄 다이얼로그가 출력되기 전에 호출된다.

? OnBeginPrinting()
?인쇄 다이얼로그가 출력된 후 호출된다.

? OnEndPrinting()

함수

작업

OnPreparePrinting
OnBeginPrinting
OnPrepareDC(각 페이지마다)
OnPrint (각 페이지마다)
OnEndPrinting

최소/최대 페이지 수 설정
GDI 객체 생성
맵핑 모드 설정/더 출력할 페이지가 있는지 검사
프린트 지정 결과를 수행하고 나서 OnDraw() 호출
GDI 객체 제거
Visual C++ Programming

(C) 1998 Sang Il Kim

?마지막 페이지가 프린트된 후 프린트 작업을 종료할 때 호출된다.

5
8

CHAPTER 18
? CArray
? template <class TYPE, class ARG_TYPE> class CArray : public CObject
? Parameters
?TYPE 배열에 저장된 객체의 타입을 기술하는 템플릿 파라미터
( CArray에 의해 리턴되는 파라미터이다. )
?ARG_TYPE 배열에 저장된 접근 객체로 사용되는 전달인자 타입을
기술하는 템플릿 파라미터 ( CArray로 전달되는 파라미터 )
? #include <afxtempl.h>
? CArray::RemoveAll
? 배열의 모든 요소를 제거한다.
(C) 1998 Sang Il Kim

? 배열에 할당된 메모리는 FreeExtra()를 호출하거나 그 객체가
파괴될 때까지 해제되지 않는다.
? void RemoveAll( );
Visual C++ Programming

5
8

? CArray::GetUpperBound
? CObArray::GetUpperBound
? GetSize에 의해 리턴되는 요소의 전체 수보다 1이 작은 마지막 요소의
인덱스 배열의 상한 인덱스를 리턴한다.
? int GetUpperBound( ) const;
? Return value
배열의 상한 인덱스(m_bSize - 1)
? The following table shows other member functions that are similar to
CObArray::GetUpperBound.
Class
Member Function
CByteArray
int GetUpperBound( ) const;
CDWordArray int GetUpperBound( ) const;
CPtrArray
int GetUpperBound( ) const;
CStringArray
int GetUpperBound( ) const;
CUIntArray
int GetUpperBound( ) const;
CWordArray
int GetUpperBound( ) const;
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 18

5
9

CHAPTER 18
? CArray::GetSize
? CObArray::GetSize
? 배열의 크기를 리턴한다.
? 배열의 크기는 가장 큰 인덱스보다 1이 더 크다.
? int GetSize( ) const;
? CArray::SetSize
? CObArray::SetSize
? 필요하면 메모리를 할당하거나, 배열의 요소의 수를 설정한다.
? nGrowBy 파라미터는 배열이 증가될 필요가 있으면 생성되는
최소 요소의 수를 기술한다.
throw( CMemoryException );
? Parameters
?nNewSize

새로운 배열 크기(number of elements).

?nGrowBy

생성하는 보조 요소의 수 (minimum number of element)
Visual C++ Programming

(C) 1998 Sang Il Kim

? void SetSize( int nNewSize, int nGrowBy = -1 );

5
9

CHAPTER 18
? Example
? See CObList::CObList for a listing of the CAge class used in all
collection examples.
// example for CObArray::GetUpperBound
CObArray array;
array.Add( new CAge( 21 ) ); // Element 0
array.Add( new CAge( 40 ) ); // Element 1

(C) 1998 Sang Il Kim

ASSERT( array.GetUpperBound() == 1 ); // Largest index

Visual C++ Programming

5
9

CHAPTER 18
? CPrintInfo::SetMaxPage
? void SetMaxPage( UINT nMaxPage );
? Parameters
?nMaxPage Number of the last page of the document.
? CPrintInfo::SetMinPage
? void SetMinPage( UINT nMinPage );
? Parameters
?nMinPage Number of the first page of the document.
? CPrintInfo::GetMaxPage
? UINT GetMaxPage( ) const;
? Return Value
?The number of the last page of the document.
(C) 1998 Sang Il Kim

? CPrintInfo::GetMinPage
? UINT GetMinPage( ) const;
? Return Value
?The number of the first page of the document.
Visual C++ Programming

5
9

? 템플릿 콜렉션 클래스 - CArray 클래스
? 템플릿 클래스는 콜렉션 안의 모든 요소를 직렬화하기 위해 전역 함수
SerializeElements()를 사용한다.
? 디폴트 SerializeElements() 함수는 CArchive 객체에서 각 요소의
bitwise 복사를 수행한다.
? 배열의 요소가 되는 클래스가 포인터 또는 다른 복합체를 포함하면
SerializeElements() 함수를 직접 작성할 필요가 있다.
? 컴파일러는 템플릿 내부에서 SerializeElements() 함수를 대체하여 사용한다.
? 이 작업은 컴파일러가 템플릿 클래스 선언을 인식하기 전에 SerializeElements()
함수 원형을 인식해야 작동한다.
? 이 함수를 사각형 배열로 작성하면 다음과 같다.
void AFXAPI SerializeElements( CArchive& ar, CRect* pNewRects, int nCount)
{
for(int i=0; i < nCount; i++, pNewRects++){
if(ar.IsStoring()){
ar << *pNewRects;
}
else{
ar >> *pNewRects;
}
}
}
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 18

5
9

CHAPTER 18

? rand
? Generates a pseudorandom number.
? int rand( void );
Routine Required Header
Compatibility
rand
<stdlib.h>
ANSI, Win 95, Win NT
? Return Value
?rand returns a pseudorandom number, as described above.
There is no error return.
? Remarks
?The rand function returns a pseudorandom integer in the range
0 to RAND_MAX. Use the srand function to seed the
pseudorandom-number generator before calling rand.
Visual C++ Programming

(C) 1998 Sang Il Kim

? RAND_MAX
? #include <stdlib.h>
? Remarks
?The constant RAND_MAX is the maximum value that can be returned
by the rand function. RAND_MAX is defined as the value 0x7fff.

5
9

? srand
? Set a random starting point.
? void srand( unsigned int seed );
Routine Required Header
Compatibility
srand
<stdlib.h>
ANSI, Win 95, Win NT
? Return Value
?None
? Parameters
?seed Seed for random-number generation.
? Remarks
?The srand function sets the starting point for generating a series of
pseudorandom integers. To reinitialize the generator, use 1 as the
seed argument. Any other value for seed sets the generator to a
random starting point. rand retrieves the pseudorandom numbers that
are generated. Calling rand before any call to srand generates the
same sequence as calling srand with seed passed as 1.
Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 18

5
9

CHAPTER 18
? Example
/* RAND.C: This program seeds the random-number generator
* with the time, then displays 10 random integers. */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

}

/* Display 10 numbers. */
for( i = 0; i < 10;i++ )
printf( " %6d\n", rand() );

6929
8026
21987
30734
20587
6699
22034
25051
7988
10104
Visual C++ Programming

(C) 1998 Sang Il Kim

void main( void )
{
int i;
/* Seed the random-number generator with current time so that
* the numbers will be different every time we run. */
Output
srand( (unsigned)time( NULL ) );

5
9

CHAPTER 18
? CDC::GetTextExtent
? 현재 폰트를 사용하여 기술한 문자열의 높이와 폭(논리 단위)을 계산한다.
? CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
? CSize GetTextExtent( const CString& str ) const;
? Return Value
문자열의 크기(논리단위)를 포함하는 CSize object.
? Parameters
?lpszString 계산되는 크기에 대한 텍스트 문자열에 대한 포인터
?str

lpszString 파라미터에 의해 가리키는 문자열의 길이(바이트)
계산되는 크기에 대한 텍스트 문자열을 포함하는
CString 객체에 대한 참조

(C) 1998 Sang Il Kim

?nCount

Visual C++ Programming

5
9

CHAPTER 19

(C) 1998 Sang Il Kim

분할 윈도우와 다중 뷰

Visual C++ Programming

5
9

CHAPTER 19
? 분할 윈도우와 다중 뷰(Splitter Windows and Multiple Views)
? 윈도우용 워드프로세서를 사용해 보면 하나의 문서 내용이 여러 부분으로
동시에 오픈 되는 것을 보게 되는데, 이 두 개의 윈도우는 모두 일반 뷰를
가질 수도 있고 하나는 페이지 레이아웃 뷰, 다른 하나는 아웃라인 뷰를
가질 수도 있다.
? 어플리케이션 프레임워크는 다중 뷰를 출력하기 위해
분할 윈도우(splitter window)나 다중 MDI 차일드 윈도우를 사용한다.

? CSplitterWnd 객체는 프레임 윈도우(CFrameWnd 나 CMDIChildWnd)의
클라이언트 영역을 차지하는 윈도우가 된다.
? 뷰 윈도우는 분할 윈도우의 패인 영역을 차지한다.
? 분할 윈도우는 명령 전달 체계에 관여하지 않으며, 활성화된 뷰 윈도우는
뷰의 프레임 윈도우에 직접 연결된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 분할 윈도우
? 분할 윈도우는 패인(pane)에 여러 뷰를 갖는 프레임 윈도우의 특별한 형태이다.
? 분할 윈도우는 CSplitterWnd 클래스의 객체로 표현된다.

6
0

CHAPTER 19

? 분할 윈도우를 갖지 않는 MDI 어플리케이션, 다수의 뷰 클래스
?표준 MDI 어플리케이션을 약간 변경하면 다수의 뷰를 사용할 수 있다.
?EX19D
? 분할 차일드 윈도우를 갖는 MDI 어플리케이션
?온라인 설명서에 상세히 설명된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 뷰 옵션들
? 분할 윈도우를 갖는 SDI 어플리케이션, 하나의 뷰 클래스
?각 분할 윈도우 패인은 다른 도큐먼트 부분을 스크롤 되게 할 수 있다.
?EX19A
? 분할 윈도우를 갖는 SDI 어플리케이션, 다수의 뷰 클래스
?프로그래머는 패인의 개수와 뷰의 순서를 결정하고 사용자는 프로그램 실행시에
패인 크기를 변경할 수 있다. ?EX19B
? 분할 윈도우를 갖지 않는 SDI 어플리케이션, 다수의 뷰 클래스
?사용자는 메뉴의 선택에 따라 뷰 클래스를 전환한다. ?EX19C
? 분할 윈도우를 갖지 않는 MDI 어플리케이션, 하나의 뷰 클래스
?사용자가 윈도우 메뉴의 New Window 메뉴 아이템을 선택하면 이미 오픈된
도큐먼트에 대한 새로운 차일드 윈도우를 오픈하게 한다.

6
0

CHAPTER 19
? 동적 분할 윈도우와 정적 분할 윈도우
? 동적 분할 윈도우(Dynamic Splitter Windows)
?사용자가 메뉴 아이템을 선택하거나 스크롤바에 있는 분할 박스를 드래그
하여 윈도우를 분할할 수 있다.
?패인 - 일반적으로 동일한 뷰 클래스를 사용하며, 스크롤바는 뷰 사이에 공유된다.
?하나의 뷰 객체로 시작된다.
?사용자가 프레임을 분할하면 다른 뷰 객체가 생성되고 분할을 해제하면
뷰 객체가 소멸된다.

?패인 - 윈도우가 처음 생성될 때 정의되어 이후에 변경되지 않는다.
?스크롤바를 공유하지 않는다.
?모든 뷰 객체는 프레임 생성시 생성되고 프레임이 소멸될 때 모두 소멸된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 정적 분할 윈도우(Static Splitter Windows)

6
0

CHAPTER 19
? 예제 EX19A - 단일 뷰 클래스 SDI 동적 분할
? 4개의 패인을 갖는 SDI 동적 분할 윈도우를 만든다.
? 4개로 분리된 뷰 객체는 모두 하나의 뷰 클래스에 의해 관리된다.
? AppWizard Step4에서 Advanced… 버튼을 누른 후,
Windows Styles 탭에서 Use split window를 체크한다.
? 기존에 있는 어플리케이션의 CMainFrame 클래스에 분할 기능 코드를 직접
추가할 수 있다.
? 분할을 위한 리소스

아이템을 추가한다.
?ID_WINDOW_SPLIT는 CView::OnSplitCmd()에 맵핑되어 있다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?Use split window가 체크되면 AppWizard는 View 메뉴에 Split 메뉴

6
0

CHAPTER 19
? 예제 EX19A - 단일 뷰 클래스 SDI 동적 분할
? CMainFrame 클래스
?MainFrm.h
protected:
CSplitterWnd m_wndSplitter;
//Overrides
public:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);

?어플리케이션 프레임워크는 메인 프레임 객체가 생성될 때
CFrameWnd::OnCreateClient()를 호출한다.
BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
return m_wndSplitter.Create( this,
2, 2,
// 행과 열의 개수 조정
CSize(10, 10), // 패인의 최소 크기 조정
pContext);
}
Visual C++ Programming

(C) 1998 Sang Il Kim

?MainFrm.cpp

6
0

CHAPTER 19
? CFrameWnd::OnCreateClient
? 적당한 메뉴를 갖는 기본 사용자 윈도우를 생성하는 데 사용된다.
? MDI 사용자 윈도우의 생성을 Customize하기 위하여 중복시킬 수 있다.
? virtual BOOL OnCreateClient( LPCREATESTRUCT lpcs,
CCreateContext* pContext );
? Return Value
성공하면 TRUE, 실패하면 FALSE
?lpcs

CREATESTRUCT 구조체에 대한 포인터

?pContext

CCreateContext 구조체에 대한 포인터
(C) 1998 Sang Il Kim

? Parameters

Visual C++ Programming

6
0

CHAPTER 19
? 예제 EX19B - 이중 뷰 클래스 SDI 정적 분할
? 두 개의 뷰가 출력되는 정적 분할 윈도우를 만든다.
? 이 분할 윈도우는 두 개의 패인으로 초기화된다.
? 정적 분할 어플리케이션을 만드는 방법
?CSplitterWnd::CreateStatic() 을 사용한다.
? 프로그램 수정
?ex19bDoc.cpp, ex19bDoc.h, ex19bView.cpp, ex19bView.h삭제
?아래의 파일을 추가한다.(Project메뉴 - Add To Project - Files)
PoemDoc.cpp, PoemDoc.h, StringView.cpp, StringView.h
LogScrollView.cpp, LogScrollView.h, HexView.cpp, HexView.h
#include “ex19bDoc.h”, #include “ex19bView.h” 제거
#include “PoemDoc.h”, #include “StringView.h” 추가
RUNTIME_CLASS(CEx19bDoc), RUNTIME_CLASS(CEx19bView)의 내용을
RUNTIME_CLASS(CPoemDoc), RUNTIME_CLASS(CStringView)로 바꾼다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?ex19b.cpp 수정

6
0

CHAPTER 19

? Parameters
?row
?col
?pViewClass
?sizeInit
?pContext

분할 윈도우의 행의 수
분할 윈도우의 열의 수
새로운 뷰의 CRuntimeClass
새로운 뷰의 초기 크기
뷰를 생성할 때 사용되는 컨텍스트 생성에 대한 포인터
(usually the pContext passed into the parent frame's
overridden CFrameWnd::OnCreateClient member function
in which the splitter window is being created).

Visual C++ Programming

(C) 1998 Sang Il Kim

? CSplitterWnd::CreateView
? virtual BOOL CreateView( int row, int col, CRuntimeClass* pViewClass,
SIZE sizeInit, CCreateContext* pContext );

6
0

? CSplitterWnd::CreateStatic
? BOOL CreateStatic( CWnd* pParentWnd, int nRows, int nCols,
DWORD dwStyle = WS_CHILD | WS_VISIBLE,
UINT nID = AFX_IDW_PANE_FIRST );
? Parameters
?pParentWnd 분할 윈도우의 부모 프레임 윈도우
?nRows
행의 수. 이 값은 16을 초과할 수 없다.
?nCols
열의 수. 이 값은 16을 초과할 수 없다.
?dwStyle
윈도우의 스타일
?nID
윈도우의 자식 윈도우 ID
The ID can be AFX_IDW_PANE_FIRST unless the
splitter window is nested inside another splitter window.

Visual C++ Programming

(C) 1998 Sang Il Kim

CHAPTER 19

6
0

CHAPTER 19
? 예제 EX19C - 윈도우를 분할하지 않고 뷰 클래스 전환하기
? 분할 윈도우를 생성하지 않고 CStringView 클래스와 CHexView 클래스
사이를 전환하는 SDI 어플리케이션이다.
? 리소스 요구사항
?View 메뉴의 Split 삭제, 다음 두 개의 아이템을 View 메뉴에 추가한다.
명령 ID

String View

ID_VIEW_STRINGVIEW COMMAND : OnViewStringView()
UPDATE_COMMAND_UI :
OnUpdateViewStringView()
ID_VIEW_HEXVIEW
COMMAND : OnViewHexView()
UPDATE_COMMAND_UI :
OnUpdateViewHexView()

Hex View

CMainFrame 클래스의 메시지 함수

Visual C++ Programming

(C) 1998 Sang Il Kim

제목

6
0

CHAPTER 19
? 예제 EX19C - 윈도우를 분할하지 않고 뷰 클래스 전환하기
? HexView.h StringView.h 수정
?HexView.h

StringView.h

public:

public:

CHexView();

CStringView();

DECLARE_DYNCREATE(CHexView)
DECLARE_DYNCREATE(CStringView)
? CFrameWnd::GetActiveView
? 현재 활성화된 뷰를 리턴한다. (있을 경우)
(C) 1998 Sang Il Kim

? CView* GetActiveView( ) const;
? Return Value
?현재 활성화된 뷰에 대한 포인터. 없으면 NULL

Visual C++ Programming

6
1

CHAPTER 19
? CWnd::GetDlgItem
? 지정한 자식 윈도우 포인터나 핸들을 리턴한다.
? 보통 다이얼로그에 있는 컨트롤을 얻는 데 사용된다.
? CWnd* GetDlgItem( int nID ) const;
? void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
? Parameters
?nID
얻을 자식 윈도우 ID 또는 컨트롤의 ID
?phWnd
지정 자식 윈도우 핸들로 채워지는 HWND에 대한 포인터
? Return value
첫번 째 함수는 지정 자식 윈도우에 대한 포인터를 리턴하거나
자식 윈도우가 존재하지 않으면 NULL
? CView::GetDocument
(C) 1998 Sang Il Kim

? 뷰에 대한 관련되는 도큐먼트를 리턴한다.
? CDocument* GetDocument( ) const;
? Return Value
관련 도큐먼트에 대한 CDocument 포인터.
관련 도큐먼트를 갖지 않으면 NULL
Visual C++ Programming

6
11

CHAPTER 19
? CWnd::SetDlgCtrlID
? 자식 윈도우 ID를 특정 ID로 변경한다.
? 자식 윈도우 ID는 많은 함수에서 윈도우를 참조하는데 사용된다.
? int SetDlgCtrlID( int nID );
? Parameters
?nID

새로운 자식 윈도우 ID

? RecalcLayout
? 프레임 윈도우의 크기가 변경되거나 컨트롤바가 표시되거나 숨겨질 때
호출된다.
? virtual void RecalcLayout( BOOL bNotify = TRUE );
? Parameter
?bNotify TRUE - 프레임에 대한 활성화 인플레이스 항목이 레이아웃
변경에 대해 통보받는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 프레임 윈도우의 레이아웃 행위를 customize하기 위하여 중복될 수 있다.

6
1

CHAPTER 19
? CObject::IsKindOf
? 객체가 파생한 인스턴스인가 CObject에서 파생한 클래스인가를 판단한다.
? BOOL IsKindOf( const CRuntimeClass* pClass ) const;
? Parameters
?pClass

기술한 클래스에 대한 CRuntimeClass에 대한 포인터

? CView::OnInitialUpdate
? 뷰가 도큐먼트에 추가된 다음에 뷰가 표시되기 전에 처음 호출되는 함수

(C) 1998 Sang Il Kim

? virtual void OnInitialUpdate( );

Visual C++ Programming

6
1

CHAPTER 19
? 예제 EX19D - 다중 뷰 클래스 MDI 어플리케이션
? 도큐먼트와 뷰 클래스를 이용하여 분할 윈도우가 없는 다중 뷰 클래스 MDI
어플리케이션을 생성한다.
? AppWizard에서 MDI 옵션을 설정, AppWizard Step4에서 Context-Sensitive Help
옵션을 설정

?ex19d.cpp 수정
#include “ex19dDoc.h”, #include “ex19dView.h” 제거
#include “PoemDoc.h”, #include “StringView.h”, #include “HexView.h” 추가
RUNTIME_CLASS(CEx19dDoc), RUNTIME_CLASS(CEx19dView)의 내용을
RUNTIME_CLASS(CPoemDoc), RUNTIME_CLASS(CStringView)로 바꾼다.

? HexView.cpp, PoemDoc.cpp, StringView.cpp 수정
?#include “ex18a.h” 를 #include “ex19d.h”로 바꾼다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 프로그램 수정
?ex19dDoc.cpp, ex19dDoc.h, ex19dView.cpp, ex19dView.h삭제
?아래의 파일을 추가한다.(Project메뉴 - Add To Project - Files)
PoemDoc.cpp, PoemDoc.h, StringView.cpp, StringView.h
LogScrollView.cpp, LogScrollView.h, HexView.cpp, HexView.h

6
1

CHAPTER 19

? CMDIFrameWnd::MDIGetActive
? 현재 활성화 MDI 자식 윈도우를 얻는다.
? CMDIChildWnd* MDIGetActive( BOOL* pbMaximized = NULL ) const;
? Return Value
?활성화 MDI 자식 윈도우에 대한 포인터. 아무 것도 존재하지 않으면 NULL
? Parameters
?pbMaximized BOOL 리턴값에 대한 포인터
윈도우가 최대화 되었으면 TRUE, 그렇지 않으면 FALSE.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CWinApp::ExitInstance
? 윈도우 인스턴스에 대한 청소 작업을 수행한다.
? 인스턴스가 종료하려고 할 때, MFC에 의해 호출된다.
? virtual int ExitInstance( );
? Return Value
?The application's exit code; 0 indicates no errors, and values greater
than 0 indicate an error. This value is used as the return value from
WinMain.

6
1

CHAPTER 19
? OnFilePrintPreview
? 뷰를 사용하여 미리 보기 세션을 시작하기 위하여 호출된다.
? 세션에 대해 새로운 CPrintPreviewState 객체를 생성하고 DoPrintPreview를 호출한
다음에 세션이 완료된 다음에 청소 작업을 한다.
? void CView::OnFilePrintPreview()
{
// In derived classes, implement special window handling here
// Be sure to Unhook Frame Window close if hooked.

if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
RUNTIME_CLASS(CPreviewView), pState))
{
// In derived classes, reverse special window handling
// here for Preview failure case

}

}

TRACE0("Error: DoPrintPreview failed");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState;
// preview failed to initialize, delete State now

Visual C++ Programming

(C) 1998 Sang Il Kim

// must not create this on the frame. Must outlive this function
CPrintPreviewState* pState = new CPrintPreviewState;

6
1

CHAPTER 19
? AfxGetApp
? CWinApp에서 파생한 어플리케이션 객체에 대한 포인터를 얻는다.
? CWinApp* AfxGetApp( );
? Return Value
?CWinApp에서 파생한 객체에 대한 포인터
? AssertValid(), ASSERT_VALID
? 객체를 확인한다.
? 각 CObject에서 파생한 클래스는 특정 확인을 수행하기 위하여 이 함수를
중복시켜야 한다.
? 보통 이 함수는 디버그 모드에 있을 때 파생 클래스에 대해서만 구현된다.
? ASSERT_VALID 매크로는 객체 자체에 대한 포인터 값을 검사한다.
? Debug모드 : ASSERT_VALID는 먼저 CObject에서 파생한 포인터에 의해 가리키는
(C) 1998 Sang Il Kim

메모리를 검사한 다음 AssertValid()를 호출한다.
? Release모드 : ASSERT_VALID는 아무 것도 하지 않는다.
? virtual void AssertValid() const;
? ASSERT_VALID( pObject )
? Parameters
?pObject CObject에서 파생한 클래스의 객체

Visual C++ Programming

6
1

CHAPTER 19
? CDocTemplate::CreateNewFrame
? 보관된 프레임 런타임 클래스로부터 새로운 도큐먼트를 생성하고
템플릿에 추가한다.
? 성공하면, 프레임의 리소스가 메로리에 로드된다.
? 프레임은 도큐먼트와 관련된 뷰를 포함하는 데 사용된다.
? virtual CFrameWnd* CreateNewFrame( CDocument* pDoc,
CFrameWnd* pOther );
? Return Value
성공하면 새로운 CFrameWnd에 대한 포인터. 그렇지 않으면 NULL.
? Parameters
새로운 프레임과 관련되는 도큐먼트에 대한 포인터.
(C) 1998 Sang Il Kim

?pDoc

그렇지 않으면 NULL.
?pOther 새로운 프레임이 근거되는 프레임에 대한 포인터.
템플릿에 관련되는 프레임을 사용하려면 NULL.
Visual C++ Programming

6
1

CHAPTER 19

? VERIFY
? ASSERT와 거의 유사
? Debug와 Release 모두에서 작동한다.
? VERIFY( booleanExpression )
? Parameters
?booleanExpression Specifies an expression (including pointer values)
that evaluates to nonzero or 0.

Visual C++ Programming

(C) 1998 Sang Il Kim

? CDocTemplate::InitialUpdateFrame
? 도큐먼트의 모든 뷰가 OnInitialUpdate 통보 메시지를 받을 수 있게 호출된다.
? CFrameWnd::InitialUpdateFrame 함수에 제어를 전달한다.
? virtual void InitialUpdateFrame( CFrameWnd* pFrame,
CDocument* pDoc, BOOL bMakeVisible = TRUE );
? Parameters
?pFrame
통보 메시지를 받을 도큐먼트를 포함하는 프레임 윈도우
?pDoc
통보 메시지를 받는 도큐먼트. 이 값은 NULL일 수 있다.
?bMakeVisible TRUE - 윈도우를 보이게 한다. FALSE - 보이지 않게 한다.

6
1

CHAPTER 19
? CFrameWnd::GetActiveDocument
? CFrameWnd에 포함되어 있는 현재 활성화된 도큐먼트를 얻는다.
? virtual CDocument* GetActiveDocument( );

(C) 1998 Sang Il Kim

? Return Value
현재 활성화된 도큐먼트에 대한 포인터. 활성화 도큐먼트가 없으면 NULL.

Visual C++ Programming

6
2

CHAPTER 20

(C) 1998 Sang Il Kim

문맥감지형 도움말

Visual C++ Programming

6
2

CHAPTER 20
? 문맥감지형 도움말(Context-Sensitive Help)
? MFC 4.21 어플리케이션 프레임 워크로 생성된 프로그램은 윈도우에 포함되어
있는 WinHelp의 help 엔진을 이용하여 문맥 감지형 도움말 기능을 제공한다.

? 윈도우 WinHelp 프로그램
? RTF(Rich Text Format)
?윈도우 SDK 문서에는 도움말 파일 형식으로 rich text format이라고 하는
ASCII 파일 포맷을 제시한다.
?RTF는 마이크로소프트사에서 표준화한 파일형식. 서로 다른 프로그램,
운영체제에서 형식화된 텍스트를 전송하기 쉽게 하기 위해 만들어진 것이다.

? 도움말 프로젝트 파일 *.Hpj를 만들기 위해서는 도움말의 문서 형식, 즉 서식
있는 문자열 *.Rtf 파일이 필요하다.
? 서식 있는 문자열(*.Rtf) 파일을 만들기 위해서는 RTF를 지원하는
워드프로세서가 필요하다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 도움말 작성

6
2

CHAPTER 20
? 사용자 정의 각주에 따른 기능
기능

#
K
+
@
$
!
*

문서간 점프 지정
검색 기능을 위한 색인(Keyword) 지정
Browse sequence 지정
저자 정의 설명
현재의 제목에 이름 지정
현재의 제목 시작시 실행되는 매크로 지정
특수한 구조 태그

(C) 1998 Sang Il Kim

사용자 정의 각주

Visual C++ Programming

6
2

CHAPTER 20
? 도움말 프로젝트 파일
[OPTIONS]
CONTENTS=HID_CONTENTS
TITLES=SIMPLE Application Help // 도움말 파일의 제목
COMPRESS=true

// 압축 설정 여부, true - 압축 설정

WARNING=2

// 컴파일시 모든 경고 메시지 표시

[FILES]
// 도움말 문서지정 - 도움말의 텍스트를 담은 rtf 파일이
simple.rtf 임을 지정

(C) 1998 Sang Il Kim

simple.rtf

Visual C++ Programming

6
2

CHAPTER 20
? 도움말 파일 만들기
? Microsoft Help Workshop(HCRTF) 유틸리티를 실행
(DevStudio\Vc\bin\Hcrtf.exe)
? 4.02 이전 버전의 HCRTF 유틸리티의 경우 MS-WORD97에 의해 생성된
RTF를 지원하지 않으므로 HwDll.dll을 DevStudio\Vc\bin 디렉토리에
복사해야 한다.
? 도움말 파일 구성
? 도움말 토픽 파일(.rtf)
(C) 1998 Sang Il Kim

? 도움말 프로젝트 파일(.hpj) - Help 컴파일 후 (.hlp) 파일 생성
? 도움말 목차 파일(.cnt)
? 도움말 그래픽/멀티미디어 파일
Visual C++ Programming

6
2

CHAPTER 20
? 어플리케이션 프레임워크와 WinHelp
? 어플리케이션 프레임워크는 WinHelp를 이용하여 문맥 감지형 도움말 기능을
제공한다.(F1, Shift-F1)
1. AppWizard의 Step4에서 Context-Sensitive Help 옵션을 선택한다.
2. AppWizard는 어플리케이션의 Help 메뉴에 Help Topics 메뉴 아이템을
생성하고 도움말 프로젝트 파일 (.hlp), 도움말 컴파일러를 실행할 배치 파일과
하나 이상의 도움말 토픽 파일 (.rtf)을 생성한다.
3. AppWizard는 가속기 F1을 삽입하고 F1키와 Help Topics 메뉴 아이템을
ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
4. 사용자가 F1키를 누르거나 Help Topics 메뉴 아이템을 선택하면
Help context ID가 WinHelp로 전달되어 해당 도움말 토픽이 출력된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

메인 프레임 윈도우 객체의 멤버 함수에서 맵핑 한다.

6
2

CHAPTER 20
? WinHelp 호출하기
? CWinApp 클래스의 멤버 함수 WinHelp()는 어플리케이션 내부로 부터
WinHelp를 활성화 한다.
? WinHelp()의 두 번째 파라미터에 Help context ID를 설정하고 프로그램이
다음과 같은 문장을 포함한다면, Simple Help 파일을 사용할 수 있다.
AfxGetApp()->WinHelp(HID_TOPIC1);
? WinHelp에서 어떤 도움말 파일이 사용되는지 어떻게 알 수 있는가?
?어플리케이션의 이름과 도움말 파일의 이름이 동일하기 때문이다.
도움말 파일 : Simple.hlp

? 프로그램에서 사용되는 상수 HID_TOPIC1(WinHelp()의 첫번째 파라미터)
과 도움말 토픽 파일의 Help context ID를 어떻게 연결시키는가?
?도움말 프로젝트 파일(.hpj)에 MAP 섹션이 포함되어야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

실행 프로그램 : Simple.exe,

6
2

CHAPTER 20
? WinHelp 호출하기
? 어플리케이션의 resource.h 파일에 HID_TOPIC1이 101로 정의되었다면
도움말 프로젝트 파일(Simple.hpj)에 다음과 같은 MAP 섹션이 추가되어야 한다.

?[MAP]
HID_TOPIC1

101

? 프로그램의 resource.h 파일에 #define HID_TOPIC1 101로 정의된
매크로 상수명(HID_TOPIC1)과 프로젝트 파일의 MAP 섹션에 추가한
Help context ID(HID_TOPIC1) 이름이 반드시 일치할 필요는 없다.
(C) 1998 Sang Il Kim

? 지정된 숫자 101(컨텍스트 번호)은 반드시 동일해야 한다.

Visual C++ Programming

6
2

CHAPTER 20
? 검색 문자열 사용하기
? Help context ID보다는 키워드를 기준으로 도움말이 필요한 어플리케이션의
경우 WinHelp()의 두 번째 파라미터에 HELP_KEY 또는 HELP_PARTIALKEY를
사용한다.
?CString string(“find this string”);
AfxGetApp()->WinHelp((DWORD)(LPCSTR)string, HELP_KEY);
? 어플리케이션 메뉴로부터 WinHelp 호출하기
? AfxGetApp() -> WinHelp(0L, HELP_FINDER);
(C) 1998 Sang Il Kim

?색인 탭 다이얼로그가 출력된다.
? AfxGetApp() -> WinHelp(0L, HELP_INDEX);
?목차 테이블 화면이 출력된다.
Visual C++ Programming

6
2

CHAPTER 20
? Help context ID Aliases
? 도움말 프로젝트 파일(.hpj)의 Alias 섹션은 Help context ID와 동일하게
사용할 수 있는 다른 이름을 설정할 때 사용한다.
?[ALIAS]
HID_TOPIC1 = HID_GETTING_STARTED
[MAP]
HID_TOPIC1

101

? 도움말 토픽 파일(.rtf)에서 HID_TOPIC1과 HID_GETTING_STARTED
(C) 1998 Sang Il Kim

모두 사용이 가능하며 숫자 101(컨텍스트 번호)에 연결된다.

Visual C++ Programming

6
3

CHAPTER 20
? Help context 결정하기
? 어플리케이션 프레임워크는 활성화된 프로그램 요소의 ID에 기초하여
Help context ID를 결정한다.
? 프로그램 요소에는 메뉴 아이템, 프레임 윈도우, 다이얼로그, 메시지 박스,
컨트롤바를 포함한다.
? 프로그램 요소의 ID값이 중복될 경우, 어플리케이션 프레임 워크는 ID값
중복 문제를 해결하기 위해 프로그램 요소의 ID에서 유도된 #define 상수를
새롭게 정의한다.

대응되고,
IDR_MAINFRAME(0x20080)은 IDR_MAINFRAME(0x80)에 대응된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? HID_EDIT_CLEAR_ALL(0x1E121)은 ID_EDIT_CLEAR_ALL(0xE121)에

6
3

CHAPTER 20
? Help context 결정하기
프로그램 요소

프로그램 요소 ID Help context ID 기준(16진수)

메뉴 아이템

ID_

HID_

10000

프레임, 다이얼로그

IDR_, IDD_

HIDR_, HIDD_

20000

에러 메시지 박스

IDP_

HIDP_

30000

H...

40000

HIDW_

50000

비 클라이언트 영역
컨트롤 바

DW_

디스패치 에러 메시지

60000

? Help 명령 처리 (예제 - EX20B)
(C) 1998 Sang Il Kim

? F1 키 처리 - OnCommandHelp()
? Shift+F1 키 처리 - OnHelpHitTest()
?모달 다이얼로그와 메시지 박스에서는 작동하지 않는다.
Visual C++ Programming

6
3

CHAPTER 20
? ON_MESSAGE
? ON_MESSAGE( message, memberFxn )
? Parameters
?message
메시지 ID.
?memberFxn
메시지를 맵핑하기 위한 메시지 핸들러 함수의 이름
? CWinApp::WinHelp
? WinHelp 어플리케이션을 실행하고, 기술한 대로 도움말 토픽을 동작시킨다.
? virtual void WinHelp( DWORD dwData, UINT nCmd = HELP_CONTEXT );
? Parameters
?dwData 부가적인 데이터를 기술한다.
이 값은 nCmd 파라미터의 값에 따른다.
?nCmd

표시하고 어떻게 기술한 도움말 토픽을 찾는가의 도움말 타입을
기술한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

도움말 파일에서 어디로 점프하는지를 판단한다.

6
3

CHAPTER 20
? OnCommandHelp (F1 키 처리)
? 프레임 윈도우에 대한 도움말 커맨드 호출을 처리한다.
? afx_msg LRESULT OnCommandHelp( WPARAM wParam, LPARAM lParam );
? Parameters
?wParam
사용되지 않는다.
?lParam
도움말 컨텍스트 ID
? OnHelpHitTest (Shift + F1 키 처리)
? 사용자가 다이얼로그의 특정 위치를 클릭할 때 윈도우 도움말 엔진에 전달되는
도움말 컨텍스트 ID를 판단하는 데 사용된다.
? 기본 구현은 항상 HID_BASE_RESOURCE 상수의 값에 다이얼로그의 도움말 ID를
? afx_msg LRESULT OnHelpHitTest( WPARAM wParam, LPARAM lParam );
? Return value
도움말 인덱스 ID를 리턴한다.
? Parameters
?wParam
?lParam

마우스 위치의 x축 디바이스 좌표
마우스 위치의 y축 디바이스 좌표
Visual C++ Programming

(C) 1998 Sang Il Kim

더하여 리턴한다.

6
3

CHAPTER 20
the same name and path as the application (.EXE -> .HLP).
? This is a public CWinApp member variable named m_pszHelpFilePath that the user
can change if desired.
? Help Context Ranges
?0x00000000 - 0x0000FFFF : user defined
?0x00010000 - 0x0001FFFF : commands (menus/command buttons)
?0x00010000 + ID_
(note: 0x18000-> 0x1FFFF is practical range since command IDs are >=0x8000)
?0x00020000 - 0x0002FFFF : windows and dialogs
?0x00020000 + IDR_
(note: 0x20000-> 0x27FFF is practical range since IDRs are <= 0x7FFF)
?0x00030000 - 0x0003FFFF : error messages (based on error string ID)
?0x00030000 + IDP_
?0x00040000 - 0x0004FFFF : special purpose (non-client areas)
?0x00040000 + HitTest area
?0x00050000 - 0x0005FFFF : controls (those that are not commands)
?0x00040000 + IDW_
? These rules are hard-coded into the default implementation of the Microsoft
Foundation classes. They can be overridden by providing different implementations
of the various Help-related member functions.

Visual C++ Programming

(C) 1998 Sang Il Kim

? Help Files
? The Microsoft Foundation classes assume a single Help file. That Help file must have

6
3

북쪽 바다에서 청어잡이를 하는 어부들의 가장 큰 관심사는, 어떻게 하면
북해로부터 먼 거리에 있는 런던까지 청어를 싱싱하게 살려서 가지고
가는가 하는 것이었다.
모든 어부들이 아무리 잘 해도 배가 런던에 도착해 보면 청어들은
거의 죽어 있는데, 꼭 한 어부만은 싱싱하게 청어를 산채로 런던에
가지고 와서 큰 수입을 얻는 것이었다.
동료 어부들이 이상해서 물었으나 그는 비밀이라며 가르쳐 주지 않다가
압력에 못 이겨 다음과 같이 말했다.
“나는 청어를 잡아서 넣은 통에다 메기를 한 마리씩 넣습니다.”
그러자 모든 어부들이 눈이 둥그래지면서 “그러면 메기가 청어를 잡아
먹지 않소?”라고 묻는 것이었다. 그는 다음과 같이 말했다.
“네, 메기가 청어를 잡아 먹습니다. 그러나 메기는 청어를 두 세 마리
밖에 못 잡아 먹지요. 그러나 그 통에 있는 수백 마리의 청어들은 잡혀
먹히지 않으려고 계속 도망쳐 다니지요. 런던에 올 때까지 모든 청어들은
마치 올챙이들처럼 헤엄치고 도망 다니고 있습니다. 그래서 청어는
여전히 살아서 싱싱합니다. 다 살아 있거든요”
오해하지 마십시오. 편안하고 풍요로운 것만이 행복은 아니라는 것을!
Visual C++ Programming

(C) 1998 Sang Il Kim

청어가 살아있는 비결

6
3

CHAPTER 21

(C) 1998 Sang Il Kim

DLL(동적 링크 라이브러리)

Visual C++ Programming

6
3

CHAPTER 21
? DLLs(Dynamic Link Libraries)
? 클래스 - build_time 모듈러
? DLL - run_time 모듈러
? 내용이 변경될 때마다 다시 만들고 테스트해야 하는 거대한 EXE 프로그램
대신, 작은 DLL 모듈들을 만들면 개별적인 수정과 테스트가 가능하다.
? DLL 의 기초 이론
? DLL은 디스크상의 파일(.dll)로서 글로벌 데이터, 컴파일된 함수들, 프로세스의
일부분이 되는 리소스로 구성되어 있다.

? Win32에서 각 프로세스는 자신만의 DLL의 읽기/쓰기 글로벌 변수의
복사본을 갖는다.
? 프로세스간에 메모리 공유를 원하면 메모리 맵 파일을 사용하거나
데이터 섹션 분리(shared data section)를 선언해야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? DLL은 컴파일되어 기본 주소에 로드되고 다른 DLL과 충돌이 없다면
프로세스에서 동일한 가상 주소에 맵핑된다.
? DLL은 다양한 익스포트된 함수들을 가지고 있고 클라이언트 프로그램은
익스포트된 함수들을 임포트한다.

6
3

CHAPTER 21
? 임포트(Imports)와 익스포트(Exports) 연결 방법
? 익스포트되는 함수들을 symbolic name과 ordinal number라고 하는 정수로
외부에 노출된다.
? 클라이언트 프로그램은 DLL을 로드할 때 symbolic name과 ordinal number
를 인식하고, 이때 동적 링크 프로세스가 클라이언트가 호출한 함수를 DLL
에 있는 함수 테이블의 함수 주소와 연결시킨다.
? DLL코드 - 익스포트된 함수 선언
?__declspec(dllexport) int MyFunction( int n );
? 클라이언트 프로그램 - 임포트를 선언
(C) 1998 Sang Il Kim

?__declspec(dllimport) int MyFunction( int n );
? C++에서 MyFunction()이라는 C 함수를 사용하려면
extern “C” __declspec(dllexport) int MyFunction( int n );
extern “C” __declspec(dllimport) int MyFunction( int n );
Visual C++ Programming

6
3

CHAPTER 21
? 암시적 연결과 명시적 연결(Implicit Linkage vs. Explicit Linkage)
? 암시적 연결(Implicit linking)
?DLL 을 만들 때 링커는 DLL의 익스포트된 함수에 대한 정보(symbolic name, ordinal
number)를 포함하는 임포트 라이브러리 파일(.lib)을 생성한다.

?클라이언트 프로그램을 만들 때 링커에 생성된 임포트 라이브러리 파일(.lib)을 지정
하면(정적 링크) 임포트된 symbolic name, ordinal number는 임포트 라이브러리
파일의 익스포트된 symbolic name, ordinal number에 매칭된다.

?클라이언트 프로그램이 로드될 때 DLL이 로드된다.
?symbolic name, ordinal number에 동적으로 링크된다.
(C) 1998 Sang Il Kim

? 명시적 연결(Explicit linking)
?명시적 연결은 임포트 라이브러리 파일(.lib)을 사용하지 않는다.
?LoadLibrary() 함수 파라미터로 DLL의 경로를 지정하여 호출한다.
Visual C++ Programming

6
4

CHAPTER 21
? 암시적 연결과 명시적 연결(Implicit Linkage vs. Explicit Linkage)
? 클라이언트 프로그램의 명시적 연결 예
?extern “C” __declspec(dllexport) double SquareRoot( double d );
typedef double (SQRTPROC) (double);
HINSTANCE hInstance;
SQRTPROC* pFunction;
VERIFY( hInstance = ::LoadLibrary(“c:\\windows\\system\\mydll.dll”));
VERIFY(pFunction = (SQRTPROC*)::GetProcAddress(hInstance, “SquareRoot”));

(C) 1998 Sang Il Kim

double d = (*pFunction)(81.0); // DLL의 SquareRoot()을 호출

Visual C++ Programming

6
4

CHAPTER 21
? symbolic name과 ordinal number
? MFC 라이브러리의 DLL은 ordinal number 연결을 사용한다.
? ordinal number 연결은 임포트의 긴 symbolic name을 포함할 필요가 없기 때문에
프로그램의 EXE 파일을 작게 할 수 있다.

? ordinal number 연결로 자신만의 DLL을 만들려면 프로젝트의 모듈 정의 파일(.def)에
ordinal number를 지정한다.

? 익스포트된 함수가 C++ 함수라면 모듈 정의 파일(.def)에 decorated이름을 사용해야
한다. (또는 extern “C”로 함수를 선언한다.)
?ReadList@CRecentFileList@@UAEXXZ @ 5458 NONAME
?ReadNameDictFromStream@CPropertySection@@QAEHPAUIStream@@@Z @ 5459 NONAME
?ReadObject@CArchive@@QAEPAVCObject@@PBUCRuntimeClass@@@Z @ 5460 NONAME
?ReadString@CArchive@@QAEHAAVCString@@@Z @ 5461 NONAME
?ReadString@CArchive@@QAEPADPADI@Z @ 5462 NONAME
?ReadString@CInternetFile@@UAEHAAVCString@@@Z @ 5463 NONAME
?ReadString@CInternetFile@@UAEPADPADI@Z @ 5464 NONAME

symbol

ordinal number

Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC 라이브러리의 DEF(DevStudio\VC\mfc\src\intel\MFC42.DEF)

6
4

CHAPTER 21
? 모듈정의 파일 *.def
? 모듈 정의 파일은 프로그래머가 작성한 프로그램(또는 소스)을 컴파일하여
생기는 오브젝트(.OBJ) 파일을 링크(Link) 시키는데 필요한 정보를 포함한다.

NAME
DESCRIPTION
EXETYPE
STUB
CODE
DATA
HEAPSIZE
STACKSIZE

SAMPLE
‘The Windows Program SAMPLE.C’
WINDOWS
‘WINSTUB.EXE’
PRELOAD MOVEABLE DISCARDABLE
PRELOAD MOVEABLE MULTIPLE
1024
5120

◐ 모듈 정의 파일 템플릿(.DEF) ◑
Visual C++ Programming

(C) 1998 Sang Il Kim

? 과거에는 모든 윈도 프로그램이 링커가 사용할 모듈정의 파일을 가져야 했다.
? 32비트 윈도우 프로그램의 경우에는 더 이상 모듈정의 파일을 필요로 하지
않는다.

6
4

CHAPTER 21
? 모듈정의 파일
CODE

PRELOAD MOVEABLE DISCARDABLE

DATA

PRELOAD MOVEABLE MULTIPLE

응용 프로그램의 코드 세그먼트에 대한 해당 메모리 옵션을 명시한다.
코드 세그먼트를 어떤 방식으로 메모리에 로드할 것인가를 결정하기 위해 설정.
HEAPSIZE

1024

STACKSIZE

5120

응용 프로그램에서 사용될 스택(Stack)의 크기를 바이트 단위로 할당.
5BYTE ~ 65536BYTE
Visual C++ Programming

(C) 1998 Sang Il Kim

응용 프로그램에서 사용될 힙(Local Heap)의 크기를 바이트 단위로 할당.
256BYTE ~ 65536BYTE

6
4

CHAPTER 21
? 모듈정의 파일

PRELOAD
LOADONCALL

의미
프로그램이 처음 시작될 때 윈도우가 코드 세그먼트를 즉시
로드하게 한다.
프로그램이 코드 세그먼트나 데이터 세그먼트를 요청하는 순간에
로드하게 한다.

FIXED

코드 세그먼트나 데이터 세그먼트가 기억장소로 로드되면 고정되어
이동할 수 없게 한다.

MOVEABLE

사용되는 코드 세그먼트나 데이터 세그먼트를 이동 가능한 형식으로
설정한다.

MULTIPLE

인스턴스들이 각기 자체적인 데이터 세그먼트를 사용하게 한다.

SINGLE
DISCARDABLE

모든 인스턴스들이 하나의 같은 데이터 세그먼트를 나누어
사용하게 한다.
필요한 경우에는 프로그램이 메모리에서 제거되었다가 다시
로드될 수 있다는 것을 의미한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

옵션

6
4

CHAPTER 21
? DLL Entry Point-DllMain
? 윈도우는 DLL을 로드하면 __DllMainCRTStartup 스타트 코드를 호출한다.
? __DllMainCRTStartup 스타트 코드는 전역 객체를 생성하고, 전역 함수
DllMain()을 호출한다.
? DllMain()은 DLL이 프로세스에 결합하거나 분리될 때, 스레드가 시작되거나
닫힐 때 dwReason 파라미터에 따라 호출된다.
? DLL에서 DllMain() 함수가 없으면 런타임 라이브러리를 사용할 수 없다.

(C) 1998 Sang Il Kim

? EXE의 스타트 코드 - _WinMainCRTStartup

Visual C++ Programming

6
4

CHAPTER 21

(C) 1998 Sang Il Kim

? DLL Entry Point-DllMain
? DllMain() 함수의 키포인트
HINSTANCE g_hInstance;
extern “C” int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
TRACE0(“EX21A.DLL Initializing!\n”);
// 여기에 초기화 설정
}
else if(dwReason == DLL_PROCESS_DETACH)
{
TRACE0(“EX21A.DLL Terminating!\n”);
// 여기에 해제 작업 설정
}
return 1;
}
Visual C++ Programming

6
4

CHAPTER 21
? 인스턴스 핸들 - 리소스 읽기
? 모든 인스턴스 핸들은 특정 프로세스에서만 유효하며, DLL이나 EXE가
시작되는 가상 주소를 나타낸다.
? 프로세스(EXE) 인스턴스 핸들의 주소 - 0x400000
? 로드된 DLL 인스턴스 핸들의 디폴트 주소 - 0x10000000
? FindResource() - 리소스 핸들을 얻는다.
?DLL의 리소스가 필요하면 HINSTANCE 파라미터에 DLL의 인스턴스
핸들을 지정한다.
?EXE의 리소스가 필요하면 EXE의 인스턴스 핸들을 지정하여 해당 리소스
? GetModuleHandle() - 인스턴스 핸들을 얻는다.
?EXE의 인스턴스 핸들이 필요하면 NULL 파라미터를 사용한다.
?DLL의 인스턴스 핸들이 필요하면 DLL 이름을 파라미터로
GetModuleHandle() 함수를 호출한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

핸들을 얻을 수 있다.

6
4

CHAPTER 21
? 클라이언트 프로그램이 DLL을 찾는 방법
? 경로를 지정하지 않는 암시적 연결의 경우 / 명시적 연결의 경우

? MFC DLLs - 확장 DLL과 일반 DLL
? 확장 DLL
?C++ 인터페이스를 지원하므로 클래스 자체를 익스포트 할 수 있다.
?MFC 라이브러리와 동적으로 링크되기 때문에 MFC 어플리케이션에서만 사용할 수 있다.
? 일반 DLL
?C 스타일 함수로만 익스포트 할 수 있다.
?MFC 라이브러리를 정적 연결이나 동적 연결로 선택하여 사용할 수 있다.
? 정적 연결을 선택하면 필요로 하는 MFC 라이브러리 코드가 DLL안에 복사되므로

DLL크기가 커진다.
? 동적 연결을 사용하면 크기는 줄어들지만, 인스톨하려는 컴퓨터에 필요한 MFC DLL이
있어야 한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

1. EXE 파일을 포함하는 디렉토리 / LoadLibrary() 에 지정된 디렉토리
2. 프로세스의 현재 디렉토리
3. 윈도우의 시스템 디렉토리
4. 윈도우 디렉토리
5. Path 환경 변수에 지정된 디렉토리
? DLL 파일을 \windows\system 디렉토리에 복사한 후 프로그램을 실행한다.

6
4

CHAPTER 21
? MFC DLLs - 확장 DLL과 일반 DLL
각주

공유 MFC 라이브러리 동적 연결

MFC 라이브러리 정적 연결

일반 DLL
확장 DLL
클라이언트 EXE

_AFXDLL, _USRDLL
_AFXEXT, _AFXDLL
_AFXDLL

_USRDLL
지원되지 않음
#define 상수 없음

? 공유 MFC DLL과 윈도우 DLL
? Debug 모드에서 프로그램을 만들었다면 그 프로그램은 MFC DLL중 하나 또는 그
이상에 동적으로 연결된다.

핵심 MFC 클래스

mfco42d.dll

ActiveX(OLE) 클래스

mfcd42d.dll

데이터베이스 클래스(ODBC와 DAO)

mfcn42d.dll

Winsock, WinInet 클래스

? Release 모드로 만들 경우 프로그램은 mfc42.dll에 동적으로 연결된다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? mfc42d.dll

6
5

CHAPTER 21
? MFC 확장 DLL - 클래스 익스포트
? DLL에 클래스를 추가하고 해당 클래스 선언에 AFX_EXT_CLASS 매크로를 추가
?class AFX_EXT_CLASS CStudent::public Cobject //p694
? MFC 확장 DLL 리소스 검색 순서
? 확장 DLL, MFC DLL, EXE 순으로 리소스를 검색한다.
? 리소스 검색 순서 변경
HINSTANCE hInstResourceClient = AfxGetResourceHandle();
//사용하는 DLL의 인스턴스 핸들 설정(리소스 검색 순서를 DLL의 리소스를 먼저 찾도록 설정한다.)

AfxSetResourceHandle(::GetModuleHandle(“mydllname.dll”));
CString strRes;
// 클라이언트 프로그램의 인스턴스 핸들로 복원 (리소스 검색 순서를 원래대로 복원한다.)

AfxSetResourceHandle(hInstResourceClient);

? 확장 DLL에서 AfxGetInstanceHandle()은 DLL의 핸들이 아닌 EXE의 핸들을
리턴하므로 사용할 수 없다.
Visual C++ Programming

(C) 1998 Sang Il Kim

strRes.LoadString(IDS_MYSTRING);

6
5

CHAPTER 21
유형

MFC DLL 설명

일반 DLL

정적

확장 DLL

공유

?C 스타일의 함수만 익스포트 한다.
?DLL 크기가 정적에 비해 작지만 DLL배포시 관련된
다른 MFC DLL도 함께 배포해야 한다.
?C++ 클래스 자체를 익스포트 할 수 있다.
?단, MFC 어플리케이션에만 사용가능하다.
(C) 1998 Sang Il Kim

공유

?C 스타일의 함수만 익스포트 한다.
?DLL 크기가 공유에 비해 크지만 DLL배포시 자신의
DLL만 배포하면 된다.

Visual C++ Programming

6
5

CHAPTER 21
? The TRACE Macro
? This topic explains how to use the TRACE macro during development to print or
display debugging messages from a program. TRACE prints a string argument to
your debugger.

? Note With 32-bit MFC, the only way to get debug output is via the debugger.
? The TRACE macro can handle a variable number of arguments, similar to the

way

printf operates. Following are examples of different ways to use TRACEmacros:

? int x = 1;

int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );
TRACE( "The value of x is %d \n", x );

TRACE( "x = %d and y = %x and z = %f\n", x, y, z );
? The TRACE macro is active only in the debug version of the class library. After
a program has been debugged, you can build a release version to deactivate all
TRACE calls in the program.
? Tip When debugging Unicode, the TRACE0, TRACE1, TRACE2, and TRACE3
macros are easier to use because the _T macro is not needed.Visual C++ Programming

(C) 1998 Sang Il Kim

TRACE( "x = %d and y = %d \n", x, y );

6
5

CHAPTER 21
? TRACE
? TRACE( exp )
? Parameters
?exp Specifies a variable number of arguments that are used in exactly the

same way that a variable number of arguments are used in the run-time
function printf.

? TRACE is limited to sending a total of 512 characters at a time. If you call

TRACE with formatting commands, the total string length after the formatting
commands have been expanded cannot be more than 512 characters, including
the terminating NULL. Exceeding this limit causes an ASSERT.

? Example

(C) 1998 Sang Il Kim

// example for TRACE
int i = 1;
char sz[] = "one";
TRACE( "Integer = %d, String = %s\n", i, sz );
// Output: 'Integer = 1, String = one'

Visual C++ Programming

6
5

CHAPTER 21
? TRACE0
? TRACE0( exp )
? Parameters
?exp A format string as used in the run-time function printf.
? Remarks

TRACE0 is similar to TRACE, and is one variant of a group of trace macros that you can use for
debug output. The group includes:

?TRACE0 - Takes a format string (Only) and can be used for simple text messages which are
dumped to afxDump

?TRACE1 - Takes a format string plus one argument (one variable which is dumped to afxDump)
?TRACE2 - Takes a format string plus two arguments (two variables which are dumped to afxDump)
?TRACE3 - Takes a format string plus three arguments (three variables which are dumped to
afxDump)

TRACE, it only dumps data to afxDump if you have compiled a debug version of your application.

? Note This macro is available only in the debug version of MFC.
? Example
// example for TRACE0
TRACE0( "Start Dump of MyClass members:" );

Visual C++ Programming

(C) 1998 Sang Il Kim

? TRACE0 does nothing if you have compiled a release version of your application. As with

6
5

CHAPTER 21
? TRACE1
? TRACE1( exp, param1 )
? Parameters
?exp
A format string as used in the run-time function printf.
?param1 The name of the variable whose value should be dumped.
? Example

? TRACE2
? TRACE2( exp, param1, param2 )
? Parameters
?exp
A format string as used in the run-time function printf.
?param1 The name of the variable whose value should be dumped.
?param2 The name of the variable whose value should be dumped.
? Example
int i = 1;
char sz[] = "one";
TRACE2( "Integer = %d, String = %s\n", i, sz );
// Output: 'Integer = 1, String = one'

Visual C++ Programming

(C) 1998 Sang Il Kim

int i = 1;
TRACE1( "Integer = %d\n", i );
// Output: 'Integer = 1'

6
5

CHAPTER 21
? TRACE3
? TRACE3( exp, param1, param2, param3 )
? Parameters
?exp
A format string as used in the run-time function printf.
?param1
The name of the variable whose value should be dumped.
?param2 The name of the variable whose value should be dumped.
?param3 The name of the variable whose value should be dumped.
? AfxGetResourceHandle
? 리소스를 찾을 때 윈도우에 의해 사용되는 기본 리소스 인스턴스 핸들을 얻는다.

? AfxSetResourceHandle
? 리소스를 찾을 때 윈도우에 의해 사용되는 기본 리소스 인스턴스 핸들을 설정한다.
? void AfxSetResourceHandle( HINSTANCE hInstResource );
? Parameters
?hInstResource
리소스 인스턴스 핸들
Visual C++ Programming

(C) 1998 Sang Il Kim

? HINSTANCE AfxGetResourceHandle( );
? Return Value
?리소스 인스턴스 핸들

6
5

CHAPTER 21
? AfxGetInstanceHandle
? 어플리케이션의 인스턴스 핸들을 얻는다.
? 이것은 항상 항상 MFC의 USRDLL 버전을 사용하는 DLL에서 호출되지
않으면 실행 파일에 대한 것이다.
? HINSTANCE AfxGetInstanceHandle( );

(C) 1998 Sang Il Kim

? Return Value
?어플리케이션의 인스턴스 핸들

Visual C++ Programming

6
5

CHAPTER 21
? MFC 일반 DLL - CWinApp 파생 클래스
? AppWizard가 일반 DLL을 생성할 때 DllMain() 함수는 프레임워크 내부에 있게 된다.
? EXE 프로그램과 같이 CWinApp에서 파생된 클래스로 끝난다.
? 일반적으로 C 함수를 작성하여 _declspec(dllexport) 키워드 또는 프로젝트 모듈 정의
파일(.def)에 엔트리 지정)로 익스포트 한다.

? 확장 DLL의 경우 AppWizard가 생성한 코드 안에 DllMain() 함수가 있게 된다.
? AFX_MANAGE_STATE 매크로 사용하기
? mfc42.dll은 프로세스의 일부로 로드될 때 전역 변수에 데이터를 저장한다.
? 일반 DLL에서 mfc42.dll이 호출되는 경우 전역 변수는 동기화 되지 않는다.
?AFX_MANAGE_STATE(AfxGetStaticModuleState()); // p700
? DLL이 정적으로 MFC 라이브러리에 연결되는 일반 DLL의 경우 이 매크로를 사용할
필요가 없다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 문제 해결 - 일반 DLL의 익스포트된 함수 안에 다음 라인을 삽입한다.

6
5

CHAPTER 21
? AFX_MANAGE_STATE
? AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )
? Parameters
?pModuleState
AFX_MODULE_STATE 구조체에 대한 포인터
? AfxGetStaticModuleState
? AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );
? Return Value
?AFX_MODULE_STATE 구조체에 대한 포인터

자신의 리소스만을 로드하고, 일반 DLL 내부에서 리소스 로딩 함수를 호출하면 DLL
자신의 리소스를 로드한다.

? 클라이언트 프로그램에서 DLL의 리소스를 로드하고자 할 경우

AfxSetResourceHandle() 함수를 사용하여 일시적으로 리소스 검색 순서를 변경하면
된다. // PowerPoint 333쪽
Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC 일반 DLL 리소스 검색 순서
? 일반 DLL에 연결된 클라이언트 프로그램 내부에서 리소스 로딩 함수를 호출하면 EXE

6
6

CHAPTER 21
? 커스텀 컨트롤 DLL (A Custom Control DLL)
? 원래 커스텀 컨트롤은 순수한 C로 작성된 독립된 DLL이었다.
? 일반(regular) DLL은 C++ 인터페이스를 필요로 하지 않고 custom control을 받아
사용하는 개발 시스템에 사용할 수 있기 때문에 최선의 선택이다.

? 커스텀 컨트롤이란 무엇인가?
? 커스텀 컨트롤은 에디트 컨트롤과 같은 표준 컨트롤처럼 작동한다.
? WM_COMMAND 통보 메시지를 부모 윈도우에 보내고 사용자 정의 메시지를 받는다.
? 사용자 정의 메시지인 경우에는 ClassWizard를 사용할 수 없으므로 수작업으로
맵핑해야 한다.

? 커스텀 컨트롤의 윈도우 클래스
? 다이얼로그 리소스 템플릿은 기호식 윈도우 클래스 이름에 의해 커스텀 컨트롤을
? 윈도우 클래스
?클래스 이름
?클래스 윈도우에 보내진 메시지를 받는 WndProc 함수의 포인터
?배경 브러시 같은 여러 가지 속성
? 클라이언트 프로그램은 컨트롤 윈도우 클래스 이름을 사용하여 차일드 윈도우를 만든다.
Visual C++ Programming

(C) 1998 Sang Il Kim

지정한다.

6
6

CHAPTER 21
? 커스텀 컨트롤의 윈도우 클래스(WNDCLASS)
? 창 클래스 데이터 구조는 모니터에 나타난 모든 창을 정의할 때 사용한다.
? 창 클래스는 실제로 객체지향 클래스가 아니다. 단지 창의 유형만을 의미한다.
? 창 클래스는 진정한 OOP 기술인 상속이나 다형성은 지원하지 않고 있다.
typedef struct _WNDCLASS {
UINT style;

// 윈도우 클래스 스타일

WNDPROC lpfnWndProc;

// 메시지를 받아 처리할 윈도우 프로시저의 포인터

int cbClsExtra;

// 여분의 클래스 바이트

int cbWndExtra;

// 여분의 윈도우 바이트

HICON hIcon;

// 아이콘 핸들

HCURSOR hCursor;

// 커서 핸들

HBRUSH hbrBackground;

// 배경 색상(브러시)

LPCTSTR lpszMenuName;

// 리소스 파일에 정의한 메뉴 이름

LPCTSTR lpszClassName;

// 윈도우 클래스 이름

(C) 1998 Sang Il Kim

HANDLE hInstance;// 윈도우 클래스를 정의하는 어플리케이션의 인스턴스 핸들

} WNDCLASS;
Visual C++ Programming

6
6

CHAPTER 21
? 윈도우 WNDCLASS 구조의 멤버들
멤버

목적

창의 클래스 스타일 또는 스타일을 지정한다.
창 프로시저를 가리키는 포인터.
창 클래스 구조의 마지막 부분에 할당할 별도의 바이트를 지정한다.
이 바이트는 윈도우가 ‘0’으로 자동으로 초기화한다.
cbWndExtra
창 인스턴스의 뒤를 이을 별도의 바이트를 지정한다.
이 바이트는 윈도우가 ‘0’으로 자동으로 초기화한다.
hInstance
응용 프로그램의 창 프로시저에서 창 클래스의 응용 프로그램
인스턴스를 식별한다.
hIcon
창 클래스에 대한 아이콘으로 사용할 아이콘 자원의 핸들을 식별한다.
hCursor
창 클래스에 대한 커서로 사용할 커서 자원의 핸들을 식별한다.
hbrBackground 클래스 창의 배경을 그리는데 사용할 물리적 붓 또는 색 값 배경 붓을
가리키는 핸들을 식별한다.
lpszMenuName 클래스에 대해서 사용할 메뉴 자원의 이름을 지정하는
NULL 종료 문자열을 가리키는 포인터.
lpszClassName 창 클래스의 이름을 지정하는 NULL 종료 문자열을 가리키는 포인터.

? DevStudio\Vc\include\winuser.h(1067라인, 배경색상 정의 - 5914라인)
Visual C++ Programming

(C) 1998 Sang Il Kim

style
lpfnWndProc
cbClsExtra

6
6

CHAPTER 21
? 윈도우 WNDCLASS 구조의 멤버들
? 색 값 붓을 창 클래스의 hbrBackground 멤버로 지정한다면, 그 색 값을
붓 핸들(HBRUSH)로 형 변환 해야 한다.
wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
? 색 값이 ‘0’이 되는 것을 방지하기 위해 색 값에 1을 더한다.
? 창 클래스 스타일 ( Window style )
? 창 클래스 스타일은 해당 클래스에 속해 있는 모든 창들에 대해서 공통적인

(C) 1998 Sang Il Kim

행동 양식을 정의한다.

Visual C++ Programming

6
6

CHAPTER 21
? MFC 라이브러리와 WinProc 함수
? 윈도우는 컨트롤에 보내진 각 메시지에 대해 컨트롤의 WinProc() 함수를
호출한다.

? 컨트롤에 대한 C++ 클래스는 ClassWizard를 사용하여 CWnd에서 파생되는
새로운 클래스(CRygWnd)를 작성한다.
LONG MyControlWndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
if(this is the first message for this window){
CWnd* pWnd = new CMyControlWindowClass();
attach pWnd to hWnd
}
return AfxCallWndProc(pWnd, hWnd, message, wParam, lParam);
}

? MFC 전역 함수 AfxCallWndProc()는 프레임워크에서 전달받은 메시지를
CMyControlWindowClass에 맵핑된 멤버 함수에 전달한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? 컨트롤 WinProc() 함수

6
6

CHAPTER 21
? 커스텀 컨트롤 통보 메시지(Custom Control Notification Messages)
? 컨트롤은 특정 WM_COMMAND 통보 메시지로 부모 윈도우와 통신하며, 부가적인
정보를 갖는 파라미터가 전달된다.
파라미터

사용

(HIWORD)wParam 통보 코드
(LOWORD)wParam 차일드 윈도우 ID
lParam
차일드 윈도우 핸들

컨트롤에서 보낸 코드를 사용하여 세부 처리를 한다.
? 예, 코드 77이 컨트롤에 위치해 있는 동안 사용자가 문자를 입력한 것으로 지정하면
컨트롤은 다음과 같이 통보 메시지를 보낸다.
GetParent()->SendMessage(WM_COMMAND,
GetDlgCtrlID() | ID_NOTIFYCODE << 16, (LONG) GetSafeHWnd());
? 클라이언트 프로그램 - MFC ON_CONTROL로 메시지를 맵한다.
ON_CONTROL(ID_NOTIFYCODE, IDC_MYCONTROL, OnClickedControl)
? 핸들러 함수를 선언한다.
afx_msg void OnClickedMyControl();
Visual C++ Programming

(C) 1998 Sang Il Kim

? 통보 코드는 임의적이고 컨트롤 의존적이며, 통보 코드를 받는 부모 윈도우는 해당

6
6

CHAPTER 21
? 컨트롤에 보내진 사용자 정의 메시지
? 사용자 정의 메시지는 클라이언트 프로그램이 컨트롤과 통신하는 수단이다.
? 메시지가 32비트 값을 반환하므로 PostMessage() 함수보다 SendMessage() 함수를
사용하면 클라이언트 프로그램은 컨트롤로부터 부가 정보를 얻을 수 있다.

? 예제 EX21D - 커스텀 컨트롤(Custom Control)
? off, red, yellow, green 상태를 나타내는 신호등 컨트롤을 구현한 MFC 일반 DLL
? 좌측 마우스 버튼을 클릭하면 DLL은 클릭된 통보 메시지를 부모 윈도우에 보내고,
부모 윈도우에서 보내는 사용자 정의 메시지 RYG_SETSTATE, RYG_GETSTATE에
대응하는 메시지 핸들러가 있고, 색깔을 나타내는 정수 m_nState 데이터 멤버가 있다.

(C) 1998 Sang Il Kim

? ON_CONTROL
? ON_CONTROL( wNotifyCode, id, memberFxn )
? Parameters
?wNotifyCode
컨트롤의 통지 코드
?id
command ID.
?memberFxn
커맨드를 맵핑하는 메시지 핸들러 함수의 이름
Visual C++ Programming

6
6

Seven Deadly Sins (일곱 가지 치명적인 죄악들)
1) Pleasure without conscience (양심 없는 쾌락)
2) Politics without principle (원칙 없는 정치)
3) Commerce without ethics (윤리 없는 상거래)
4) Knowledge without character (성품 없는 지식)
5) Science without humanity (인간성 없는 과학)
6) Wealth without work (노동 없는 부)
7) Worship without sacrifice (희생 없는 종교적 숭배)

(C) 1998 Sang Il Kim

- 간디 -

Visual C++ Programming

6
6

CHAPTER 23

(C) 1998 Sang Il Kim

Component Object Model

Visual C++ Programming

6
6

CHAPTER 23
? 컴포넌트 객체 모델 ( Component Object Model )
? Component Object Model(COM)은 새로운 ActiveX 기술의 토대이며,
현재는 윈도우의 핵심 부분으로 통합되었다.
? ActiveX 기술의 배경
? OLE - Object Linking and Embedding을 의미하며, drag and drop을 포함한
ActiveX 기술의 일부분이다.
? IIS - Microsoft Internet Information Server
? “server” - 데이터베이스 서버, 인터넷 서버
? “Component” - OLE 서버의 새로운 이름
? COM이 풀어야 할 문제
? 윈도우 프로그램 모듈을 위한 표준 방법이 없어 서로간에 통신이 이루어지지 않는다.
? 윈도우 API - 350개 이상의 분리된 함수로 존재하여 프로그래밍 “표면 영역”이
너무 크다.
? VBX - 32비트에서는 작동하지 않는다.
? DDE - 어플리케이션, 토픽, 아이템에 관한 시스템이 복잡하다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? COM의 본질

6
7

CHAPTER 23
? COM의 본질
? 윈도우에 단일화되고 확장 가능한 객체지향 통신 프로토콜을 제공한다.
?Win32 클라이언트 EXE가 Win32 DLL을 로드하고 호출하는데 있어 언어 독립적인
표준 방법을 제공한다.
?동일한 컴퓨터 내에서 EXE가 다른 EXE를 컨트롤하는 일반적인 목적을 가진 방식을
제공한다. (DDE 대체)
?VBX 컨트롤을 대체할 ActiveX Control을 제공한다.
?어플리케이션 프로그램이 운영체제와 상호 작용하는 새롭고 강력한 방법을 제공한다.
?마이크로소프트의 OLE DB 데이터베이스 인터페이스와 같은 새로운 프로토콜을
수용할 수 있는 확장성을 제공한다.
?새롭게 배포된 분산 COM(DCOM)은 EXE가 다른 컴퓨터(컴퓨터가 서로 다른
? COM - COM은 하나의 소프트웨어 모듈을 다른 것과 연결하고 나서
픽쳐(데이터의 형식을 지정하는)를 드롭하는 프로토콜이다.
? 연결이 설정된 후 두 모듈은 인터페이스라고 불리는 메커니즘을 통해 통신할 수 있다.
? 인터페이스는 정적 또는 동적으로 링크된 엔트리 포인터나 통신 프로세스가 시작되는
일반 목적용 COM함수와 다른 하드-코드된 주소를 필요로 하지 않는다.
Visual C++ Programming

(C) 1998 Sang Il Kim

microprocessor-chip을 사용해도)에 있는 EXE와 통신할 수 있는 방법을 제공한다.

6
7

CHAPTER 28

(C) 1998 Sang Il Kim

마이크로소프트 ODBC를
통한 데이터베이스 관리

Visual C++ Programming

6
7

CHAPTER 28
? ODBC(Open DataBase Connectivity)
? ODBC는 SQL(Structured Query Language)의 표준화된 버전에 기초를 둔다.
? ODBC와 SQL을 사용하면, 다른 데이터베이스 제품과는 상관없는(독립적인)
데이터베이스 액세스 코드를 작성할 수 있다.
? 데이터베이스 관리의 이점
? 표준 파일 포맷 사용 - MDB포맷을 사용하면, 데이터베이스의 모든 테이블과 인덱스를
하나의 디스크 파일에 포함시킬 수 있다.
? 인덱스 파일 액세스 - 키를 사용하여 레코드를 빠르게 액세스하려면, 인덱스 파일
액세스가 필요하다.
? 데이터 무결성 보호 - 전문적인 DBMS 제품은 데이터를 보호하는 프로시저를
가지고 있다.(예, 트랜잭션 처리)
처리되지 못하면 트랜잭션은 rollback되고, 따라서 데이터베이스는 트랜잭션 이전의
원래 상태로 돌아가게 되므로 서로 관련되는 데이터들의 무결성이 보장된다.
? 다중 사용자 액세스 컨트롤
?DBMS는 대부분 레코드 로킹을 제공하여 동시 사용자들 사이에서의 엉킴을 막아준다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?트랜잭션에는 일련의 연관성 있는 변화들이 포함되는데, 이 때 트랜잭션 전체가

6
7

CHAPTER 28
? SQL(구조적 질의어)
? 자체의 문법을 가진 표준 데이터베이스 액세스 언어이다.
? 데이터베이스는 행(row:레코드)과 열(column:필드)로 이루어진 테이블의 콜렉션이다.
? ODBC 표준
? SQL 문법 규칙과, SQL 데이터베이스에 대한 C언어 프로그래밍 인터페이스를 정의.
? Visual C++과 ODBC SDK에는, DBF 파일, 액세스 MDB 데이터베이스,
액셀 XLS파일, 폭스프로 파일, ASCII 텍스트 파일, SQL서버 데이터베이스를 위한
32비트 드라이버가 포함되어 있다.
? C++ 프로그램을 사용하여 SQL 서버 데이터베이스를 갱신한 다음, 규격품인
ODBC 호환 리포트 라이터를 사용하여 포맷을 만들고 데이터를 프린트할 수 있다.
? ODBC를 이용하면 프로그래머들은 데이터베이스 제품에 상관없이 하나의 API만을
배우면 된다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? ODBC는 실제 데이터베이스 관리 및 처리로부터 사용자 인터페이스를 분리한다.

6
7

CHAPTER 28
? ODBC 아키텍처
? DLL에 기초한 ODBC 고유의 아키텍처는 시스템 전체를 모듈러로 만드는 것.
? ODBC32.DLL은 API를 정의한다.
? ODBC32.DLL은 프로그램이 실행되는 동안 특정 데이터베이스가 지정한
DLL(드라이버)을 로드한다.
? ODBC32.DLL은 윈도우 레지스트리의 도움을 받아, 데이터베이스에 지정된 DLL이
이용가능한지 추적하여 단일 프로그램이 다수의 DBMS 데이터를 동시에 접근하도록
한다.
? ODBC SDK 프로그래밍

특정 드라이버와
데이터 소스 조합을 참조한다.

(C) 1998 Sang Il Kim

? ODBC 요소 3가지 - 환경(environment), 커넥션(connection), 문장(statement)
? ODBC32.DLL에는 레지스트리에서 정의된 커넥션을 나열한 내장 윈도우 다이얼로그를
가지고 있다.
? 일단 커넥션이 있으면, 실행할 SQL문장이 필요하다.
SELECT FNAME, LNAME, CITY FROM AUTHORS
WHERE STATE = ‘UT’ORDER BY LNAME

Visual C++ Programming

6
7

CHAPTER 28
? ODBC SDK 프로그래밍
? 다이너셋(Dynaset) - 동적 행집합
?데이터베이스가 변경될 때마다 행집합을 갱신한다.
? 스냅샷(Snapshots) - 정적 행집합
?레코드를 가리키는 포인터의 리스트를 메모리 내에 구축하게 된다.
?이들 레코드들은 일단 스크롤하면 변경되지 않으므로, 다중 사용자 상황에서는
정기적으로 데이터베이스를 다시 질의하여 스냅샷을 재구축해야 한다.
? MFC ODBC 클래스 - CRecordset(행집합)과 CDatabase

? 일반적으로 CRecordset에서 클래스를 파생하여 데이터베이스 테이블의
열(column)들을 매칭시킨다.
? CRecordset::Open() - 파라미터 값과 데이터 멤버들을 사용하여 CDatabase
객체를 생성하고 오픈한다.
? CRecordset 클래스는 기본 ODBC 행집합 코드와 더불어 데이터베이스
Dynaset과 Snapshots을 관리한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CRecordset의 객체들은 스크롤되는 행집합을 표현한다.
? CDatabase의 객체들은 데이터 소스와의 ODBC연결을 표현한다.

6
7

CHAPTER 28
? CRecordset 멤버 함수
설명

Open()
AddNew()

레코드 셋을 연다.
새로운 레코드를 테이블에 추가할 준비를 한다.

Update()
Delete()

데이터 소스에 새로운 데이터나 편집된 데이터를 저장함으로써
AddNew()와 Edit()를 완료한다.
레코드 셋 에서 현재 레코드를 삭제한다.

Edit()

현재 레코드를 편집할 준비를 한다.

IsBOF()

현재 레코드가 첫번째 레코드 앞에 위치하고 있는지를 알아낸다.

IsEOF()

현재 레코드가 마지막 레코드 뒤에 위치하고 있는지를 알아낸다.

MoveNext()

현재 레코드를 다음 레코드에 설정한다.

MoveFirst()

현재 레코드를 처음 레코드에 설정한다.

MoveLast()

현재 레코드를 마지막 레코드에 설정한다.

MovePrev()

현재 레코드를 이전 레코드에 설정한다.

(C) 1998 Sang Il Kim

함수

Visual C++ Programming

6
7

CHAPTER 28
? CRecordset 멤버 함수
함수

설명

GetDefaultConnect()

레코드 셋의 기초가 되는 데이터 소스의 디폴트 연결
문자열을 얻는다.
디폴트 SQL을 얻는다.

GetDefaultSQL()
DoFieldExchange()

레코드 셋 데이터 필드와 데이터 소스간에 대응되는
레코드끼리 데이터를 교환한다.

GetStatus()

레코드 셋의 현재 레코드 인덱스와 최종 개수 상태를 얻는다.

GetRecordCount()

레코드 셋 안에 있는 레코드의 개수를 얻는다.

GetODBCFieldCount() 레코드 셋 객체 내의 필드 수를 얻는다.
레코드 셋 객체 내의 필드에 대한 정보를 얻는다.
(C) 1998 Sang Il Kim

GetODBCFieldInfo()

Visual C++ Programming

6
7

CHAPTER 28
? 레코드 셋 내의 행(row) 개수 count
? 레코드 셋에 포함된 레코드 수를 알고 싶은 경우 MoveNext()를 호출하여
전체 테이블을 루핑해야만 한다.
? 프로그램에서 레코드를 추가/삭제하거나, 또는 다른 사용자가 레코드를
추가/삭제하더라도 레코드 개수는 조정되지 않는다.
? high-water mark

(C) 1998 Sang Il Kim

현재까지 추출되어진 레코드의 총 개수

Visual C++ Programming

6
7

CHAPTER 28
? ODBC 예외 처리하기
? MFC ODBC 호출들은 대부분 에러 코드를 리턴하지 않고, 대신 에러를 설명하는
문자열을 포함한 ODBCException 객체를 제시한다.
? CRecordset::Delete() 를 호출했을 때, MFC 기초 클래스에서 제시된 ODBC 에러
메시지 박스가 출력된다.
예) 서로 릴레이션이 설정되어 있는 A와 B 두 개의 테이블이 있을 때 :
A테이블에서 레코드를 삭제하려 하면, 액세스는 참조 무결성에 의해
B테이블의 행이 의존하고 있는 행을 삭제하지 못하도록 막는다.
? 프로그램은 에러를 삭제하여 현재 레코드에 의존하는 CRecordset::MoveNext()와
같은 함수들을 호출하지 않도록 해야 한다.
? 참조 무결성(Referential Integrity)
검증하여 모순이 없을 때만 작업을 허락함으로써 데이터 베이스의 신뢰성을 높이는
수단.
?일단 상관되는 테이블간에 릴레이션을 설정할 때 참조 무결성을 강화해 놓으면
이러한 모순이 발생치 않도록 데이터베이스 엔진이 알아서 관리해 준다.
Visual C++ Programming

(C) 1998 Sang Il Kim

?레코드의 추가, 변경, 삭제 작업시 해당 테이블과 릴레이션이 맺어 있는 테이블을

6
8

CHAPTER 28
? ODBC 예외 처리하기
? try {
m_pSet->Delete();
}
catch(CDBException* e) {
AfxMessageBox(e->m_strError);
e->Delete();
m_pSet->MoveFirst();
UpdateData(FALSE);
(C) 1998 Sang Il Kim

return;
}
m_pSet->MoveNext();
Visual C++ Programming

6
8

MessageBeep
? MessageBeep()
? BOOL MessageBeep( UINT uType );
? Parameters
?uType Specifies the sound type, as identified by an entry in the [sounds]
section of the registry.

매개변수

설명

0xFFFFFFFF
MB_ICONASTERISK
MB_ICONEXCLAMATION
MB_ICONHAND
MB_ICONQUESTION
MB_OK

PC 스피커를 이용하는 표준 경고음
SystemAsterisk
SystemExclamation
SystemHand
SystemQuestion
SystemDefault

? MessageBeep()는 사용자의 제어판에 있는 소리 애플릿에서
WindowsAsterisk 소리와 결합된 웨이브 파일을 재생한다.
? 웨이브 파일 소리는 MB_ICONASTERISK 매개 변수에 의해 결정된다.
? 사용자의 PC에서 소리를 이용할 수 없다면, MessageBeep()는
PC 스피커에서만 나타난다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? MessageBeep() 함수에서 이용할 수 있는 매개 변수 목록

6
8

일반 진단 매크로
? MFC가 제공하는 범용 진단 매크로
매크로

사용 방법

하나의 불 값 매개변수를 계산하여 결과가 FALSE이면, 진단 메시지를
출력하고(MFC의 디버그 버전에서), 프로그램을 중단시키게 된다.
가리키는 객체가 특정 클래스의 객체(또는 특정 클래스로 부터 파생된 객체)
ASSERT_KINDOF
이어야 함을 나타내는 역할을 한다.
자신의 AssertValid() 메소드를 호출하여 CObject 객체(또는 이로부터파생된
ASSERT_VALID
객체)의 내부 상태의 유효성을 조사한다.
메모리가 깨지는 현상을 디버깅하는 것을 도와 준다. 힙 영역을 할당하기 위해
DEBUG_NEW new 연산자를 사용할 수 있는 곳이면, 어느 곳에서나 사용할 수 있다. 모든 객체
를 할당할 때 파일 이름과 줄 번호를 제공하는 역할을 한다.(디버그 모드일때)
MFC의 디버그 버전에서 C 실행 시간 라이브러리 printf() 함수와 같이
TRACE
포맷된 디버깅 출력을 제공하는 역할을 한다.

TRACE0

매개변수가 없는 포맷 문자열만 받아들인다.

TRACE1

매개변수가 하나만 있는 포맷 문자열만 받아들인다.

TRACE2

두 개의 매개변수만 갖는 포맷 문자열만 받아들인다.

TRACE3

세 개의 매개변수만 갖는 포맷 문자열만 받아들인다.

VERIFY

ASSERT와 유사하지만 MFC의 디버그 버전은 물론 발표 버전에서도 동작한다.

? MFC42.DLL : Release 버전, MFC42D.DLL : Debug 버전
Visual C++ Programming

(C) 1998 Sang Il Kim

ASSERT

6
8

일반 진단 변수와 함수
함수

설명

AfxCheckMemory()

현재 할당된 모든 메모리 무결성을 조사한다.

afxDump

디버거로부터 호출되었을 때 기본 객체 덤프 기능을 제공하고 있다.
CDumpContext 객체를 통해서 디버거 출력창(또는 디버그 터미널)
에 디버깅 데이터를 보낸다.

AfxIsMemoryBlock()

메모리 블록이 올바로 할당되는지를 확인하기 위해 메모리 추적
기능을 활성화하거나 비활성 상태로 만드는 역할을 한다.
new 연산자의 디버그 버전을 사용할 때 메모리 블록이 올바로
할당되었는지의 여부를 검증한다.

AfxIsValidAddress()

메모리 주소가 응용 프로그램의 메모리 공간 내에 존재하는지 조사한다.

AfxIsValidString()

문자열에 대한 포인터가 조사한다.

afxMemDF
AfxSetAllocHook()

디버깅 메모리 할당자의 행동을 제어하여 할당 상태의 진단을
사용자가 조정할 수 있게 한다.
메모리를 할당하기 전에 특정 함수를 호출할 수 있게 하는
후크를 설정한다.

afxTraceEnabled

TRACE 매크로가 활성화되어 있는지의 여부를 결정한다.

afxTraceFlags

MFC의 내장된 보고 기능을 활성화하는 역할을 한다.

AfxEnableMemoryTracking()

Visual C++ Programming

(C) 1998 Sang Il Kim

? MFC의 일반 진단 변수와 함수

6
8

일반 진단 변수와 함수
? MFC 객체 진단 함수
? AfxDoForAllClasses()
매크로 DECLARE_DYNAMIC, DECLARE_DYNCREATE,
DECLARE_SERIAL로 실행 시간 유형 조사를 지원하는 모든 CObject로
부터 파생된 클래스들에 대해 특정 반복 함수를 호출한다.
? AfxDoForAllObjects()
new 연산자를 사용하여 할당된 모든 CObject로 부터 파생된 객체들에

(C) 1998 Sang Il Kim

대해 특정 함수를 호출한다.

Visual C++ Programming

6
8

문자열
? CString 객체를 문자 배열로 취급할 때 사용하는 String 메소드와 연산자
Empty()

문자 배열의 길이가 0이 되도록 CString 을 비운다.

GetAt()

배열에서 특정 위치에 존재하는 문자를 얻는다.

GetLength()

CString 문자열 내의 문자들의 수를 구한다.

IsEmpty()

CString 객체가 아무 문자라도 갖고 있는지 조사한다.

SetAt()

문자열 내에서 특정 위치에 있는 문자를 바꾼다.
(바꿀 문자는 \0이 될 수 없다.)

연산자 [ ]

배열 내의 특정 위치에 있는 문자를 얻는다.
GetAt() 메소드 대신에 사용한다.

연산자 LPCTSTR

CString 객체에 저장되어 있는 문자들에 대한 포인터를
반환한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

메소드 또는 연산자 설명

6
8

문자열
? CString 할당, 접합, 비교, 추출
연산자

설명

연산자 =

새 값을 CString 객체에 할당한다.

연산자 +

두 개의 문자열을 더하여 새 문자열을 반환한다.

연산자 +=

새 문자열을 기존의 문자열의 끝에 붙인다.

? CString str1 = “This is an easy way to perform”;
CString str2 = “string concatenation”;
CString str3 = str1 + “ ” + str2;
(C) 1998 Sang Il Kim

AfxMessageBox(str3, MB_OK | MB_ICONINFORMATION);

Visual C++ Programming

6
8

문자열
? CString 비교 메소드와 연산자
Compare()

두 문자열을 비교한다. (대소문자 구별)

CompareNoCase()

두 문자열을 비교한다. (대소문자 구별하지 않음)

연산자 ==

두 문자열이 같은지 조사한다. (대소문자 구별)

연산자 !=

두 문자열이 서로 다른지 조사한다. (대소문자 구별)

연산자 <

한 문자열이 다른 문자열보다 작은지 조사한다. (대소문자 구별)

연산자 >

한 문자열이 다른 문자열보다 큰지 조사한다. (대소문자 구별)

연산자 <=

한 문자열이 다른 문자열보다 작거나 같은지 조사한다. (대소문자 구별)

연산자 >=

한 문자열이 다른 문자열보다 크거나 같은지 조사한다. (대소문자 구별)

? A string < a string
A string > A String
A string = A string
Visual C++ Programming

(C) 1998 Sang Il Kim

메소드 또는 연산자 설명

6
8

문자열
? CString 추출 메소드
메소드

설명

Left()

문자열의 문자 배열 왼쪽 부분에서 지정한 수의 문자들을 추출한다.

Mid()

문자열의 문자 배열 중간 부분에서 지정한 수의 문자들을 추출한다.

Right()

문자열의 문자 배열 오른쪽 부분에서 지정한 수의 문자들을 추출한다.

SpanExcluding() 지정한 문자 배열에 없는 문자들로만 이루어진 하위 문자열을 추출한다.
SpanIncluding()

지정한 문자 배열에 있는 문자들로만 이루어진 하위 문자열을 추출한다.

? 하위 문자열을 추출하고 연결
CString str2 = str1.Left(8) + str1.Right(18);
AfxMessageBox(str2, MB_OK | MB_ICONINFORMATION);

Visual C++ Programming

(C) 1998 Sang Il Kim

CString str1 = “This is the way to perform string extraction!”;

6
8

문자열
? CString 서식 지정과 변환 메소드
메소드

설명

Format()

C 실행시간 라이브러리 함수 sprintf()가 하는 것과 같은 방법으로
문자열의 서식을 지정한다.

FormatMessage() 메시지 문자열의 서식을 지정한다.(Format()과 유사)
MakeLower()

문자열 내의 모든 문자를 소문자로 변환한다.

MakeUpper()

문자열 내의 모든 문자를 대문자로 변환한다.

MakeReverse()

문자열 내의 문자들을 뒤집는다.

TrimLeft()

문자열의 왼쪽에서 여백 문자들을 제거한다.

TrimRight()

문자열의 오른쪽에서 여백 문자들을 제거한다.

Find()
ReverseFind()
FindOneOf()

지정한 하위 문자열과 일치하는 문자열 내의 첫번째 문자의 0을
기반으로 한 인덱스를 반환한다.
지정한 하위 문자열과 일치하는 문자열 내의 마지막 문자의 0을
기반으로 한 인덱스를 반환한다.
지정한 하위 문자열 내에 포함된 임의의 글자와 일치하는 문자열 내의
첫번째 문자의 0을 기반으로 한 인덱스를 반환한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CString 검색 메소드

6
9

문자열
? CString 버퍼 액세스 메소드
설명

FreeExtra()

CString 문자열에 이전에 할당되었던 별도의 메모리를 모두 비운다.

GetBuffer()

CString 내의 문자들에 대한 포인터를 얻는다.

GetBufferSetLength()

CString 내의 문자들에 대한 포인터를 얻는다.
그러나 문자열을 지정된 길이만큼 자른다.

LockBuffer()

문자열의 복사본을 만들고, 이를 버퍼 내에 잠금으로써 CString 참조
계수기를 비활성 상태로 만들고, 버퍼 내의 문자열을 보호한다.

ReleaseBuffer()

GetBuffer() 메소드가 반환한 버퍼에 있는 문자열을 반환한다.

UnlockBuffer()

LockBuffer() 메소드를 호출하여 얻은 버퍼의 잠금을 풀고
참조 계수기를 활성화한다.
(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

6
9

문자열
? 문자열 비교
? int strcmp( const char *string1, const char *string2 );
? int wcscmp( const wchar_t *string1, const wchar_t *string2 );
?wide-character, 헤더파일 string.h, wchar.h
? int _mbscmp(const unsigned char *string1, const unsigned char *string2 );
?multibyte-character, 헤더파일 mbstring.h
? int strncmp( const char *string1, const char *string2, size_t count );
? int wcsncmp( const wchar_t *string1, const wchar_t *string2, size_t count );
? int _mbsncmp( const unsigned char *string1,
const unsigned char *string2, size_t count );
? int _strnicmp( const char *string1, const char *string2, size_t count );
? int _wcsnicmp( const wchar_t *string1, const wchar_t *string2, size_t count );
? int _mbsnicmp( const unsigned char *string1,
const unsigned char *string2, size_t count );
? Parameters
?string1, string2 Strings to compare
?count
Number of characters to compare
Visual C++ Programming

(C) 1998 Sang Il Kim

?헤더파일 string.h

6
9

문자열
? 문자열 복사
? char *strcpy( char *strDest, const char *strSource );
?헤더파일 string.h
? wchar_t *wcscpy( wchar_t *strDest, const wchar_t *strSource );
?wide-character, 헤더파일 string.h, wchar.h
? unsigned char *_mbscpy( unsigned char *strDest,
const unsigned char *strSource );
?multibyte-character, 헤더파일 mbstring.h
? char *strncpy( char *strDest, const char *strSource, size_t count );
? wchar_t *wcsncpy( wchar_t *strDest, const wchar_t *strSource, size_t count );
? unsigned char *_mbsncpy( unsigned char *strDest,
const unsigned char *strSource, size_t count );

?strDest
?strSource
?count

(C) 1998 Sang Il Kim

? Parameters
Destination string
Source string
Number of characters to be copied
Visual C++ Programming

6
9

문자열
? 문자열 연결
? char *strcat( char *strDest, const char *strSource );
?헤더파일 string.h
? wchar_t *wcscat( wchar_t *strDest, const wchar_t *strSource );
?wide-character, 헤더파일 string.h, wchar.h
? unsigned char *_mbscat( unsigned char *strDest,
const unsigned char *strSource );
?multibyte-character, 헤더파일 mbstring.h
? char *strncat( char *strDest, const char *strSource, size_t count );
? wchar_t *wcsncat( wchar_t *strDest, const wchar_t *strSource, size_t count );

?strDest

Null-terminated destination string

?strSource

Null-terminated source string

?count

Number of characters to append

(C) 1998 Sang Il Kim

? unsigned char *_mbsncat( unsigned char *strDest,
const unsigned char *strSource, size_t count);
? Parameters

Visual C++ Programming

6
9

문자열
? 문자열 길이
? size_t strlen( const char *string );
?헤더파일 string.h
? size_t wcslen( const wchar_t *string );
?wide-character, 헤더파일 string.h, wchar.h
? size_t _mbslen( const unsigned char *string );
?multibyte-character, 헤더파일 mbstring.h
? size_t _mbstrlen( const char *string );
?헤더파일 stdlib.h

(C) 1998 Sang Il Kim

? Parameter
?string
Null-terminated string

Visual C++ Programming

6
9

콜렉션 클래스
? 템플릿 기반의 콜렉션 클래스
? 비템플릿 기반의 콜렉션 클래스

? 콜렉션 모양
? 배열
?이들 클래스는 동적으로 크기를 변경할 수 있고, 인덱스가 붙은 객체 배열을 제공한다.

? 목록
?이들 클래스는 이중 링크 목록으로 구현된 요소들의 목록을 제공한다.

?맵
?이들 클래스는 키 객체를 값 객체와 연관시키는 콜렉션을 제공한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

?목록 내에 요소들을 넣고 빼는 작업을 매우 빠르고 효율적으로 수행할 수 있다.

6
9

콜렉션 클래스
? 비템플릿 기반의 콜렉션 클래스
? AFXCOLL.H 를 포함시켜야 한다.

? 비템플릿 기반의 배열 클래스
배열 클래스

설명

CByteArray()

동적으로 크기를 변경할 수 있는 바이트의 배열을 지원한다.(BYTE형)

CDWordArray()

동적으로 크기를 변경할 수 있는 32바이트의 배열을 지원한다.(DWORD형)

CObArray()

동적으로 크기를 변경할 수 있는 CObject 포인터의 배열을 지원한다.

CPtrArray()

동적으로 크기를 변경할 수 있는 void 포인터의 배열을 지원한다.(void *형)

CStringArray()

동적으로 크기를 변경할 수 있는 CString 객체의 배열을 지원한다.

CUIntArray()

동적으로 크기를 변경할 수 있는 부호없는 정수의 배열을 지원한다.

CWordArray()

동적으로 크기를 변경할 수 있는 16비트의 배열을 지원한다.(WORD형)
Visual C++ Programming

(C) 1998 Sang Il Kim

? 이들 클래스는 보통 이미 사용하고 있는 이전의 MFC 프로그램과의 호환성을 위해 사용한다.

6
9

콜렉션 클래스
? 비템플릿 기반의 목록 클래스
설명

CObList()

유일하지 않은 CObject 포인터들의 순서가 있는 이중 링크 목록을 지원한다.

CPtrList()

유일하지 않은 void 포인터들의 순서가 있는 이중 링크 목록을 지원한다.

CStringList()

유일하지 않은 CString 포인터들의 순서가 있는 이중 링크 목록을 지원한다.

(C) 1998 Sang Il Kim

목록 클래스

Visual C++ Programming

6
9

콜렉션 클래스
? 비템플릿 기반의 맵 클래스
맵 클래스

설명

CMapPtrToPtr()

void 포인터를 키로 갖고 있는 void 포인터의 맵을 지원

CMapPtrToWord()

void 포인터를 키로 갖고 있는 16비트 워드의 맵을 지원

CMapStringToOb()

고유의 CString 객체나 문자열을 키로 갖고 있는 CObject 포인터의 맵을 지원

CMapStringToPtr() 고유의 CString 객체를 키로 갖고 있는 void 포인터(void *)의 맵을 지원
CString 객체를 키로 갖고 있는 CString 객체의 맵을 지원

CMapWordToOb()

16비트 단어를 키로 갖고 있는 CObject 포인터의 맵을 지원

CMapWordToPtr()

16비트 단어를 키로 갖고 있는 void 포인터(void *)의 맵을 지원
(C) 1998 Sang Il Kim

CMapStringToString()

Visual C++ Programming

6
9

콜렉션 클래스
? 템플릿 기반의 클래스
? 이들 클래스는 개발자가 재사용할 수 있는 소프트웨어 클래스를 만들 수 있도록 해준다.

템플릿 클래스

설명

CArray

임의 유형의 객체로 된 배열을 생성하는데 사용한다.

CList

임의 유형의 객체로 된 목록을 생성하는데 사용한다.

CMap

임의 유형의 객체로 된 맵을 생성하는데 사용한다.

CTypedPtrArray

CObArray 와 CPtrArray 객체로 된 유형 안전 배열을 만드는데 사용한다.

CTypedPtrList

CObList 와 CPtrList 객체로 된 유형 안전 목록을 만드는 데 사용한다.

CTypedPtrMap

CObMap과 CPtrMap객체로 된 유형 안전 맵을 만드는데 사용한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

? 이들 클래스를 이용하면, 임의 유형의 객체로 된 배열과 목록, 맵을 만들 수 있다.

7
0

날짜와 시간 클래스
? CTime 클래스 메소드
설명

Format()

CTime 객체를 지역 시간대를 바탕으로 서식이 지정된 문자열로 변환한다.

FormatGmt()

GMT(Greenwich Mean Time)로 알려진 UTC(Universal Time Coordinates)
를 바탕으로 서식이 지정된 문자열로 CTime 객체를 변환한다.

GetDay()

CTime 객체에 나타난 그 달의 오늘 날짜(1-31)를 구한다.

GetDayOfWeek()

CTime 객체에 나타난 요일(1-7)을 구한다.

GetGmtTm()

CTime 객체를 UTC를 기반으로 각 요소별로 분석한다.
(Time.h 에 있는 tm 구조에 정의된 대로)

GetHour()

CTime 객체에 나타난 시간(0-23)을 구한다.

GetLocalTm()

CTime 객체를 지역 시간대를 기반으로 각 요소별로 분석한다.
(Time.h 에 있는 tm 구조에 정의된 대로)

GetMinute()

CTime 객체에 나타난 분(0-59)을 구한다.

GetMonth()

CTime 객체에 나타난 월(1-12)을 구한다.

GetSecond()

CTime 객체에 나타난 초(0-59)를 구한다.

GetTime()

CTime 객체의 의미에 맞게 time_t 구조를 채운다.

GetYear()

CTime 객체에 나타난 연도를 구한다.

(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

7
0

날짜와 시간 클래스

연산자

설명

연산자 =

시간 값을 할당한다.

연산자 +

CTimeSpan과 CTime 객체를 더한다.

연산자 -

CTimeSpan과 CTime 객체를 뺀다.

연산자 +=

CTimeSpan객체를 CTime 객체에 더한다.

연산자 -=

CTimeSpan객체를 CTime 객체로부터 뺀다.

연산자 ==

두 개의 절대 시간이 같은지 비교한다.

연산자 !=

두 개의 절대 시간이 같지 않은지 비교한다.

연산자 <

두 개의 절대 시간 중 하나가 다른 것보다 작은지 비교한다.

연산자 >

두 개의 절대 시간 중 하나가 다른 것보다 큰지 비교한다.

연산자 <=

두 개의 절대 시간 중 하나가 다른 것보다 작거나 같은지 비교한다.

연산자 >=

두 개의 절대 시간 중 하나가 다른 것보다 크거나 같은지 비교한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CTime 클래스 연산자

7
0

날짜와 시간 클래스
? CTimeSpan 클래스 메소드
설명

Format()

CTimeSpan을 서식이 지정된 문자열로 변환한다.

GetDays()

CTimeSpan에 있는 완전한 날의 수를 구한다.

GetHours()

오늘 날짜의 수(-23 ~ 23)를 구한다.

GetMinutes()

현재의 시간에 있는 분의 수(-59 ~ 59)를 구한다.

GetSeconds()

현재의 분에 있는 초의 수(-59 ~ 59)를 구한다.

GetTotalHours()

CTimeSpan에 있는 완전한 시간의 전체 수를 구한다.

GetTotalMinutes()

CTimeSpan에 있는 완전한 분의 전체 수를 구한다.

GetTotalSeconds()

CTimeSpan에 있는 완전한 초의 전체 수를 구한다.
(C) 1998 Sang Il Kim

메소드

Visual C++ Programming

7
0

날짜와 시간 클래스

연산자

설명

연산자 =

새 시간 값을 할당한다.

연산자 +

CTimeSpan 객체를 더한다.

연산자 -

CTimeSpan 객체를 뺀다.

연산자 +=

CTimeSpan객체를 CTimeSpan 객체에 더한다.

연산자 -=

CTimeSpan객체를 CTimeSpan 객체로부터 뺀다.

연산자 ==

두 개의 절대 시간이 같은지 비교한다.

연산자 !=

두 개의 절대 시간이 같지 않은지 비교한다.

연산자 <

두 개의 절대 시간 중 하나가 다른 것보다 작은지 비교한다.

연산자 >

두 개의 절대 시간 중 하나가 다른 것보다 큰지 비교한다.

연산자 <=

두 개의 절대 시간 중 하나가 다른 것보다 작거나 같은지 비교한다.

연산자 >=

두 개의 절대 시간 중 하나가 다른 것보다 크거나 같은지 비교한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

? CTimeSpan 클래스 연산자

7
0

CDialog
? CDialog 클래스 메소드
메소드

설명

DoModal()

규격 대화 상자를 호출하고, 대화 상자가 닫히기 전에는 반환하지 않는다.

EndDialog()

규격 대화 상자를 닫거나 비규격 대화 상자를 숨긴다.

GetDefID()

대화 상자의 기본 누름 단추 컨트롤의 ID를 받는다.

GotoDlgCtrl()

대화 상자 내의 특정 컨트롤에 입력 포커스를 맞춘다.

NextDlgCtrl()

대화 상자의 입력 포커스를 다음 컨트롤로 옮긴다.

PrevDlgCtrl()

대화 상자의 입력 포커스를 이전 컨트롤로 옮긴다.

SetDefID()

대화 상자에 기본 누름 단추 컨트롤을 설정한다.

SetHelpID()

대화 상자에 문맥을 감지하여 동작하는 도움말 ID를 설정한다.

Visual C++ Programming

(C) 1998 Sang Il Kim

MapDialogRect() 직사각형의 대화 상자 단위를 나타내기 위한 단위에 맵핑한다.

7
0

DDV(Dialog Data Validation)
? DDV (데이터 유효성 검사)
? 이 함수들은 전형적으로 유효성 검사시 일어난 문제점을 알리는 메시지 상자를
나타내고, 문제가 일어난 컨트롤에 포커스를 맞춘다.
? 사용자가 입력한 데이터가 유효하지 않거나 받아들일 수 있는 범위를 벗어났을 때
예외를 발생시킨다.
? 컨트롤의 DDV 함수의 호출은 DDX 함수를 호출한 후에 일어나야 한다.
메소드

설명

DDV_MaxChars()

특정 값의 매개 변수와 연결된 컨트롤에서 문자의 개수가 지정된 값을
초과하지 않았는지를 확인한다.

DDV_MinMaxByte()

컨트롤의 BYTE 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxDouble()

컨트롤의 DOUBLE 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxFloat()

컨트롤의 FLOAT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxInt()

컨트롤의 INT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxLong()

컨트롤의 LONG 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

DDV_MinMaxUnsigned() 컨트롤의 UINT 값이 지정된 최소, 최대값 사이에 있는지 확인한다.
Visual C++ Programming

(C) 1998 Sang Il Kim

DDV_MinMaxDWord() 컨트롤의 DWORD 값이 지정된 최소, 최대값 사이에 있는지 확인한다.

7
0

Sign up to vote on this title
UsefulNot useful