Download presentation
Presentation is loading. Please wait.
1
Windows 프로그래밍 환경 및 MFC의 구조
2
강의 내용 Stack과 Heap의 원리 (1부) Windows 프로그래밍 환경 (API) MFC의 구조
3
Heap과 Stack 변수 할당의 두 가지 형태 void function() { int * pa; pa = new int();
왼쪽의 경우 변수 a가 유효한 범위는 중괄호 {…} 내부이며 메모리 내에서 제거하기 위한 별도의 조처가 필요하지 않음 (실제로 }를 만나면 자동으로 메모리에서 제거됨) -> STACK에 메모리 존재 오른쪽의 경우는 실행되는 부분이 중괄호 {…}를 벗어 나는 경우에도 delete() 함수를 만나기 전까지는 계속 메모리에 그 내용이 유지됨 -> HEAP에 메모리 존재 void function() { int * pa; pa = new int(); (*pa) = 100; . delete(pa); } void function() { int a; a = 100; . }
4
Stack의 구조 스택은 위에서부터만 자료를 쌓을 수 있고 가장 위에 있는 자료만 꺼내 볼 수 있는 구조
OS에서 프로세스(Process)가 생성되면 각 프로세스 당 내부 스택이 하나 씩 할당됨 이 스택은 1) 함수 호출 2) 자동 변수 (=지역(local) 변수) 할당 및 이용을 위해 편리하게 활용됨
5
Stack의 원리 (1부) 다음과 같은 코드가 있다면… 실행될 때…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k;
6
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; main()
7
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; a=100 main()
8
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; b=20 a=100 main()
9
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; c = add(20, 100) b=20 a=100 main()
10
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; c=add(20, 100) b=20 a=100 main()
11
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; result = 0 c=add(20, 100) b=20 a=100 main()
12
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; y= 100 x= 20 result = 0 c=add(20, 100) b=20 a=100 main()
13
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; y= 100 x= 20 result = 120 c=add(20, 100) b=20 a=100 main()
14
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; y= 100 x= 20 result = 120 c=add(20, 100)=120 b=20 a=100 main()
15
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; y= 100 x= 20 result = 120 c=add(20, 100)=120 b=20 a=100 main() 설명: 호출된 함수에서 마지막 } 괄호 부분을 만나면 스택에서 해당 함수가 호출된 부분(즉, 시작 부분)까지 pop (제거)
16
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; c=add(20, 100)=120 b=20 a=100 main()
17
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; d=sub(120, 100) c=add(20, 100)=120 b=20 a=100 main()
18
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; d=sub(120, 100) c=add(20, 100)=120 b=20 a=100 main()
19
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; k = ?? d=sub(120, 100) c=add(20, 100)=120 b=20 a=100 main()
20
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; s = 120 t = 100 k = ?? d=sub(120, 100) c=add(20, 100)=120 b=20 a=100 main()
21
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; s = 120 t = 100 k = =20 d=sub(120, 100) c=add(20, 100)=120 b=20 a=100 main()
22
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; s = 120 t = 100 k = =20 d=sub(120, 100)=20 c=add(20, 100)=120 b=20 a=100 main()
23
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; s = 120 t = 100 k = =20 d=sub(120, 100)=20 c=add(20, 100)=120 b=20 a=100 main()
24
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; d=sub(120, 100)=20 c=add(20, 100)=120 b=20 a=100 main()
25
Stack의 원리 다음과 같은 코드가 있다면… 화살표는 실행되는 행을 표시…. void main()
{ int a; int b; int c; int d; a = 100; b = 20; c = add(a, b); d = sub(c-a); } int add(int x, int y) { int result = 0; result = x + y; return result; } int sub(int s, int t) int k; k = s – t; return k; d=sub(120, 100)=20 c=add(20, 100)=120 b=20 a=100 main()
26
Stack의 원리 정리 1부 이야기 중괄호 {…} 내부에서 정의되는 지역 (자동) 변수 (=포인터 변수가 아닌 변수)의 경우 스택 공간을 메모리로 이용하기 때문에 중괄호가 끝나는 즉시 자동으로 제거 따라서 별도의 메모리 관리(garbage collection = 쓰레기 정리)가 필요하지 않음 2부 예고 이에 비해 new를 이용해서 메모리를 별도로 할당하면 스택 이외의 힙(heap) 공간에 메모리 할당 이 경우 반드시 delete를 이용해서 삭제하지 않으면 해당 공간에는 의미 없는 자료가 남게 되며 동시에 실행되는 다른 프로그램이 사용하지 못하는 문제 발생
27
Stack과 Heap의 원리 (2부) 다음 시간에 계속…
28
이벤트와 이벤트 핸들러 이벤트 발생 대기 ... 시스템 메시지 대기열 메시지 대기열 #3 메시지 대기열 #2 처리
응용 프로그램 메시지 대기열 #1 메시지 대기열 #2 메시지 대기열 #3 ... 처리 대기
29
Windows 프로그래밍의 기본 구조
30
VC++ IDE (통합 개발 환경) 시스템의 구성 요소 개발 과정 단순화를 위한 기타 도구 Editor Compiler
Source code 작성 Compile, editing, debuging 등의 interactive 환경 제공 Compiler Compile : Source code machine language Error and warning detecting and notifying Output : object code (.obj) Linker Link : module merging + program libraries Linking error detecting and notifying Library Standard library MFC&T(Microsoft Foundation Classes and Templates) 개발 과정 단순화를 위한 기타 도구 AppWizard : Windows 프로그램의 기본적인 프레임웍 자동 생성 ClassWizard : AppWizard에 의해 생성된 클래스 확장 용이성 제공
31
VC++ IDE 구조
32
윈도우 응용 프로그램 개발 도구 (1/3) API(Application Programming Interface) 기반 장점
운영체제가 응용 프로그램을 위해 제공하는 각종 함수의 집합 장점 세부적인 제어가 가능하고, 윈도우 운영체제가 제공하는 모든 기능을 사용할 수 있다. 생성 코드의 크기가 작고 속도가 빠르다. 단점 생산성이 낮다.
33
윈도우 응용 프로그램 개발 도구 (2/3) RAD(Rapid Application Development) 장점 단점
시각적으로 화면을 디자인하고 코드를 추가하는 방법으로 프로그램을 빠르게 개발 Visual Basic, Delphi 등 장점 생산성이 높다. 단점 일반적으로 생성 코드의 크기가 크고 실행 속도가 느리다. 운영체제가 제공하는 모든 기능을 활용한 세부적인 제어가 어렵다.
34
윈도우 응용 프로그램 개발 도구 (3/3) MFC (Microsoft Foundation Class Library) 기반 장점
API 중 많이 사용되는 기능들을 사용하기 쉽게 잘 포장해 놓은 것 객체 지향 언어를 이용하여 클래스로 제공 장점 API 직접 이용 보다 생산성이 높다. RAD보다 생성 코드의 크기가 작고 실행 속도가 빠르다. 단점 초기 학습에 필요한 기간이 길다. 객체 지향 언어 클래스 라이브러리 구조와 기능, 각 클래스의 관계 파악
35
Win32 Program의 구조
36
Win32 ? (= Windows API) 프로그래밍의 과정은 無에서 시작하지 않고 다른 사람들이 잘 만들어놓은 확장된 기능들을 이용하여 원하는 기능을 구현한다. 확장된 기능(데이터타입, 구조체, 함수들)을 모아놓은 것을 library라고 한다. EX.) 그림을 화면에 표시하기 위한 함수들 (Library) 소리를 내기 위한 함수들(Library) API Win32 윈도우에서 돌아가는 프로그램을 만들기 위한 기능들을 모아놓은 가장 기본적인 library Ex.) 창만들기, 버튼 달기, 메뉴만들기 등…
37
Win32 ? ( = Windows API) API (Application Programming Interface) Win32
운영체제 등을 제어하기 위한 기능들을 모아놓은 Library의 일종 주로 C 함수의 형태로 되어 있음. Win32 Windows용 API의 이름 즉, 윈도우에서 돌아가는 프로그램을 만들기 위한 기능들을 모아놓은 가장 기본적인 library Ex.) 창만들기, 버튼 달기, 메뉴만들기 등…
38
Win32 Project 만들어 보기 FileNewProject Win32 Project 선택
39
실행결과
40
Code…. // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
// PURPOSE: Processes messages for the main window. // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) case IDM_ABOUT: // MessageBox(hWnd, _T("haha"), _T("about"), MB_OK); DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); default: return DefWindowProc(hWnd, message, wParam, lParam); } case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... RECT rect; GetClientRect(hWnd, &rect); DrawText(hdc, _T("hello, Windows"), -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER); EndPaint(hWnd, &ps); case WM_DESTROY: PostQuitMessage(0); return 0; // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) UNREFERENCED_PARAMETER(lParam); case WM_INITDIALOG: return (INT_PTR)TRUE; if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)FALSE; // // FUNCTION: MyRegisterClass() // PURPOSE: Registers the window class. // COMMENTS: // This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTWIN32)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TESTWIN32); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // FUNCTION: InitInstance(HINSTANCE, int) // PURPOSE: Saves instance handle and creates main window // COMMENTS: // In this function, we save the instance handle in a global variable and // create and display the main program window. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; // testWin32.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "testWin32.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_TESTWIN32, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTWIN32)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) TranslateMessage(&msg); DispatchMessage(&msg); return (int) msg.wParam;
41
Code in short BOOL InitInstance(…) { hWnd = CreateWindow(…);
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(…) switch (message) case WM_COMMAND: break; case WM_PAINT: case WM_DESTROY: PostQuitMessage(0); default: return; return 0; int APIENTRY _tWinMain(…) { // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) return FALSE; } // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) if (!TranslateAccelerator(…)) TranslateMessage(&msg); DispatchMessage(&msg); return (int) msg.wParam;
42
Code in short BOOL InitInstance(…) { hWnd = CreateWindow(…);
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(…) switch (message) case WM_COMMAND: break; case WM_PAINT: case WM_DESTROY: PostQuitMessage(0); default: return; return 0; int APIENTRY _tWinMain(…) { // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) return FALSE; } // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) if (!TranslateAccelerator(…)) TranslateMessage(&msg); DispatchMessage(&msg); return (int) msg.wParam;
43
Win32 프로그램 구조 WinMain(…) main 함수 {
InitInstance(…) 초기화 (틀을 만들고 보여줌) while( GetMessage (…)) 메시지 루프 DispatchMessage(…) 메세지처리(WinProc) }
44
MFC ?
45
윈도우 응용 프로그램 개발 도구 (1/3) API(Application Programming Interface) 기반 장점
운영체제가 응용 프로그램을 위해 제공하는 각종 함수의 집합 장점 세부적인 제어가 가능하고, 윈도우 운영체제가 제공하는 모든 기능을 사용할 수 있다. 생성 코드의 크기가 작고 속도가 빠르다. 단점 생산성이 낮다.
46
윈도우 응용 프로그램 개발 도구 (2/3) RAD(Rapid Application Development) 장점 단점
시각적으로 화면을 디자인하고 코드를 추가하는 방법으로 프로그램을 빠르게 개발 Visual Basic, Delphi 등 장점 생산성이 높다. 단점 일반적으로 생성 코드의 크기가 크고 실행 속도가 느리다. 운영체제가 제공하는 모든 기능을 활용한 세부적인 제어가 어렵다.
47
윈도우 응용 프로그램 개발 도구 (3/3) MFC (Microsoft Foundation Class Library) 기반 장점
API 중 많이 사용되는 기능들을 사용하기 쉽게 잘 포장해 놓은 것 객체 지향 언어를 이용하여 클래스로 제공 장점 API 직접 이용 보다 생산성이 높다. RAD보다 생성 코드의 크기가 작고 실행 속도가 빠르다. 단점 초기 학습에 필요한 기간이 길다. 객체 지향 언어 클래스 라이브러리 구조와 기능, 각 클래스의 관계 파악
48
정리 - Application Wizard
AppWizard 기능 만들고자 하는 기본적인 프로젝트를 생성 해주고 그 안에 필요한 클래스 생성 클래스에 기본적인 내용을 코딩 기본적인 코딩시간을 절약 하므로 빠른 프로젝트 완성 AppWizard사용 도중 실수로 옵션을 선택하지 않았을 경우 소스에서 새로 추가할 수 있다.
49
정리 - Project Workspace 프로젝트 워크스페이스의 구성 MFC 클래스를 상속 받아 탄생된 새로운 클래스
클래스 소스가 설정되어 있는 파일들 소스파일 cpp 헤더 파일 h 프로그램에 필요한 메뉴, 아이콘, 문자열, 대화상자 같은 자원
50
정리 - Project Workspace 프로젝트 워크스페이스의 항목별 설명 프로젝트에 설정되어 있는 클래스별로 출력,
해당 항목을 선택하면 수정 가능 ClassView 프로젝트에 설정되어 있는 파일 리스트 출력, 해당 항목을 선택하여 수정 가능 Solution Explore (=FileView) 프로젝트에 설정되어 있는 메뉴, 대화 상자, 문자열, 아이콘, 비트맵 등 자원의 리스트 출력, 해당 항목 선택 수정 가능 ResourceView 내 용 항 목
51
정리 - Project Workspace Class View 화면
해당 항목을 더블 클릭하면 클래스 헤더가 나타나고 우측 버튼을 클릭하면 해당 클래스에 함수나 변수, 이벤트를 설정하도록 메뉴 등장 해당 클래스의 멤버 함수와 멤버 변수의 리스트 +버튼을 클릭한 상태에서 해당 항목(변수)을 클릭하면 해당 항목이 설정되어 있는 소스 파일로 이동 protected 형태로 설정되어 있을 경우(열쇠) protected 형태로 설정되어 있지 않을 경우는 열쇠 아이콘이 나타나지 않음
52
정리 - Project Workspace Resource View 화면
엑셀레이터(핫키 정의) 키값을 정의하는 항목 대화 상자(어떤 형태의 대화 상자의 출력할 폼을 만들어서 저장) 자원들 아이콘 자원 메뉴 자원 문자열 테이블 툴바
53
정리 - Project Workspace 솔루션 탐색기(File View) 화면 소스 파일 헤더 파일 자원 파일
54
VC++ Framework CFrameWnd CChildView 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우
CWinApp : 위의 두 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림
55
프로그램 내부 구조 theApp (CSimpleApp : CWinApp) m_pMainFrame
(CMainFrame : CFrameWnd) m_wndView (CChildView : CWnd)
56
응용 프로그램 실행순서 CSimpleApp theApp; WinMain() // MFC 내부에 숨겨짐 {
theApp.InitInstance(); // 초기화 theApp.Run(); // 메시지 루프 theApp.ExitInstance(); // 종료 }
57
응용 프로그램 클래스 (1/4) // Simple.h class CSimpleApp : public CWinApp {
virtual BOOL InitInstance(); afx_msg void OnAppAbout(); DECLARE_MESSAGE_MAP() };
58
응용 프로그램 클래스 (2/4) MFC 기본 header file을 모아놓음 #include "stdafx.h"
#include "simple.h" #include "MainFrm.h“ // Simple.cpp BEGIN_MESSAGE_MAP(CSimpleApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) END_MESSAGE_MAP() CSimpleApp::CSimpleApp() { } CSimpleApp theApp; MFC 기본 header file을 모아놓음 // 응용프로그램 자신에 해당하는 전역객체
59
응용 프로그램 클래스 (3/4) BOOL CSimpleApp::InitInstance() {
SetRegistryKey(_T("Local AppWizard-Generated Applications")); CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; }
60
응용 프로그램 클래스 (3/4) BOOL CSimpleApp::InitInstance() {
SetRegistryKey(_T("Local AppWizard-Generated Applications")); CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; } 60
61
응용 프로그램 실행순서 CSimpleApp theApp; WinMain() // MFC 내부에 숨겨짐 {
theApp.InitInstance(); // 초기화 theApp.Run(); // 메시지 루프 theApp.ExitInstance(); // 종료 }
62
응용 프로그램 클래스 (4/4) // 대화상자 관련 클래스 선언 및 정의 부분 - 생략 // ...
void CSimpleApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); }
63
VC++ Framework CFrameWnd CChildView 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우
CWinApp : 위의 두 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림
64
프레임 윈도우 클래스 (1/5) // MainFrm.h class CMainFrame : public CFrameWnd {
protected: DECLARE_DYNAMIC(CMainFrame) virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); virtual ~CMainFrame(); CChildView m_wndView; afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSetFocus(CWnd *pOldWnd); DECLARE_MESSAGE_MAP() };
65
프레임 윈도우 클래스 (2/5) // MainFrm.cpp
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_WM_SETFOCUS() END_MESSAGE_MAP() CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame()
66
프레임 윈도우 클래스 (3/5) int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) TRACE0("Failed to create view window\n"); } return 0;
67
프레임 윈도우 클래스 (4/5) BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.dwExStyle &= ~WS_EX_CLIENTEDGE; cs.lpszClass = AfxRegisterWndClass(0); return TRUE; }
68
프레임 윈도우 클래스 (4/5) struct CREATESTRUCT{ LPVOID lpCreateParams;
HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCTSTR lpszName; LPCTSTR lpszClass; DWORD dwExStyle; }; 68
69
프레임 윈도우 클래스 (5/5) void CMainFrame::OnSetFocus(CWnd* pOldWnd) {
m_wndView.SetFocus(); } BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
70
VC++ Framework CFrameWnd CChildView 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우
CWinApp : 위의 두 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림
71
뷰 클래스 (1/4) // ChildView.h class CChildView : public CWnd { public:
protected: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual ~CChildView(); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() };
72
뷰 클래스 (2/4) // ChildView.cpp CChildView::CChildView() { }
BEGIN_MESSAGE_MAP(CChildView,CWnd ) ON_WM_PAINT() END_MESSAGE_MAP()
73
뷰 클래스 (3/4) BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) {
if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE; cs.style &= ~WS_BORDER; cs.lpszClass = AfxRegisterWndClass ( CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); return TRUE; } Style: ExStyle: System Color:
74
뷰 클래스 (4/4) void CChildView::OnPaint() { CPaintDC dc(this);
dc.TextOut(100, 100, _T("안녕하세요.“)); }
75
요약 클래스 종류 베이스 클래스 이름 핵심 함수 - 주 역할 응용 프로그램 CWinApp
InitInstance() - 프레임 윈도우를 생성한다. Run() - 메시지 루프를 제공한다. 프레임 윈도우 CFrameWnd OnCreate() - 뷰를 생성한다. 뷰 CWnd OnPaint() - 화면에 출력한다.
76
MFC 주요 특징 (1/3) 윈도우 응용 프로그램을 작성하는데 드는 수고를 크게 덜어준다.
라이브러리 재사용 AppWizard, ClassWizard API를 기반으로 프로그램과 대등한 속도를 가진다. 인라인 함수의 활용 코드 크기 증가를 최소화한다. 동적 라이브러리 활용
77
MFC 주요 특징 (2/3) API 프로그래밍에 대한 기반 지식을 재활용할 수 있다. API 함수를 직접 호출할 수 있다.
(예) ReleaseCapture(); C++ 언어를 이용하여 기존의 C 언어에 비해 API를 좀더 편하게 사용할 수 있다. (예) 오버로딩 및 디폴트 인자
78
MFC 주요 특징 (3/3) API를 직접 사용해서 구현할 경우 복잡도가 높은 부분을 MFC를 이용하면 쉽게 구현할 수 있다.
인쇄 기능 지원, 툴바와 상태바 처리, 데이터베이스 지원, OLE와 액티브X, ...
79
MFC 구성 요소 (1/2) 구성 요소 CObject 파생 클래스: 188개 MFC 클래스 나머지: 40개
매크로와 전역 변수 및 전역 함수
80
MFC 구성 요소 (2/2) MFC클래스의 기본 구조 MFC의 계층적 구조 형태 CObject CCmdTarget CWnd
CWinThread CDocument 기타 CWinApp ► CMainFrame 과 Cview클래스는 CWnd에서 상속받음
81
MFC Application Architecture
CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp CObject 클래스 (최상위 클래스) 메모리에 클래스를 설정하는 기능 클래스를 할당하기 위한 new연산자가 오버로딩 클래스의 기능과 종류를 알 수 있는 함수가 있음 CObject MFC class1 MFC class3 MFC class2
82
MFC Application Architecture
CObject 의 기본 기능 서비스 이름 기능 실행 시간 클래스 정보 프로그램 실행 중 객체 정보를 알아낸다. 동적 객체 생성 객체를 동적으로 생성한다. 직렬화 (serialize) 객체를 저장하거나 읽어 들인다. 타당성 점검 객체 상태를 점검한다. 집합 클래스와의 호환성 서로 다른 클래스 객체를 집합 클래스에 저장할 수 있도록 한다.
83
MFC Application Architecture
CObject 포인터를 저장할 수 있는 MFC가 제공하는 집합 클래스 종류 클래스 이름 배열 CObArray, CArray(템플릿 클래스) 리스트 CObList, CList(템플릿 클래스) 맵 CMapWordToOb, CMapStringToOb, CMap(템플릿 클래스)
84
MFC Application Architecture
CCmdTarget클래스 메시지 전송 및 처리를 담당하는 클래스들의 기본 클래스 예) Cview, CWinApp, Cdocument, CWnd, CFrameWnd CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp 윈도우 시스템 Application 이벤트 발생 메시지 전송 메시지 처리 화면에 출력
85
MFC Application Architecture
CWnd클래스 화면에 보이는 윈도들은 모두 CWnd 에서 상속 받음 가장 많이 사용되는 클래스 윈도우의 최상위 클래스 주로 CWnd에서 상속된 다른 클래스(예: CView 등)를 사용 윈도우를 구동하는 모든 기능을 가진 함수가 있다. Initialization Window State Functions Window Size and position Coordinate Mapping Functions Window Message Functions …….. CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp
86
CWnd를 상속 받은 클래스들 CWnd CFrameWnd 프레임 형태의 윈도우 CControlBar 컨트롤 바
CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp CWnd CFrameWnd 프레임 형태의 윈도우 CControlBar 컨트롤 바 CPropertySheet 프로퍼티 시트 CDialog 대화 상자 CView View 윈도우 Control class 컨트롤 들
87
MFC Application Architecture
CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp CWndThread 클래스 윈도우가 스레드로 돌아갈 수 있도록 구동 되는 클래스 스레드는 독립적인 형태로 구동 되는 하나의 모듈 한 개의 프로그램을 독립적으로 움직이려면 한 개의 프로그램은 한 개 이상의 CWinThread를 포함해야 한다 Multi-tasking이 가능 CWndApp 클래스 한 개의 프로그램을 포함하고 관장하는 클래스
88
MFC Application Architecture
CDocument 클래스 데이터를 디스크에서 읽어 들이거나 디스크에 저장하는 부분을 담당하는 클래스 나중에 다른 프로그램에서 재사용이 용이 CObject CCmdTarget CWnd CWinThread CDocument 기타 CWinApp
89
VC++ Framework CFrameWnd CView CDocument CMainFrame CProgramView
CProgramDoc 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우 데이터를 저장, 처리 (눈에 안보임) CWinApp : 위의 세 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림 CProgramApp
90
CWinApp 클래스 윈도우 프로그램의 동작 방식 윈도우 프로그램은 사용자가 취하는 동작에 반응하여, 해당 기능을 수행
평상시에는 아무 동작을 하지 않음 마우스를 클릭하였을 경우 특정 작업 수행 키보드가 눌려졌을 경우 특정 작업 수행 메시지 구동 방식을 취함 윈도우 운영체제는 사용자의 모든 동작을 감지하여 메시지 형태로 프로그램에 전달 사용자가 키보드를 누르면 어떤 키보드가 눌렸다는 메시지 마우스를 움직이면 어느 좌표에서 마우스가 움직였다는 메시지 메뉴나 버튼이 눌려지면 어떠한 메뉴나 버튼이 눌렸다는 메시지
91
메시지와 메시지 핸들러의 예 마우스의 왼쪽 버튼 클릭 메시지 박스 Popup
92
CView에 메시지 헨들러 추가하기
93
추가된 메시지 핸들러
94
추가된 메시지 핸들러 편집
95
연습 마우스 오른쪽 버튼 클릭 메시지 박스 Popup
96
MFC 구성 요소 구성 요소 CObject 파생 클래스: 188개 MFC 클래스 나머지: 40개 (※MFC 6.0 기준)
매크로와 전역 변수 및 전역 함수
97
MFC 전역 함수 함수 이름 기능 AfxMessageBox() 메시지 상자를 표시한다. AfxGetApp()
응용 프로그램 객체의 주소를 리턴한다. AfxGetMainWnd() 메인 윈도우 객체의 주소를 리턴한다. AfxGetAppName() 응용 프로그램의 이름을 리턴한다. AfxGetInstanceHandle() 인스턴스 핸들을 리턴한다. AfxBeginThread() 스레드를 시작한다. AfxEndThread() 스레드를 종료한다. 함수 이름 기능 AfxMessageBox() 메시지 상자를 표시한다. AfxGetApp() 응용 프로그램 객체의 주소를 리턴한다. AfxGetMainWnd() 메인 윈도우 객체의 주소를 리턴한다. AfxGetAppName() 응용 프로그램의 이름을 리턴한다. AfxGetInstanceHandle() 인스턴스 핸들을 리턴한다. AfxBeginThread() 스레드를 시작한다. AfxEndThread() 스레드를 종료한다.
98
AfxMessageBox() 사용 예 void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) { AfxMessageBox("마우스를 클릭했습니다."); }
99
매크로 단계 매크로 이름 사용 목적 사용 위치 1 DECLARE_DYNAMIC 실행 시간 클래스 정보 클래스 선언부 (*.H)
IMPLEMENT_DYNAMIC 클래스 정의부 (*.CPP) 2 DECLARE_DYNCREATE 실행 시간 클래스 정보, 동적 객체 생성 IMPLEMENT_DYNCREATE 3 DECLARE_SERIAL 동적 객체 생성, 직렬화 IMPLEMENT_SERIAL
Similar presentations