본문 바로가기
C & C++/C & C++

[MFC] 기본 이론

by izen8 2011. 4. 25.
반응형

@ 윈도우 응용 프로그램의 특징
 

1. GUI

 

2. 메시지 구동 방식

- 프로그램 제어를 OS와 분담하여 처리

- OS : 이벤트 감지후 해당 프로그램에 message 전달

- Event-Driven 방식 ( event : 사용자의 물리적 조작에 의해 발생)

 이벤트 발생 -> 운영체제 감지 -> 메시지 전달

 

* 이벤트가 발생하면 운영체제가 이를 감지해 시스템 메시지 대기열에 들어간뒤

해당하는 응용 프로그램 메시지 대기열로 dispatch되서 처리된다.

 

* 메시지 전달

- 부가정보 포함 : 이벤트가 일어난 프로그램등

- 구조체로 정의됨

 

* 프로그래머는 초기화와 이벤트 핸들링만 해주면 된다. (나머지는 자동으로 됨)


                        
                        < Message Driven Architecture (메시지 구동구조) >


- SDI (single document interface) (ex) 메모장, 익스플로어

- MDI (multiple document interface) (ex) 엑셀, 비쥬얼

- Dialog Based (ex) 계산기, 지뢰찾기 형태


헝거리언 표기법

, 소문자를 혼용하여 변수의 의미와 데이터 타입을 알 수 있도록 표기.

 접두어(Prefix)

 데이터 타입

 접두어(Prefix)

  데이터 타입

a
b
ch
cb

dw

h

u

clr

배열(Array)
BOOL
문자
(Character)
바이트 개수

(Count of byte)
unsigned long
(DWORD)
핸들(Handle)

unsigned int

COLORREF

i
l
p, lp
n
sz

w

 

str

인덱스(Index)
long int
long(far) pointer
int
NULL
로 끝나는 문자열


unsigned int
(WORD)

CString형 변수

 

메시지나 스타일 등을 나타내는 매크로 상수들은 접두어를 이용하여 의미전달을 한다.
  [
메시지(Message)]

 접두어(Prefix)

 의미

BM_

CB_

DM_

EM_

LB_

WM_

버튼 메시지
콤보 박스 메시지
다이얼로그 메시지
에디트 컨트롤 메시지
리스트 박스 메시지
윈도우 메시지 

 

[스타일(Style)]

 접두어(Prefix)

 의미

BS_
CBS_
DS_
ES_
LBS_
WS_ 

버튼 스타일
콤보 박스 스타일
다이얼로그 스타일
에디트 컨트롤 스타일
리스트 박스 스타일
윈도우 스타일 

 

데이터 타입을 요약하면 다음과 같습니다.

데이터 타입

의미

데이터 타입

의미

BOOL
BYTE
COLORREF

DWORD
HANDLE
HBITMAP
HBRUSH
HCURSOR

HDC
HFILE

LONGLONG

ULONGLONG

TCHAR

WORD

 

CPoint

 

CSize

 

논리형(TRUE, FALSE)
8비트 unsigned형 정수

색상을 표현하는 32비트
데이터형
더블워드(32비트)
객체에 대한 핸들

비트맵에 대한 핸들
브러시에 대한 핸들
커서에 대한 핸들

디바이스 컨텍스트 핸들
파일에 대한 핸들

64비트 부호 있는 정수

64비트 부호 없는 정수

유니코드 또는 윈도우 문자

16비트 수형

 

2차원 좌표 계의 점

멤버변수(x,y)

가로와 세로 길이

멤버변수(cx, cy)

HFONT
HICON
HINSTANCE

HPEN
HWND
LPARAM
LPSTR

LPCSTR

LPTSTR

LPCTSTR
LRESULT

UINT
WPARAM

 

 

CRect

 

CString

POSITION

폰트에 대한 핸들
아이콘에 대한 핸들
인스턴스에 대한 핸들

펜에 대한 핸들
윈도우에 대한 핸들
32
비트 메시지 파라미터
문자열에 대한 포인터(널로 끝남)
문자열 상수에 대한 포인터

유니코드 또는 윈도우 문자열의 포인터

유니코드 또는 윈도우 문자열 상수의 포인터

메시지 처리에 대한 결과를 나타내
32비트 정수
32
비트 unsigned형 정수
32
비트 메시지 파라미터

 

 

사각형의 좌측 상단과 우측 하단의 좌표

멤버(left, top, right, bottom)

문자열 저장 기능

리스트에 저장된 항목을 가리키는 포인터

 


2. MFC의 구성요소

1. CObject 클래스로부터 상속 받은 클래스

대다수의 클래스들은 CObject 클래스로부터 상속을 받습니다.

따라서 이러한 클래스들은 CObject *로 전부 주소를 대입할 수 있습니다.

 

2. CObject 클래스로부터 상속 받지 않은 클래스

이러한 클래스들은 특별한 기능을 하는 클래스인 경우가 많습니다.

 

3. 전역함수(Afx로 시작)와 매크로(함수의 옵션)

Ex) int AfxMessageBox(LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0)

모든 클래스들에서 이용해야 하는 함수인 경우가 많으므로 중요합니다.

 

4. API 함수

MFC API 함수들을 비슷한 기능을 하는 함수들끼리 그룹별로 묶어서 클래스를 구현한 경우가 많으므로 이들 사이의 관계를 알아두고 활용할 수 있어야 합니다.


 

3. MFC의 클래스 계층도

4. MFC 프로젝트

MFC AppWizard를 이용한 프로젝트 생성 절차

[파일] – [새로 만들기] – [프로젝트] – Visual C++MFC 탭에서 [MFC 응용 프로그램]을 선택

프로젝트 명(TestMFC)

응용 프로그램 종류

Single Document(단일 문서): 프레임 윈도우가 하나 인 경우(SDI)

Multiple document(다중 문서): 프레임 윈도우가 여러 개 인 경우(MDI)

Dialog based(대화 상자 기반): 대화상자 프로그램

 

프로젝트스타일: 윈도우의 모양을 결정

탐색기 또는 표준 스타일

 

MFC 사용 – Dll을 포함해서 프로젝트를 생성할 것인지 여부

공유 DLL에서 MFC사용 – MFC로 시작하는 DLL파일이 설치되어 있어야 함

정적 라이브러리에서 MFC 사용 – DLL 파일이 없어도 실행되지만 프로그램의 부피가 커짐

Document/View architecture support(문서/뷰 아키텍쳐 지원)?

데이터부분과 뷰 부분을 분리하는 기능을 지원할 것인지를 설정

 

언어 선택과 유니코드 사용여부 선택

 

2단계: 복합 문서지원

없음

OLE를 지원하지 않는 어플리케이션을 생성

컨테이너

OLE를 컨테이너 어플리케이션을 생성

미니 서버

OLE복합문서를 생성하고 관리하는 OLE서버 어플리케이션을 생성.

, 독립적으로 실행이 되지 않음

(컨테이너 프로그램 내에서만 수행)

풀 서버

OLE복합문서를 생성하고 관리하는 OLE서버 어플리케이션을 생성. Mini-server와 달리 독립적으로 실행

컨테이너/풀 서버

OLE 컨테이너와 서버역할을 동시에 하는 어플리케이션을 생성.

**ActiveX document server**
ActiveX문서를 생성하는 서버 어플리케이션을 생성.  어플리케이션에서 생성된 문서는 인터넷 익스플로러 3.0이상 버전에서 In-place활성화가 됨.

 Visual C++ MFC - chapter 1.MFC 시작

 

 

 

 

3단계

파일의 확장자를 설정할 수 있고 제목표시줄에 보이는 텍스트 설정

4단계

데이터베이스 설정 기능

5단계: 윈도우 프레임의 모양

6단계: 고급 기능 설정

7단계: 기본적인 클래스의 이름을 정의하고 View 클래스의 부모 클래스를 선택

TestMFC 프로젝트 작성 시 생성되는 파일

TestMFC.sln

TestMFC.vcproj

TestMFC.dsw

TestMFC.dsp

솔루션 파일

프로젝트파일

워크 스페이스파일(6.0)

프로젝트파일(6.0)

TestMFC.h, TestMFC.cpp

응용 프로그램 클래스가 정의되어 있습니다.

MainFrm.h, MainFrm.cpp

메인 프레임 클래스가 정의 되어 있습니다.

TestMFCDoc.h, TestMFCDoc.cpp

도큐먼트 클래스가 정의 되어 있습니다.

TestMFCView.h, TestMFCView.cpp

뷰 클래스가 정의 되어 있습니다.

TestMFC.rc

리소스 정의 파일

TestMFC.ncb

클래스 위저드가 사용하는 정보파일

Readme.txt

간단한 설명이 들어있습니다.

StdAfx.h, StdAfx.cpp

PCH 파일을 만드는데 사용됩니다.

 

Visual C++ 은 컴파일 속도의 증가를 위해 미리 컴파일 된 헤더(PCH: PreCompiled Header) 라는 기법을 사용합니다.

C컴파일러는 컴파일 시간의 대부분을 헤더파일을 컴파일 하기 위해 소모하게 되는데 헤더파일은 내용을 직접 변경시키지 않는 경우가 많기 때문에 다시 컴파일을 하지 않아도 될 경우가 많습니다.

Visual C++ 은 헤더파일을 한 번만 컴파일 한 후 컴파일 결과를 PCH 파일에 저장해 두고 다음부터 컴파일 할 때는 헤더파일을 직접 컴파일 하지 않고 미리 컴파일 해 놓은 결과인 pch 파일만을 가지고 실행합니다.

PCH기법을 사용하기 위해 만들어진 파일이 StdAfx.h StdAfx.cpp 파일입니다.


 

5. MFC 4대 클래스

1. CTestMFCApp: CWinApp로부터 상속됩니다.

- 3개 클래스(CMainFrame, CTestDoc, CTestView) 통합 관리하고 프로그램 전체를 대표하는 기능을 수행

- 프로그램의 시작과 끝을 담당.

- 프로그램이 시작할 때 메인 프레임을 만들어 줍니다.

- 사용자에 의한 이벤트에 따라 메시지를 발생시키고 메시지 정보를 처리함수(핸들러)로 보냅니다.

WM_QUIT 메시지가 올 때까지 계속 반복합니다.

 

응용 프로그램 클래스(Application Program Class)란 윈도우즈 프로그램 그 자체를 나타냅니다.

프로젝트의 메인 클래스입니다.

응용 프로그램 클래스는 보통 프로젝트 이름과 같은 이름의 파일에 저장되며 클래스 이름 뒤에는 App가 추가됩니다.

TestMFC.vcproj 프로젝트에서 응용 프로그램 클래스는 TestMFC.h 파일에 선언되고 구현파일은 TestMFC.cpp가 되며, 응용 프로그램 클래스는 CTestMFCApp가 됩니다.

앞에 붙인 C는 클래스라는 뜻입니다.

소스에 포함된 주석 문은 프로그래머가 소스를 쉽게 파악할 수 있도록 하기 위해 AppWizard가 붙인 것입니다.

생성자 함수가 있을 것입니다.

InitInstance()는 프로그램을 초기화하는 루틴을 넣습니다.

이 함수의 시작 부분에

AfxMessageBox(TEXT("Hello MFC"));

이 코드를 지정하면 윈도우를 생성하기 전에 메시지 박스를 화면에 출력할 것입니다.

 

OnAppAbout 함수는 도움말 항목을 눌렀을 때 발생하는 메시지에 대한 처리 부분입니다.

MFC에서는 특정 메시지에 대한 처리를 함수를 생성해서 구현합니다.

일반적으로 함수 명은 메시지 이름 앞에 On을 붙여서 정의합니다.

 


 

CWinApp클래스의 주요 멤버

m_hInstance: 현재 응용 프로그램의 인스턴스 핸들

m_lpCmdLine: 프로그램을 실행하였을 때 명령 줄 정보

m_nCmdShow: 프로그램이 보여지는 모양

m_pActiveWnd: 최상위 프레임 윈도우에 대한 포인터로 일반적으로 CMainFrame에 대한 포인터 입니다.

m_pszAppName: 프로그램의 제목

m_pszExeName: 확장자를 제외한 실행 파일명

InitInstance(): 응용 프로그램이 초기화되는 시점에서 호출되는 함수

대부분 재 정의 되어있으며 직접 코드 수정 가능

Run(): 메시지 루프를 처리해주는 함수로 재정의 되어있지 않으며 수정할 수 없음

ExitInstance(): 응용 프로그램이 종료하는 시점에 호출

재정의 되어 있지 않으므로 직접 재정의 해서 사용해야 함
CMainFrame: MainFrm.h/ MainFrm.cpp

CFrameWnd 클래스로부터 상속됩니다.

메인 프레임 클래스는 MainFrm.h 파일에 정의되어 있으며 구현파일은 MainFrm.cpp입니다.

이 클래스는 프로젝트의 종류에 상관없이 거의 고정된 역할을 하므로 프로젝트 이름과 상관없이 이름이 고정되어 있습니다.

프로그램의 외형을 만드는 역할을 담당합니다.

OnCreate()함수가 이 부분을 담당합니다.

이 함수는 WM_CREATE 메시지에 의해 호출됩니다.

현재는 이 함수에 툴바와 상태 표시줄을 생성하는 코드가 작성되어 있습니다.

 

PreCreateWindow(CREATESTRUCT& cs)

이 함수는 윈도우를 생성하기 전에 수행되는 함수입니다.

이 함수의 매개 변수인 cs의 값을 변경하게 되면 처음 생성되는 윈도우의 위치나 크기 등을 변경할 수 있습니다.

실행 중 윈도우의 모양을 변경하고자 한다면 SetWindowPos 함수를 이용해야 합니다.

 

CTestMFCDoc: CDocument로부터 상속됨

- 프로그램의 데이터를 파일에 저장하고 읽기 위한 클래스

저장, 열기를 담당합니다.

이 클래스의 멤버함수인 onNewDocument()는 응용 프로그램이 실행되면 반드시 한번은 수행을 하게 됩니다

 

CTestMFCView: CView로부터 상속됨

- 사용자로부터의 입력을 처리하거나 작업의 결과를 화면에 출력하는 클래스

- 보여지는 부분을 담당.

CTestMFCView 클래스는 CView 클래스로부터 상속을 받습니다.

화면출력을 담당하는 클래스입니다.

또한 뷰 클래스는 프로그램 실행 중에 키보드나 마우스로부터의 입력을 처리하는 역할을 하고 있습니다.


 

화면의 중앙에 HelloWorld를 출력하는 프로그램 작성

HelloView.cpp

void CHelloView::OnDraw(CDC* pDC)

{

CHelloDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

RECT ClientRect;

       GetClientRect(&ClientRect);

       pDC->DrawText(TEXT("Hello MFC!"),-1, &ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

}

6.0에서는 위의 소스만을 복사하면 되지만 2008에서는 매개변수인 pDC가 주석 처리 되어 있으므로 해제하고 사용해야 합니다.

 

MFC가 제공하는 Template에 소스 추가하는 방법

1. 이미 존재하는 기능의 수정 및 보강

이미 존재하는 기능을 수정하거나 보강한다는 것은 기본적으로 파생클래스에서 기반클래스의 멤버 함수를 재정하는 것을 의미합니다.

MFC에서 상속을 받아 파생 클래스를 만듦으로써 프로그램의 틀을 구현하고 기반 클래스에서 상속 받은 기능 중에 수정해야 할 부분이 있다면 재정의를 통해 그 부분만 원하는 대로 고치거나 기능을 추가할 수 있는 것입니다.

 

클래스 뷰에서 클래스를 선택하면 아래쪽 창에 이미 작성된 함수 명이 보일 것입니다.

함수를 더블 클릭하면 그 함수의 내용이 작성된 곳으로 이동하므로 소스를 작성하면 됩니다.

이 때 함수를 선택하면 Description 에 함수에 대한 간단한 설명이 나오게 됩니다.

보이지 않는 메시지나 함수는 클래스 뷰에서 클래스를 선택하고 마우스 오른쪽을 눌러서 속성 창을 보이게 한 후 메시지를 작성하면 됩니다.

 

2. 존재하지 않는 기능의 추가

존재하지 않는 새로운 기능을 추가한다는 것은 MFC에서 상속 받아 만들어진 클래스에 새로운 멤버 함수나 멤버 변수를 추가하는 것을 의미합니다.

 

Class View에서 클래스를 선택하고 오른쪽 마우스 버튼을 누르고 [추가]에서 변수 또는 함수를 선택해서 변수의 경우는 접근 지정자와 자료형 및 변수명을 지정하고 선언하면 되고 이 때는 Framework이 생성자 함수에 초기화를 자동으로 수행해 줍니다.

배열이나 포인터 변수를 생성하고자 한다면 클래스의 선언 부에 가서 직접 선언하고 생성자 함수에서 직접 초기화하면 됩니다.

함수를 추가하는 경우에도 이처럼 수행하면 됩니다.

 

프로그램 작성 시 알아두면 좋은 것

1. 멤버 함수나 멤버 변수 삭제

멤버 변수나 함수를 삭제 할 때는 클래스 뷰에서 멤버 변수를 더블 클릭해서 멤버 변수가 선언된 곳으로 이동해서 삭제 하고 초기화가 자동으로 되어 있다면 생성자 함수에 가서 직접 삭제해야 합니다.

 

2. 전역 변수나 함수 선언

클래스의 멤버 함수들이 정의 된 중간에 변수나 함수를 만들면 전역으로 선언되며 클래스뷰에는 Global에 보이게 됩니다.

 

3. 새로운 클래스 만들기

[프로젝트] – [클래스 추가]를 눌러서 Class Type을 결정합니다.

이 때 MFC가 가지고 있는 클래스인지 일반 클래스인지 결정합니다.

그리고 일반 클래스라면 클래스이름을 입력하고 구현하면 됩니다.

MFC 클래스라면 기반 클래스가 어떤 것인지 선택하고 이름을 입력하고 만들면 .cpp 파일과 .h 파일을 생성해 줍니다.

 

4. 클래스 삭제

MFC에서는 모든 클래스가 헤더파일과 구현파일을 생성해 내므로 클래스를 삭제하고자 할 때는 프로젝트가 생성된 폴더에 가서 실제로 파일을 삭제하고 와야 합니다.

 

5. 작업도중 워크스페이스에 클래스가 보이지 않을 때 처리 방법

프로젝트를 닫고 프로젝트가 저장된 폴더로 이동해서 .ncb 파일을 삭제하고 프로젝트를 다시 열면 됩니다.

ncb 파일은 전체적인 소스를 관리하는 파일 이기 때문입니다.

 

6. 작업 도중 에러를 수정하다가 수 많은 클래스 이름이나 구조체의 이름이 워크스페이스에 보일 때

대부분은 MFC가 미리 정의해 둔 구조체나 클래스를 변경한 경우이므로 이를 원래대로 해주면 됩니다.

 


 

사용자가 마우스로 클릭한 위치에 사각형을 그려주는 프로젝트 작성

1. SDI옵션으로 MFC프로젝트 작성

 

2. View클래스에 m_Rect라는 멤버 함수 작성

void m_Rect(CPoint point)

 

3. 멤버 함수 정의

CClientDC dc(this);

dc.Rectangle(point.x, point.y, point.x+20, point.y+20);

 

4. LButtonDown 함수 정의

클래스 위저드를 이용해서 호출한 후 작성

m_Rect(point);
클래스간 상호 참조

CWinAppe에 대한 접근: AfxGetApp()로 어디에서나 접근 가능

CMainFrame에 대한 접근: AfxGetMainWnd()로 어디에서나 접근 가능

CDocument에 대한 접근: MainFrame에서는 GetActiveDocument()로 접근

                      View에서는 GetDocument()로 접근

CView에 대한 접근: MainFrame에서는 GetActiveView()로 접근

 

6. MFC에서 알아두면 편리한 클래스

1) 클래스 들 간의 상속 관계

CObject 클래스에서 CCmdTarget 클래스 파생

CCmdTarget은 사용자가 정의한 메시지(메뉴, 단축키 등)을 처리할 수 있는 클래스입니다.

CCmdTarget으로부터 CWinApp, CDocument, CWnd 파생

이 세 개의 클래스들은 따라서 사용자가 정의한 메시지(메뉴, 단축키 등)을 처리할 수 있습니다.

이 중에서 CWnd만이 화면에 보여집니다.

CWnd 클래스로부터는 CFrameWnd, CView, 컨트롤 클래스들이 상속을 받습니다.

이러한 클래스들은 모든 메시지를 전부 처리할 수 있습니다.

 

2) CString 클래스

const char* LPCTSTR 대신 CString 객체를 직접 사용할 수 있습니다.

각종 연산자와 멤버 함수가 정의 되어 있어 문자열 사용하는데 편리합니다.

CString 클래스의 객체에 다른 데이터 타입을 이용하고자 하면 Format 함수를 이용하면 됩니다.

C언어의 printf 형태로 이용하면 됩니다.

) CString 객체 str에 정수 100, 200을 할당하는 방법

str.Format("x=%d, y=%d", 100, 200);

 

CString 형 객체의 내용을 char * 타입으로 변환하고자 한다면

(LPSTR)(LPCTSTR)CString객체)로 변환하면 됩니다

 

3)CPoint

점의 좌표를 저장하는 클래스

API POINTS 구조체와 유사

 

4)CRect

2개의 점의 좌표를 저장하는 클래스

 

5)CSize

가로와 세로 길이를 저장하는 클래스

 Visual C++ MFC - chapter 1.MFC 시작


반응형

'C & C++ > C & C++' 카테고리의 다른 글

[MFC] 주요 클래스  (0) 2011.04.25
[MFC] 기본 구조  (0) 2011.04.25
[Tip] Enter Key 클릭시 종료 방지 [PreTranslateMessage 사용]  (0) 2011.04.25
[TIP] MFC, STL 간단 사용팁  (0) 2011.04.23
UNICODE 에 대하여  (0) 2011.04.23

댓글