7장. MDI 프로그래밍 MDI 프로그래밍에 대한 내용을 배우도록 한다. 지금까지 배운 것은 생성된 윈도우에 단일 화면이 존재하는 형태였다. 이것을 SDI라고 부르고 Single Document Interface의 약자이다. 하나의 문서를 하나의 화면에 보여주는 형태의.

Slides:



Advertisements
Similar presentations
장기요양 인력변경보고의 온라인신고 시행에 따른 사회복지시설정보시스템 사용안내
Advertisements

메시지 처리의 기본 개념 메시지 발생된 이벤트의 종류와 정보를 전달하는 일종의 상수 값 윈도우 프로그래밍 가장 중요한 것은 메시지를 처리하는 것 윈도우 시스템 Application 이벤트 발생 메시지 전송 메시지 처리 화면에 출력.
5장5장5장5장 개요 폼 개체 다중폼 개요 폼 개체 다중폼 다중폼. 2 학습목표 폼 개체를 학습한다. 다중폼에 대하여 학습한다.
미디어 프로그래밍 II 소개.
4. 기본적인 그리기.
2장. 윈도우즈 입출력 1/211 1.
윈도우 일반 공주영상대학 게임과 이 은 순.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
Windows Programming Chapter 1. Introduction to SDK
윈도우 운영체제와 윈도우 응용 프로그램의 특징을 이해한다.
WSAAsync Select 김대열 Bit - Academy Sunmoon University, Korea.
제1장 윈도우 프로그래밍 1.1 윈도우 프로그래밍의 개념 1.2 윈도우 프로그램의 기본 구조
MFC의 메시지 처리.
Visual C++ Programming Document/View Architecture 3
제1장 윈도우 프로그래밍 1.1 윈도우 프로그래밍의 개념 1.2 윈도우 프로그램의 기본 구조
5장. 단축키와 비트맵 윈도우 프로그램에는 화면에서 사용자들의 입력을 받아 들이고 출력을 위한 코드 외 부분이 존재한다. 이 부분을 주로 리소스라고 부르고 이들은 주로 화면에 나타난다. 메뉴, 툴바, 비트맵, 단축키, 대화상자 등이 여기에 속한다. 이 부분들은 우리의 프로그램의.
Chapter 09. 소켓 입출력 모델(I).
커뮤니케이션 스킬 UP -전화매너- ..
Lab 3 Guide: 교재 4장 대화상자 예제. - 프로파일 입력 ( 쪽)
제12장 유연한 카메라 클래스 만들기 학기 컴퓨터게임(DirectX).
Windows Programming.
Windows Programming 시작하기
Win32 API Programming 이 계 임.
강사 : 이준근 Win32 API 강사 : 이준근
명품 JAVA Essential.
제2절 법인세의 계산구조와 세무조정 1. 각 사업연도소득에 대한 법인세 계산구조 회계와 사회 결산서상 당기순이익
Department of Digital Contents Sang Il Park
제 15 장 픽킹.
Window socket programming
2018학년도 2학기 장기현장실습.
명품 Java Programming.
16. DLL.
MFC Application Frameworks (AFX)
제8장 스텐실.
군산대학교 부서통계 시스템 사용자 매뉴얼 Version v1.0 작성자 칸테크 작성일자
강사 : 이준근 Win32 API 강사 : 이준근
영상처리 시작하기 & 영상처리 프로그램 만들기
주소록 프로그램.
Visual Studio 2010 프로젝트 생성하기 PC화면에서 Visual Studio 2010 아이콘을 더블클릭 하거나
Windows Programming 시작하기
제주닷컴 매뉴얼 (실시간 예약시스템) 2013년 10월.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
2.1 재배정 재배정요구등록 재배정승인취소 재배정부서연결 재배정단위업무연결
Chapter 09. 소켓 입출력 모델(I).
Lab 4 보고서 교재 5장 사용자 인터페이스 예제 - 사용자 인터페이스 갱신
Direct X Demo 따라하기 Direct X Wizard를 이용하여 프로젝트를 생성한다
' Strategic Alliance Partner with '
GUI 소켓 애플리케이션 Chapter 08. * 학습목표 윈도우 GUI 애플리케이션의 구조와 동작 원리를 이해
WSAAsync Select 김대열 Bit - Academy Sunmoon University, Korea.
젖소HACCP프로그램 사용자설명서 (ver 1.0).
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Lab 9 Guide: 인터넷 프로그래밍 예제 * 일대일 채팅 프로그램 (교재 27장, 쪽)
업체등록신청절차 목차 메인화면 메세지별 유형 2-1. 이미 가입된 공급업체
DirectSound 프로그래밍 DirectSound를 사용하면 매우 짧은 지연 시간에 사운드를 재생해, 애플리케이션으로 하드웨어 리소스를 치밀하게 제어할 수 있다. DirectSound 인터페이스를 사용하여 다음과 같은 처리가 가능하게 된다. WAV 포맷의 파일 또는.
내장형 소프트웨어 -페인트 보드 만들기 발표자 : 백종인.
3장. 제어 메시지 처리하기 1/211 1.
JVM의 구조와 메모리 모델 JVM의 내부 구조 클래스 파일 클래스 로더 메소드(method) 영역 힙(heap) 영역
Windows 프로그래밍 환경 및 MFC의 구조
성립전예산 요구등록 (사업담당자) 사업관리카드 1 2
C# 10장. 참조형.
2015년 2학년 1반.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 08. 조건에 따른 흐름의 분기.
대한민국-스웨덴 수교 60주년 기념 행사 주 스웨덴 대한민국 대사관 (토)
게임과 1학년 Flipping - 파일을 읽어서 출력하는 프로그램
컴퓨터 계측 및 실습 C++ 기초 영남대학교 기계공학부.
청소년 댄스 경연대회 제35회 문화체육관광부장관大賞 전국레크리에이션대회
8단계 3층을 완성한다 Case 1 Case 2 Case 3 Case 4
맞춤형 사법서비스 구축 4단계 주요 변경업무 전자공탁
윈도우 운영체제와 윈도우 응용 프로그램의 특징 SDK 응용 프로그램 MFC 응용 프로그램
대관시스템 매뉴얼 : 대관회원가입 및 공연장 대관신청
Presentation transcript:

7장. MDI 프로그래밍 MDI 프로그래밍에 대한 내용을 배우도록 한다. 지금까지 배운 것은 생성된 윈도우에 단일 화면이 존재하는 형태였다. 이것을 SDI라고 부르고 Single Document Interface의 약자이다. 하나의 문서를 하나의 화면에 보여주는 형태의 프로그램이라는 뜻이다. 이제 복수개의 문서를 복수개의 화면에 출력하는 Multiple Document Interface 프로그래밍을 배울 것이다. SDI 프로그램의 종류로는 메모장이 있으며 MDI 프로그램의 종류로는 파워포인트나 엑셀 등이 여기에 속한다. 1/211 1

내용 MDI 기반 어플리케이션 차일드 윈도우 사용하기 차일드 윈도우 관리하기 2/211

MDI 기반 어플리케이션 MDI는 Multiple Document Interface의 약어로 윈도우 내에 여러 개의 문서 표현 가능 프레임 윈도우 클라이언트 윈도우 MDI는 Multiple Document Interface의 약어로 윈도우내에 복수개의 문서를 표현할 수 있는 프로그램의 형태를 말한다. 위의 예는 Adobe Reader이다. 이 프로그램은 복수개의 PDF파일을 Reader 윈도우 내에 표현할 수 있다. 이때 메인 윈도우 역할을 하는 큰 윈도우의 프레임을 프레임 윈도우라고 부른다. 프레임 윈도우에 속하는 영역은 윈도우의 타이틀바, 메뉴, 도구상자, 테두리 등이다. 프레임 윈도우내에 회색영역을 우리는 클라이언트 윈도우라고 부른다. 클라이언트 윈도우는 차일드 윈도우들의 부모역할을 한다. 내부에서 문서를 실제로 표현하는 작은 윈도우들을 차일드 윈도우라고 부른다. 차일드 윈도우 여러 개 가능 3/211 3

작성방법 리소스 편집 WinMain 함수 작성 메인 메뉴에 “창 관리” 메뉴항목 추가 메뉴에 차일드 윈도우 생성위한 “새문서” 메뉴항목 추가 WinMain 함수 작성 프레임 윈도우, 차일드 윈도우를 위한 윈도우 클래스 생성 두개의 윈도우 클래스 등록 프레임 윈도우 생성 클라이언트 윈도우 생성 코드 추가 MDI 프로그램을 작성하는 방법을 단계별로 알아보도록 한다. 일은 크게 4가지로 나눌 수 있다. 먼저는 리소스 편집, 두 번째는 WinMain함수 작성, 세 번째는 메인 메시지 처리 함수 WndProc 작성, 마지막으로 차일드 윈도우 메시지 처리함수 ChildWndProc 작성이다. 리소스 편집 메인 메뉴에 “창 관리” 메뉴항목을 추가해 준다. 이것은 메인 메뉴에 존재하는 Pop-up 메뉴 항목이다. 차일드 윈도우 생성을 위해 사용할 메뉴항목을 추가해 주는데 “파일”메뉴항목에 연결된 부메뉴에 “새문서” 메뉴항목을 추가해 준다. WinMain 함수 작성 WinMain함수 내에 프레임 윈도우와 차일드 윈도우를 위한 윈도우 클래스 변수들을 선언하고 각 변수의 필드에 값을 넣어주는 코드를 작성한다. 만들어진 윈도우 클래스 변수를 이용하여 2개의 윈도우 클래스를 등록한다. 프레임 윈도우를 생성한다. 클라이언트 윈도우를 생성하는 코드를 추가해 준다. 4/211 4

작성방법(계속) 3. WndProc 함수 작성 4. ChildWndProc 함수 작성 메시지 처리 부분에서 클라이언트 윈도우에게 차일드 윈도우 생성하도록 메시지 전송 4. ChildWndProc 함수 작성 차일드 윈도우 메시지 처리함수 작성 3. WndProc 함수 작성 메뉴에서 “새문서”메뉴항목을 선택했을 때 클라이언트 윈도우에게 차일드 윈도우를 생성하도록 메시지를 전송하는 코드를 작성한다. 4. ChildWndProc 함수 작성 차일드 윈도우에서 발생하는 메시지 처리하는 코드를 작성해 준다. 5/211 5

창관리 메뉴항목 추가 프로젝트에 생성된 메뉴 IDR_MENU1에 새로운 메뉴항목 “창 관리”를 만들어 준다. 이 메뉴항목은 Pop-up으로 만들고 나중에 부메뉴에 메뉴항목들을 추가할 것이다. 6/211 6

메뉴에 새문서 항목 추가 “파일”부메뉴에는 “새문서”메뉴항목을 만들어 준다. 이제 새문서를 선택하면 차일드 윈도우가 생성되도록 할 것이다. 7/211 7

윈도우 클래스 생성 및 등록 RegisterClassEx (&wndclass) ; WNDCLASSEX wndclass ; wndclass.cbSize = sizeof(wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = FrameWndProc; // ChildWndProc; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1) ; wndclass.lpszClassName = “Class Name”; // “Child Class Name”; wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION); RegisterClassEx (&wndclass) ; WinMain함수에 프레임을 위한 윈도우클래스와 차일드윈도우를 위한 윈도우 클래스를 만들어서 등록하여야 한다. 위의 코드는 프레임 윈도우를 위한 윈도우 클래스를 만들어서 등록하는 과정을 보여 주고 있다. 여기서 메시지 처리함수의 이름을 FrameWndProc라고 정했는데 이것은 지금까지 사용했던 WndProc와 동일한 것이다. 차일드 윈도우의 메시지 처리 함수 ChildWndProc와 분명하게 구분하기 위해 Frame을 붙여준 것이다. 클래스의 이름은 여기서 붙여준 것을 따르지 않아도 된다. 하지만 프레임 윈도우의 클래스이름과 차일드 윈도우의 클래스이름은 구분해 주어야 한다. 나머지 필드들은 프레임 윈도우나 차일드 윈도우가 동일한 값을 가진다. 8/211 8

어플리케이션 인스턴스 복사 WinMain()함수에서 넘겨받은 hInstance 값을 FrameWndProc()함수에서도 사용되기 때문에 전역변수를 이용하여 복사해줌 HINSTANCE hInst; hInst = hInstance; 어플리케이션 인스턴스인 hInstance값이 FrameWndProc에서 사용된다. 이를 위해 여기서는 HINSTANCE타입의 전역변수 hInst를 만들어 사용하고 있다. WinMain에서 전역변수 hInst에 hInstance를 복사한 후 FrameWndProc에서 hInst를 이용하면 된다. 만약 전역변수를 이용하기 싫다면 FrameWndProc함수내에 case WM_CREATE: 에서 ((LPCREATESTRUCT)lParam)->hInstance 의 값을 저장하여 사용하면 된다. 9/211 9

클라이언트 윈도우 생성 차일드 윈도우를 만들고 삭제하고 관리하는 윈도우로서 FrameWndProc의 WM_CREATE에서 생성함 static HWND hwndClient ; CLIENTCREATESTRUCT clientcreate ; switch (iMsg) { case WM_CREATE : clientcreate.hWindowMenu = GetSubMenu(GetMenu(hwnd),1); clientcreate.idFirstChild = 100 ; hwndClient = CreateWindow ("MDICLIENT", NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0, 0, 0, 0, hwnd, NULL, hInst,(LPSTR) &clientcreate) ; ShowWindow(hwndClient, SW_SHOW); 이제 클라이언트 윈도우를 프레임 윈도우에 만들어 주어야 한다. 클라이언트 윈도우를 만드는 시점은 윈도우가 생성될 때이다. 이를 위해 필요한 변수는 HWND타입 변수 hwndClient와 CLIENTCREATESTRUCT타입 변수 clientcreate이다. WM_CREATE메시지가 오면 clientcreate의 hWindowMenu 필드에 우리가 만든 메뉴의 두 번째 부메뉴를 저장한다. 이것은 두 번째 부메뉴 “창관리”에 생성되는 차일드 윈도우 문서 이름들을 연결할 것이기 때문이다. 이후에 보면 알겠지만 열린 문서의 이름인 차일드 윈도우의 타이틀명들이 “창관리”부메뉴에 메뉴항목으로 붙게 된다. 먼저 GetMenu(hwnd)를 통해 프레임 윈도우에 붙어있는 메뉴를 얻어온다. 그 다음 GetSubMenu를 통해 “창관리”부메뉴를 얻어온다. GetSubMenu는 메뉴의 부메뉴를 얻어오기 위한 함수로 숫자는 0부터 시작한다. idFirstChild필드는 추가되는 메뉴항목의 ID에 붙여줄 숫자로써 여기서 부여된 100부터 증가하며 붙여준다. 그 다음 CreateWindow함수를 이용해서 클라이언트 윈도우를 만들어준다. 클라이언트 윈도우의 클래스 이름은 MDICLIENT이다. 이것은 이미 등록 된 것이다. 다른 파라메터들에 대한 자세한 설명은 생략 하겠다. 클라이언트 윈도우를 만든 다음 ShowWindow를 이용하여 나타내면 프레임 윈도우에 클라이언트 윈도우가 나타나게 된다. 10/211 10

차일드 윈도우 생성 메시지 전송 메뉴에서 새문서를 선택했을때 차일드 윈도우 생성하는 코드를 FrameWndProc의 MW_COMMAND에 추가함 MDICREATESTRUCT mdicreate ; HWND hwndChild ; switch (iMsg) { case WM_COMMAND: switch(LOWORD(wParam)) { case ID_NEW: mdicreate.szClass = "Child Window Class Name" ; mdicreate.szTitle = "Child Window Title Name" ; mdicreate.hOwner = hInst ; mdicreate.x = CW_USEDEFAULT ; mdicreate.y = CW_USEDEFAULT ; mdicreate.cx = CW_USEDEFAULT ; mdicreate.cy = CW_USEDEFAULT ; mdicreate.style = 0 ; mdicreate.lParam = 0 ; hwndChild = (HWND) SendMessage (hwndClient, WM_MDICREATE, 0,(LPARAM) (LPMDICREATESTRUCT) &mdicreate) ; return 0 ; } break; 이제 메뉴에서 “새문서”를 선택했을 때 어떻게 차일드 윈도우가 만들어지는가를 설명하겠다. 차일드 윈도우를 만들기 위해서 MDICREATESTRUCT타입 변수 mdicreate와 HWND타입 변수 hwndChild가 필요하다. “새문서”를 선택하면 WM_COMMAND메시지가 도착한다. LOWORD(wParam)에는 ID_NEW가 저장되어 있을 것이다. 이때 mdicreate 변수에 차일드 윈도우를 만들기 위한 값들을 셋팅한다. szClass에는 사용할 차일드 윈도우 클래스 이름을 넣어주고, szTitle에는 등장할 차일드 윈도우의 타이틀명을 넣어준다. hOwner에는 차일드 윈도우의 주인이기 때문에 우리 프로그램의 어플리케이션 인스턴스인 전역변수 hInst를 넣어준다. 이 hInst에는 WinMain에서 hInstance값을 복사해서 가지고 있다. (x,y)는 윈도우가 나타날 위치좌표이고 cx, cy는 차일드 윈도우의 폭과 높이 값이다. 4개 변수에 모두 WM_USEDEFAULT를 넣어줬기 때문에 커널이 원하는 위치에 원하는 크기로 나타낸다. 이제 SendMessage 를 이용해서 클라이언트 윈도우에게 WM_MDICREATE 메시지를 보낸다. 이것은 클라이언트 윈도우에게 mdicreate의 내용을 가지고 차일드 윈도우를 만들라고 하는 메시지이다. 이렇게 하고 나면 차일드 윈도우가 클라이언트 영역에 나타나게 된다. 11/211 11

차일드 윈도우 메시지 처리함수 LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) case WM_CREATE: break; case WM_DESTROY: return 0; } return DefMDIChildProc (hwnd, iMsg, wParam, lParam); 마지막으로 차일드 윈도우에서 발생하는 메시지 처리 함수를 만들어 준다. 함수이름이 ChildWndProc일뿐 기존 WndProc와 별반 다를 바 없다. 단지 메시지를 처리하고 나서 마지막에 호출하는 함수가 DefWindowProc (hwnd, iMsg, wParam, lParam);이 아니고 DefMDIChildProc (hwnd, iMsg, wParam, lParam); 이라는 것만 다르다. 12/211 12

차일드 윈도우 관리하기 다음과 같이 메뉴항목을 변경 13/211 클라이언트 윈도우에 여러 개의 차일드 윈도우가 만들어지면 관리가 필요하다. 예를 들면, 정렬, 창닫기 등이 여기에 속한다. 이와 같은 차일드 윈도우 관리를 위해 여기서 메뉴항목들을 만들었다. 위의 그림과 같이 “창관리”부메뉴에 “바둑판식 정렬”, “계단식 정렬”, “아이콘정렬”, “창닫기”메뉴항목들을 만들어 준다. 각 메뉴항목에 대한 Caption과 ID는 위의 그림과 같이 설정해 준다. 13/211 13

차일드 윈도우 관리하기 다음과 같이 메뉴항목을 변경 14/211 14

메뉴항목에 대한 메시지 처리 case WM_COMMAND: switch(LOWORD(wParam)) { case ID_WINDOW_CLOSE : hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0) ; if (SendMessage (hwndChild, WM_QUERYENDSESSION,0,0)) SendMessage (hwndClient, WM_MDIDESTROY, (WPARAM) hwndChild, 0) ; return 0 ; case ID_TILE : SendMessage (hwndClient, WM_MDITILE, 0, 0) ; 이제 각 메뉴항목에 대한 메시지를 처리하는 코드를 작성해 준다. 먼저 “창닫기”에 대해 알아보도록 한다. “창닫기” 메뉴항목을 선택했다면 클라이언트 윈도우에서 Active상태에 있는 차일드 윈도우를 닫아준다. 여러 차일드 윈도우들중 Active상태인 것은 하나 뿐이다. “창닫기” 메뉴항목을 선택했기 때문에 LOWORD(wParam)의 값은 ID_CLOSE이다. 먼저 해야 할 일은 현재 Active상태에 있는 차일드 윈도우를 알아내는 것이다. 이것을 위해 클라이언트 윈도우 hwndClient에게 WM_MDIACTIVE메시지를 보내야 한다. 이때 반환되는 값이 Active 차일드 윈도우의 핸들 값이다. 그리고, 차일드 윈도우를 종료하기 위해 종료해도 가능한지 알아보기 위한 메시지 WM_QUERYENDSESSION를 보낸다. 종료해도 된다면 TRUE를 반환하기 때문에 이제 비로소 종료메시지인 WM_MDIDESTROY를 보낸다. 종료메시지는 클라이언트 윈도우에게 보낸다는 것을 명심해야 한다. 두 번째로 “바둑판식 정렬”메뉴항목을 선택했을 때를 알아보도록 한다. LOWORD(wParam)이 ID_TILE이기 때문에 위에서는 클라이언트 윈도우에게 WM_MDITITLE메시지를 보내고 있다. 이 메시지가 차일드 윈도우를 바둑판식으로 정렬하라는 메시지이다. 15/211 15

메뉴항목에 대한 메시지 처리 case ID_CASCADE : SendMessage (hwndClient, WM_MDICASCADE, 0, 0); return 0 ; case ID_ARRANGE : SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0); case ID_EXIT : PostQuitMessage (0); } break; “계단식 정렬”메뉴항목을 선택했다면 LOWORD(wParam)이 ID_CASCADE이고 클라이언트 윈도우에게 계단식으로 정렬하라는 메시지를 보내게 된다. 이 때 보내는 메시지는 WM_MDICASCADE이다. “아이콘정렬”은 차일드 윈도우가 아이콘 상태에 있을 때 아이콘들을 자동 정렬할 때 사용한다. 이를 위해 보내는 메시지는 WM_MDIICONARRANGE이다. 16/211 16

연습문제 1 실습제목 차일드 윈도우들의 타이틀 이름 다양화 실습내용 앞에 있는 실습에서 차일드 윈도우의 타이틀명을 다음과 같이 다양하게 하시오. 앞의 예제에서는 차일드 윈도우의 타이틀 이름이 동일하였다. 이제 차일드 윈도우마다 붙여지는 타이틀 이름을 달리하는 실습을 수행한다. 메뉴에서 “새파일” 메뉴항목을 반복적으로 선택하면 차일드 윈도우가 계속 만들어지는데 차일드 윈도우의 이름을 “%d번 Child Window”라고 붙여준다. %d에는 숫자를 1부터 시작하여 붙여준다. 17/211 17

연습문제 2 실습제목 MDI를 활용한 메모장 실습내용 이전에 만들었던 10줄 메모장을 MDI버전으로 확장하시오. 18/211 이제 MDI를 활용한 메모장 프로그램을 작성해 보겠다. 물론, 실제 메모장보다는 기능상으로 부족하지만 10줄 짜리 글을 입력하고 편집할 수 있는 메모장이다. “새문서” 메뉴항목을 선택하면 새로운 차일드 윈도우가 뜨고 거기에 10줄짜리 글을 입력 및 편집할 수 있어야 한다. 2장에서 10줄짜리 메모장을 만들었던 것을 기억할 것이다. 그 코드의 WndProc에 있는 부분들을 본 프로그램의 ChildWndProc에 넣어주면 된다. 18/211 18