[게임프로그래밍전문가] 2011년 제 1회 A형
시험 정보
- 시험: 게임프로그래밍전문가
- 회차: 2011년 제 1회 A형
게임 제작 개론
문제 10
문제
다음 중 그래픽 엔진에서 백 버퍼나 보조 버퍼의 내용을 주 버퍼로 한 번에 옮겨오는 역할을 하는 것은?
보기
① 타일(Tile) ② 플리핑(Flipping) ③ 캐시(Cache) ④ 스택(Stack)
내 답: 3
고른 이유: 캐시는 알고 있었지만, 플리핑을 몰라서 대충 아는 걸로 찍었다.
정답: 2
오답 노트
플리핑은 더블 버퍼링에서 백 버퍼의 내용을 프론트 버퍼로 교체하는 기법이다.
캐시는 CPU와 메모리 사이의 임시 저장소로 버퍼 교체와 무관하다.
프로그래밍 일반
문제 5
문제
샘플로 제시된 클래스에 대하여 다음과 같이 객체를 선언하고 사용
할 경우 컴파일 할 때 에러가 발생하지 않는 것은?
class CBaseMover
{
protected:
int m_iHP;
protected:
CBaseMover() {}
public:
~CBaseMover() {}
void SetName(char* pszName) {}
virtual void SetHP(int iHP) = 0;
};
class CMover : public CBaseMover
{
public:
CMover() {}
~CMover() {}
public:
void SetHP(int iHP) { m_iHP = iHP; }
};
class CPlayer: public CBaseMover
{
private:
int m_iMP;
public:
CPlayer() {}
~CPlayer() {}
public:
void SetMP(int iMP) { m_iMP = iMP; }
};
보기
① CBaseMover* pBaseMover = new CBaseMover; pBaseMover->SetName(“BaseMover”);
② CMover* pMover = new CMover; pMover->SetName(“Mover”);
③ CPlayer* pPlayer = new CPlayer; pPlayer->SetHP(100);
④ CPlayer* pPlayer = new CPlayer; pPlayer->SetMP(100);
내 답: 4
정답: 2
오답 노트
- CBaseMover는 SetHP()가 순수 가상 함수라서 추상 클래스이기 때문에 ①은 인스턴스화가 불가능하다.
- CPlayer는 SetHP()를 구현하지 않았기 때문에 추상 클래스이고, 그렇기에 ③,④는 인스턴스화가 불가능하다.
- CMover는 SetHP()가 구현되어 있어 컴파일할 때 에러가 발생하지 않는다.
문제 9
문제
한 프로세서 안에 두개의 스레드가 있다. 한 스레드는 변수에 값을
쓰고 다른 변수는 동일한 변수에 값을 읽는 경우 사용할 수 있는 동기
화 객체가 아닌 것은?
보기
① 크리티컬 섹션(Critical Section)
② 인터럽트(Interrupt)
③ 뮤텍스(Mutex)
④ 세마포어(Semaphores)
내 답: 4
정답: 2
오답 노트
크리티컬 섹션, 뮤텍스, 세마포어는 스레드 동기화 객체.
인터럽트(Interrupt) 는 하드웨어/소프트웨어 이벤트 처리 메커니즘으로, 스레드 동기화 객체가 아니다.
문제 17
문제
SQL에서 특정 조건의 데이터를 수정하기 위해서 사용되는 명령어는?
보기
① SELECT ② DELETE ③ MODIFY ④ UPDATE
내 답: 3
고른 이유: MODIFY와 UPDATE에서 헷갈렸다. 기억 속에는 UPDATE가 남아있었는데, MODIFY라는 단어의 뜻 때문에 고른 것 같다.
정답: 2
오답 노트
SQL에서 데이터 수정은 UPDATE. MODIFY는 SQL 표준에 없는 명령어.
문제
문제
다음은 무엇을 계산하는 프로그램인가?
#include <stdio.h>
void main()
{
int i, sum;
sum = i = 0;
do{ if(i%2 == 0)
sum = sum + (++i);
else i++;
} while(i<100);
printf("%d", sum);
}
보기
① 1부터 99까지 합
② 1부터 99까지 짝수의 합
③ 1부터 99까지 홀수의 합
④ 1부터 100까지 소수의 합
내 답: 2
고른 이유: 문제를 잘못 읽었다.
정답: 3
오답 노트
추적:
- i=0 → i%2==0 → sum += (++i=1) → sum=1
- i=1 → i%2!=0 → i++ → i=2
- i=2 → i%2==0 → sum += (++i=3) → sum=4
- i=3 → i%2!=0 → i++ → i=4
…
짝수일 때 먼저 ++i로 홀수로 만든 뒤 합산 → 1, 3, 5, … 99의 합.
문제 21
문제
다음 함수 Calculate()를 호출했을 때 반환되는 값은?
int Calculate()
{
int n = 2;
switch (n)
{
case 1 : n = 1;
case 2 : n++;
case 3 : n *= 3;
case 4 : n %= 5;
}
return n;
}
보기
① 1 ② 2 ③ 3 ④ 4
내 답: 3
고른 이유: break;가 없는 걸 인지하지 못했다.
정답: 4
오답 노트
n=2
case 2: n++ → n=3 // break 없음, 폴스루
case 3: n*=3 → n=9 // break 없음, 폴스루
case 4: n%=5 → n=4
return 4
switch에 break가 없으면 폴스루(fall-through) 발생.
문제 27
문제
C++ 언어에서 생성자(Constructor)와 소멸자(Destructor)에 대한
설명으로 틀린 것은?
보기
① 생성자와 소멸자는 어떠한 Type의 데이터도 리턴하지 않는다.
② 생성자와 소멸자를 가지는 클래스는 공용체(union)의 멤버가 될 수 없다.
③ abort 함수로 프로그램의 실행을 마칠 때 소멸자는 전혀 호출되지 않는다.
④ 생성자는 가상 함수(virtual function)이다.
내 답: 4
틀리지는 않았지만 한 번 더 정리
정답: 4
정리
생성자는 호출 시점에 가상 테이블이 완성되지 않았기 때문에 가상 함수가 될 수 없다.
소멸자는 virtual 선언이 가능하다.
문제 29
문제
COM(Component Object Model)에 대한 설명으로 잘못된 것은?
보기
① 소프트웨어 모듈을 바이너리 컴포넌트로 추상화시켜 주는 마이크로소프트가 개발한 소프트웨어 구조이다.
② Win32 API 함수들을 체계적으로 통합한 클래스이다.
③ Visual Basic, Delphi 등 어떠한 프로그래밍 언어에 의해서도 접근이 가능하도록 설계하였다.
④ COM 객체의 경우 C++의 객체보다 더 엄격한 캡슐화(encapsulation)를 요구한다.
내 답: 3
정답: 2
오답 노트
COM은 언어 독립적인 바이너리 인터페이스 표준으로 Win32 API 클래스 집합이 아님.
③(언어 독립성)은 COM의 핵심 특징으로 올바른 설명.
알고리즘
문제 2
문제
다음 그림에 있는 트리의 차수(Degree)와 터미널 노드(Terminal node)의 수는?

보기
① 차수:3 터미널 노드:7
② 차수:3 터미널 노드:4
③ 차수:4 터미널 노드:7
④ 차수:4 터미널 노드:4
내 답: 1
고른 이유: 터미널 노드가 뭔지 알지 못했다.
정답: 2
오답 노트
- 차수(Degree): 한 노드가 가진 자식의 최대 수
- 터미널 노드(단말 노드): 자식이 없는 노드
문제 3
문제
다음 이진 트리를 후위법(Postorder)로 순회했을 경우를 바르게 표
시한 것은?

보기
① A-B-D-E-H-C-F-I-G-J
② D-H-E-B-I-F-J-G-C-A
③ D-B-E-H-A-I-F-C-G-J
④ A-C-G-J-F-I-B-E-H-D
내 답: 4
고른 이유: 4번과 2번 중 고민하다가 4번으로 찍었다.
정답: 2
오답 노트
- 후위 순회(Postorder) 순서: 왼쪽 서브트리 → 오른쪽 서브트리 → 루트.
- ①
A-B-D-…형태는 루트 A가 맨 앞이므로 전위 순회(Preorder)에 해당한다. - ④
A-C-G-…형태는 후위·전위·중위의 전형적인 패턴과 맞지 않는 역방향에 가깝다. - 후위 순회에서는 루트 A가 방문 순서의 맨 마지막에 와야 하므로, 끝이
…-A인 ②가 정답이다. (D-H-E-B-I-F-J-G-C-A)
문제 19
문제
삽입과 삭제 작업이 자주 발생할 때 실행시간이 가장 많이 소요되는 자료구조는?
보기
① 배열로 구현된 리스트
② 단순 연결 리스트
③ 스택(stack)
④ 디큐(deque)
내 답: 3
정답: 1
오답 노트
- 배열로 구현된 리스트는 중간 위치에 삽입·삭제할 때, 빈 칸을 만들거나 메꾸기 위해 원소를 한 칸씩 이동시켜야 해서 평균·최악
O(n)이 된다. - 연결 리스트는 삽입·삭제 위치의 노드를 이미 알고 있다면 포인터(링크)만 갱신하면 되어
O(1)로 처리할 수 있다. - 스택의
push/pop, 큐의 일반적인 연산도 보통 탑(또는 앞·뒤)에서만 다루므로O(1)에 가깝다.
문제 21
문제
다음중 문자열 처리 알고리즘이 아닌 것은?
보기
① Lempel-Ziv
② Boyer-Moore.
③ Rabin-Karp
④ Kruth-Morris-Pratt
문제지에서 오타가 있었던 듯 하다 Kruth가 아닌 Knuth라고 한다.
내 답: ?
아예 몰라서 못 풀었다.
정답: 1
오답 노트
- Lempel-Ziv(LZ77, LZ78, LZW 등)는 슬라이딩 사전·구문 치환 방식으로 데이터를 줄이는 데이터 압축 알고리즘이다.
- Boyer-Moore, Rabin-Karp, KMP(Knuth-Morris-Pratt)는 모두 긴 문자열 안에서 패턴을 찾는 문자열 검색(매칭) 알고리즘이다.
문제 22
문제
다음 방향 그래프 중, 정점 집합 위의 이진 관계로 보았을 때 동치 관계가 아닌 것은?
보기
①

②

③

④

내 답: 4
고른 이유: 동치 관계라고 하길래 뭔가 어감상 대칭이 되면 되는 줄만 알았다.
정답: 3
오답 노트
- 동치 관계(Equivalence relation)가 되려면 반사성(reflexive), 대칭성(symmetric), 추이성(transitive)을 모두 만족해야 한다.
- 3번은 추이성을 만족하지 않는다. 1↔2이고 2↔4인데, 1↔4가 존재하지 않는다.
문제 24
문제
추가적인 메모리를 필요로 하는 정렬 기법은?
보기
① 삽입 정렬(insert sort)
② 쉘 정렬(shell sort)
③ 병합 정렬(merge sort)
④ 버블 정렬(bubble sort)
내 답: 4
정답: 3
오답 노트
- 병합 정렬은 두 부분 배열을 합치는 과정에서 결과를 담을 임시 배열(또는 동일 크기의 보조 버퍼)이 필요하므로, 일반적으로 추가 공간이 O(n)이다.
- 삽입 정렬, 쉘 정렬, 버블 정렬은 원소를 제자리에서 비교·이동하는 in-place 정렬에 가깝고, 보조 공간은 상수 수준 O(1)로 보는 경우가 많다.
문제 28
문제
다음 중 곡선 생성 알고리즘이 아닌 것은?
보기
① B-Spline
② Bezier
③ NURBS
④ Blending
내 답: 3
정답: 4
오답 노트
- B-Spline, Bezier, NURBS(Non-Uniform Rational B-Spline)는 모두 곡선·곡면을 표현·생성하기 위한 방식이다.
- Blending은 두 색, 두 값, 두 포즈 등을 섞는 혼합 기법이며, 그 자체로 B-Spline·Bezier처럼 독립적인 곡선 생성 알고리즘이라고 보기 어렵다.
게임 프로그램 제작
문제 1
문제
윈도우의 GDI를 이용할 경우 화면처리 속도가 게임을 진행하기에 충분하지 않으므로 DirectX의 HAL(Hardware Abstraction Layer)과 같은 인터페이스의 지원이 반드시 필요하다. DirectX의 HAL에 대한 설명으로 옳은 것은?
보기
① 최대의 성능을 위해 하드웨어를 직접 동작시키는 인터페이스
② 하드웨어에서 지원하지 않는 부분을 에뮬레이션(Emulation) 해주는 모듈
③ Win32 환경에서 GDI와 연관 동작하는 출력 인터페이스
④ 출력 장치에 대한 윈도우즈 디바이스 드라이버
내 답: ?
HAL에 대해 들은 적이 있었는데, 좀 오래돼서 까먹은 것 같다.
정답: 1
오답 노트
- HAL(Hardware Abstraction Layer): 시험·교재 맥락에서는 하드웨어를 직접 제어하는 레이어로 기술되는 경우가 많다.
- HEL(Hardware Emulation Layer): 하드웨어가 지원하지 않는 기능을 소프트웨어로 에뮬레이션하는 층에 해당한다(② 보기 등과 대비).
문제 4
문제
다음은 퍼지논리에 대한 설명인데 적절하지 않은 것은?
보기
① 퍼지 언어 변수란 어떤 개념이나 영역을 질적으로 표현하기 위해서 한 개나 그 이상의 퍼지 집합을 합하는 것이다.
② 하나의 퍼지 집합은 소속 함수로 정의된다.
③ 후항 집합을 나타내기 위해서 요구되는 것은 반응 언어 변수이다.
④ 퍼지 규칙은 형식상 선행자(Antecedent)와 후항(Consequent)으로 구성된다.
내 답: ?
정답: 3
오답 노트
- 퍼지 규칙은 IF [선행자(Antecedent)] THEN [후항(Consequent)] 형태로 쓴다.
- 후항을 나타내는 것은 결과 언어 변수이며, “반응 언어 변수”라는 표현은 맞지 않다.
문제 5
문제
바운딩 볼륨, OBB(Oriented Bounding Box)에 대한 설명으로 옳지 않은 것은?
보기
① 기울어진 경계 박스라는 뜻이다.
② OBB/OBB 교차 검사를 유도는 데 SAT(Separating Axis Theorem)을 사용할 수 있다.
③ OBB를 생성하는 방법 중 한가지는 통계학적인 방법을 사용하는데, 공분산(Covariance)이 이용된다.
④ OBB의 자료구조는 박스의 중심점과 박스의 세 방향을 나타내는 세 개의 정규화된 벡터들로만 구성된다.
내 답: 1
고른 이유: 1번까지밖에 읽지 않았다. OBB가 방향이 지정된 것이지 기울어진 건 아니라고 생각했다.
정답: 4
오답 노트
- OBB를 표현할 때는 박스의 중심점, 세 축 방향의 단위 벡터, 각 축 방향의 반경(half-extents) 등이 함께 쓰인다.
- “중심점과 세 방향 벡터들로만 구성된다”처럼 범위(길이) 정보 없이 단위 벡터만으로 끝난다고 보면 틀린 설명이 된다.
문제 6
문제
그래픽 파이프 라인에서 다각형 단위의 조작이나 정점 단위의 조작을 주로 담당하는 부분이면서, 하드웨어 가속을 받을 수 있는 부분을 기하단계(The Geometry Stage)로 분리 할 수 있는데, 이러한 기하 단계들을 여러 기능 단계로 분할했을 때 해당되지 않는 요소는?
보기
① 투영(Projection)
② 계층적 시각 절두체 선별(View Frustum Culling)
③ 월드(World) 변환과 뷰(View) 변환
④ 클리핑(Clipping)
내 답: 3
정답: 2
오답 노트
- 기하 단계에서 다루는 흐름에는 월드 변환, 뷰 변환, 투영, 클리핑 등이 포함되는 경우가 많다.
- 계층적 시각 절두체 선별(Hierarchical view frustum culling)은 보통 애플리케이션 단계에서 미리 줄이기 위해 수행하고, 기하 단계의 전형적인 구성 요소로 넣기 어렵다.
문제 8
문제
그램-슈미트(gram-schmidt) 직교화라는 것은 주어진 벡터들을 정규 직교화해주는 알고리즘이다. 그램-슈미트 직교화 이론이 사용되는 것은?
보기
① Bezier Spline(베지어 스플라인)
② Portal Culling(포탈 선별)
③ TangentSpace Calculation(탄젠트 공간 계산)
④ Full Screen Anti Aliasing(풀스크린 안티알리어싱)
내 답: 1
고른 이유: ‘사용되지 않는 것은?’ 으로 봤다. 그래서 1번을 보자마자 고르고 넘어가버렸다.
정답: 3
오답 노트
- 탄젠트 공간(Tangent space) 계산에서 탄젠트(T), 바이탄젠트(B), 노멀(N) 벡터를 직교·정규화할 때 그램-슈미트 과정이 쓰인다.
- 베지어 스플라인 곡선 생성과는 직접적인 관련이 없다.
문제 9
문제
D3D의 렌더링 처리시 필요한 세 개의 행렬로 월드, 뷰, 투영 행렬이 있는데, 다음에서 이들에 대한 설명 중 틀린 것은?
보기
① 월드 변환(World Transform)은 물체가 사용하는 로컬 좌표계를 전체 월드 좌표계로 변환하는 것으로 SetTransform() 함수에 D3DTS_WORLD 인자 설정으로 처리한다.
② 카메라 변환은 물체의 좌표를 카메라를 기준으로 한 카메라 좌표계의 값으로 변환하는 것이다.
③ 카메라 변환은 D3DMatrixLookAtLH() 로 카메라 변환 행렬을 계산할 수 있다.
④ 투영 변환은 3차원 월드 좌표를 화면의 2차원 좌표계로 변환하는 것으로 투영 변환 후에는 (-1, -1, -1) ~ (1, 1, 1)의 사각입방체 공간으로 변환된다.
내 답: ?
정답: 4
오답 노트
- DirectX는 왼손 좌표계를 사용하며, 투영 변환 후 Z 범위는 0~1. (-1~1)은 OpenGL 기준. 따라서 DirectX에서 클립 공간은 (-1,-1,0) ~ (1,1,1).
문제 10
문제
D3D에서 텍스쳐 매핑시 UV 좌표값에 의해서 텍스쳐 텍셀 값을 읽어오는데, 이때 텍셀 값을 결정하는데 필터링(Filtering)이라는 기법을 사용한다. 이들 필터에 대한 다음 설명 중 맞지 않는 것은?
보기
내 답: 2
정답: 3
오답 노트
- ANISOTROPIC(이방성) 필터링은 시야 각도에 따라 샘플링 패턴을 바꿔 기울어진 면에서의 품질을 높이는 방식이다.
- “4개 샘플의 가우스 필터값”처럼 가우스에 고정해 두는 설명은 D3DTEXF_GAUSSIANQUAD 등 다른 필터와 혼동하기 쉽다.
문제 13
문제
다음 중 환경 맵핑(Environment Mapping)에 대한 설명으로 올바른 것은?
보기
① 적은 수의 폴리곤으로 복잡한 표면의 상태를 렌더링할 수 있는 방법이다.
② 반사성 높은 표면을 레이트레이싱을 사용하지 않고 시뮬레이션 하는 방법이다.
③ 렌더링시 나타나는 계단상의 픽셀을 줄이기 위한 방법이다.
④ 레이트래이싱 방법보다 계산량이 많다.
내 답: 1
정답: 2
오답 노트
- 환경 맵핑은 주변 환경을 미리 텍스처(큐브 맵 등)에 담아 두고, 반사가 강한 표면을 레이 트레이싱 없이 근사하는 방법이다.
- ①은 노멀 맵핑에 가깝고, ③은 안티앨리어싱에 가깝다. ④처럼 환경 맵핑이 레이 트레이싱보다 느리다고 보는 것은 반대이다.
문제 14
문제
3D 렌더링 과정에서 곡면을 효과적으로 표현하기위해 하나의 면을 여러 개로 분할하는 테셀레이션(tessellation)을 수행해야하는 경우가 있다. DirectX 9.0에서도 이 기능을 지원하는데, 이에 대한 설명으로 틀린 것은?
보기
① 직사각형 패치 테셀레이션을 지원한다.
② 적응형 테셀레이션은 N 패치, 직사각형 패치, 삼각형 패치와 같은 고차원 기본 도형의 테셀레이션을 지원한다.
③ N 패치의 경우에는 내부의 직사각형 패치의 정점을 사용한다.
④ 삼각형 패치의 경우에는 모퉁이의 패치 정점을 사용한다.
내 답: ?
정답: 3
오답 노트
- N-Patch는 기존 삼각형 메시의 꼭짓점 위치와 노멀 정보를 이용해 곡면을 부드럽게 보이게 만드는 방식이다.
- “내부의 직사각형 패치의 정점을 사용한다”는 식의 설명은 N-Patch의 전형적인 정의와 맞지 않다.
문제 17
문제
인간의 시각이 인지하는 빛의 휘도 범위를 모니터와 같은 디스플레이 장치로는 모두 표현하지 못하기 때문에, 이 문제를 해결하기 위해 고안된 렌더링 기법을 무엇이라고 하는가?
보기
① Parallax Mapping
② Deferred Rendering
③ Inferred Rendering
④ High Dynamic Range
내 답: 1
정답: 4
오답 노트
- HDR(High Dynamic Range) 렌더링은 넓은 휘도 범위를 다룬 뒤 톤 매핑 등으로 디스플레이에 맞게 압축·표현한다.
- Parallax mapping은 깊이감을 주는 범프/변위에 가까운 기법으로, 동적 범위 문제의 핵심 답과는 다르다.
문제 19
문제
다음 중 저폴리곤 모델에 명암 조작을 통하여 마치 많은 폴리곤을 사용한 것처럼 정교한 모양이 나타나도록 하는 기법은?
보기
① 법선 매핑
② 텍스처 매핑
③ 키프레이밍
④ 알파채널
내 답: 4
정답: 1
오답 노트
- 노멀 매핑(Normal mapping)은 노멀 맵에 저장된 방향 정보로 조명 계산 시 미세한 굴곡을 흉내 낸다.
- 알파 채널은 주로 투명도·컷아웃 등에 쓰이며, 복잡한 표면 명암을 대체하는 용도가 아니다.
문제 21
문제
다음 중 버전(Version) 관리 시스템이 아닌 것은?
보기
① CVS ② Subversion ③ Mantis ④ GIT
내 답: 2
정답: 3
오답 노트
- Mantis는 버그 추적(Bug tracking) 도구이다.
- CVS, Subversion(SVN), Git 등은 소스 버전 관리에 쓰는 VCS에 해당한다.
문제 24
문제
윈도우 소켓을 이용한 TCP/IP 서버 프로그램에서 사용되는 함수의 순서가 올바르게 된 것은?
보기
① socket() →listen() →bind() →accept() →recv()
② socket() →accept() →bind() →listen() →recv()
③ socket() →accept() →listen() →bind() →recv()
④ socket() →bind() →listen() →accept() →recv()
내 답: 1
정답: 4
오답 노트
- TCP 서버의 전형적인 순서:
socket()으로 소켓 생성 →bind()로 주소·포트 결합 →listen()으로 연결 대기 큐 준비 →accept()로 클라이언트 연결 수락 →recv()등으로 데이터 수신.
문제 27
문제
스레드에 대한 설명으로 옳지 않은 것은?
보기
① 스레드는 OS가 프로세서 타임을 할당하는 기본적인 단위이다.
② 스레드는 타임 슬라이스(time slice)에 의해 할당되어 구현된다.
③ 네트워크 서버의 경우 블록킹 모드를 방지하기 위해서 접속에 관한 부분을 스레드에 넣고 서버가 해야 할 일을 하며 접속이 들어오면 스레드에서 처리할 수 있도록 하기도 한다.
④ 타임 슬라이스(time slice)의 길이는 OS 와 프로세서에 의존하지만 대략 1000 밀리세컨드이다.
내 답: 3
정답: 4
오답 노트
- 타임 슬라이스(time slice)는 한 스레드가 연속으로 CPU를 쓸 수 있는 대략적인 시간으로, 보통 수 ms~수십 ms 수준에서 이야기하는 경우가 많다.
- 1000ms(1초)는 일반적인 타임 슬라이스 크기로 보기 어렵다.
문제 30
문제
게임 진행에 필요한 마우스와 키보드 입력을 윈도우 메시지로 처리할 경우 발생한 메시지를 이벤트 처리 핸들러 루틴으로 보내 주는 역할과 관계된 함수는?
보기
① PeekMessage
② TranslateMessage
③ DispatchMessage
④ DefWindowProc
내 답: 1
정답: 3
오답 노트
DispatchMessage(): 메시지를 등록된WndProc으로 전달한다.PeekMessage(): 큐에 메시지가 있는지 확인·꺼낸다.TranslateMessage(): 가상 키 메시지를 문자 메시지로 바꾼다.DefWindowProc(): 처리하지 않은 메시지의 기본 동작을 수행한다.