LuvSea

[MFC 기초] 자동생성 클래스 분석 - CWinApp 본문

sTudy

[MFC 기초] 자동생성 클래스 분석 - CWinApp

사랑海 2009. 10. 13. 18:55
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

[출처] http://myhome.hanafos.com/~log0/mfc/mfc03.htm

AppWizard 단계를 거치고  나면 Lyra 프로젝트를 만들고 나면 자동적으로
CWinApp -> CLyraApp
CMDIFrameWnd -> CMainFrame
CDocument -> CLyraDoc
CView -> CLyraView
4개의 클래스가 만들어진다.
한가지 덧붙이면 WorkSpace 창에서 클래스 탭을 클릭하면 현재 생성된  클래스들을 볼수 있다.
클래스는 *.CPP, *.h 두 파일을 모두 보여 준다. 클래스 이름을  클릭하면 *.h 파일을 볼수 있고
해당 클래스의 함수를 클릭하면 *.cpp 파일이 보여지며 클래스를  수정해도 *.cpp, *.h 파일이
함께 자동 변경된다.
 

CLyraApp클래스

우선 CWinApp 클래스입니다. 
애플리케이션 클래스로 CLyraApp란 클래스가 만들어지고 그것은 Lyra.cpp 파일에 기록되는데,
 이 CLyraApp 클래스는 CWinApp클래스를  상속받아서 사용합니다.
즉 CWinApp 클래스의 기능을 물려받고 거기다가 개발자가 하고자하는  기능을 넣으면 된다.
CWinApp라는 것은 애플리케이션을 만들 때 필요한 클래스입니다.

CLyraApp파일을 한 번 열어보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include·"stdafx.h"¬
#include·"Lyra.h"·¬
¬
#include·"mainfrm.h"¬
#include·"Lyradoc.h"¬
#include·"Lyraview.h"·¬
¬
#indef·_DEBUG¬
#UNDEF·THIS_FILE¬
ststic·char·BASED_CODE·THIS_FILE[]·=·_FILE_;¬
#endif¬
¬
/*·CLyraApp··CwinApp··········.·*/¬
BEGIN_MESSAGE_MAP(CLyraApp,·CwinApp)¬
···//{{AFX_MSG_MAP(CLyraApp)¬
¬
/*·ID_APP_ABOUT····.·¬
··············.·¬
···········.·About·DEMO1····OnAppAbout···.·*/¬
ON_COMAND(ID_APP_ABOUT,·OnAppAbout)¬
···//·NOTE-the·Classwizard·will·add·and·remove·¬
············mapping··macros·here.¬
···//·DO·NOT·EDIT·what·you·see·in·these·block·of·¬
············generated··code!¬
···//}}AFX_MSG_MAP¬
·······//·Standard·file·based·document·commands¬
·······¬
/*···File·->·New···CwinApp··OnFileNew···.·*/¬
ON_COMMAND(ID_FILE_NEW,··CwinApp::OnFileNew)¬
¬
/*···File->Open···CwinApp··OnFileOpen··.·*/·······¬
ON_COMMAND(ID_FILE_OPEN,··CwinApp::OnFileOpen)¬
·······//·Standard·print·setup·command¬
¬
/*···File->PrintSetup···CwinApp··OnFilePrintSetup··.·*/·¬
ON_COMMAND(ID_FILE_PRINT_SETUP,··CwinApp::OnFilePrintSetup)¬
END_MESSAGE_MAP()·¬
¬
BEGIN_MESSAGE_MAP(CLyraApp,·CwinApp),·END_MESSAGE_MAP()·¬
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
위 Source는 BEGIN_MESAGE_MAP 부분이다.
이상한 점은 세미콜론(;)이 없다는 것이다.
Visual C++은 윈도우 프로그래밍이다. 이말은 즉 모든 실행을 메세지로 처리한다는 뜻이다.

위에서 알수 있듯이 기본적으로 생성된 프로그램에는 보통 File메뉴와  Edit메뉴, Window메뉴,
Help메뉴가 들어간다. 또한 위의 4개의 함수는 CWinApp에서 제공 되는  기본 함수이다. 몇 번의
클릭으로 여러분은 엄청난 일을 했다. 원하는 다른 함수를  동작시키려면 위의 메시지 매핑에
사용자가 직접 써 넣어야 한다.

다른 함수는 CLyraApp의 생성자인데, 이것은 이 클래스가 생행됨과 동시에 자동적으로  실행되는 함수 이다.
이 클래스는 프로그램이 시작됨과 동시에 실행되지만, 안에는 아무것도 없다.
즉 지금 현재는 생성시 아무것도  하지 않겠지만 후에 애플리케이션 클래스가 생성될 때 어떤 일을 해야 한다는 이 함수 안에  기록하면 된다.


1
2
3
4
5
CLyraApp::CLyraApp()¬
{¬
//·TODO·add·construction·code·here,¬
//·place·all·significant·initialization·in·InitInstance¬
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


위의 함수는 CLyraApp의 생성자다.
CLyraApp 클래스가 실행됨과 동시에 자동적으로 실행되는 함수이며  프로그램이 시작과 동시에 실행된다.
생성자와 같이 CLyraApp 클래스의 실행과 함께  CWinApp::InitInstance() 함수가작동한다.
그리고 상속받은 것을 무시하려면 헤더에 다음과 같이 등록한다.
virtual BOOL InitInstance();

아래의 예는 AppWizard 4단계에서  사용자 인터페이스 옵션 항목에서 "3D Controls를 Enable했다."는 가정에서 이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
BOOL·CLyraApp::InitInstance()¬
{¬
#ifdef·_AFXDLL¬
Enable3dControls();·//·Call·this·when·using·MFC·in·a·shared·DLL¬
#else·//·Call·this·when·linking·to·MFC·statically¬
Enable3dControlsStatic();¬
#endif·¬
¬
SetRegistryKey(_T("Local··AppWizard-Generated·Applications"));¬
//·····.·····.¬
//········.·¬
¬
LoadStdProfileSettings();·//Load·standard·INI··file·options·(including·MRU)¬
/*···AppWizard·4······MRU·File·List··¬
··.···········¬
··.·*/¬
}·¬
¬
¬
·······CSingleDocTemplate*·pDocTemplate;¬
·······pDocTemplate·=·new·CSingleDocTemplate(¬
···············IDR_MAINFRAME,¬
···············RUNTIME_CLASS(CLyraDoc),¬
···············RUNTIME_CLASS(CMainFrame),········//·main·SDI·frame·window¬
···············RUNTIME_CLASS(CLyraView));¬
·······AddDocTemplate(pDocTemplate);¬
·······¬
·······¬
//·Parse·command·line·for·standard·shell·commands,·DDE,·file·open·¬
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

이 프로젝트를 SDI로 선택했었다. 그렇다면 MDI 처럼 사용될 데이터를 저장할 공간이 있어야 하는 것은 아니다.
단 SDI에 필요한 하나의 공간을 설정해 주는 클래스가 CSingleDocTemplate이다.
pDocTemplate라는 가상적인 CSingleDocTemplate 형의 변수를 선언하고 이것이 생성될 때는
CLyraDoc 클래스인 Document와 CMainFrame 형태인 틀과 CDemo1View인 화면이 링크되면서 RC(리소스) 파일의
String Table 안에 설정된 IDR_MAINFRAME형으로 연결된다.
다음은 도스창에서 프로그램을 실행시켰을 경우나 또는 DDE나 파일 설정 등으로 실행했을 때 넘겨주는 인자를 받는 내용이다.
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

위의 내용은 CCommandLineInfo라는 클래스 변수 cmdInfo를 만들고 현재 프로그램이 실행되면서
어떤 인자가 들어왔나 조사하기 위한 ParseCommandLine 라는 함수를 실행하는 것이다.
또한 AddDocTemplate 함수를 이용하여 여러개의 Doc와 View와 Frame이 연결된 템플리트를 만들어 등록하였을 경우에도
cmdInfo안에 이 정보가 들어간다. 다음 내용은 이 정보를 실행시키는 것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//·CAboutDlg·dialog·used·for·App·About·¬
¬
class·CAboutDlg·:·public·CDialog¬
{¬
public:·¬
····CAboutDlg();·¬
····//·Dialog·Data·¬
····//{{AFX_DATA(CAboutDlg)¬
····enum·{·IDD·=·IDD_ABOUTBOX·};¬
····//}}AFX_DATA·¬
¬
····//·ClassWizard·generated·virtual·function··overrides¬
//{{AFX_VIRTUAL(CAboutDlg)¬
protected:¬
····virtual·void·DoDataExchange(CDataExchange*·pDX);·//·DDX/DDV·support¬
//}}AFX_VIRTUAL·¬
¬
//·Implementation¬
protected:·¬
····//{{AFX_MSG(CAboutDlg)¬
····//·No·message·handlers¬
····//}}AFX_MSG¬
····DECLARE_MESSAGE_MAP()¬
};·¬
¬
CAboutDlg::CAboutDlg()·:··CDialog(CAboutDlg::IDD)¬
{·¬
····//{{AFX_DATA_INIT(CAboutDlg)¬
····//}}AFX_DATA_INIT¬
}¬
void·CAboutDlg::DoDataExchange(CDataExchange*·pDX)¬
{·¬
····CDialog::DoDataExchange(pDX);¬
····//{{AFX_DATA_MAP(CAboutDlg)¬
····//}}AFX_DATA_MAP¬
}·¬
¬
BEGIN_MESSAGE_MAP(CAboutDlg,·CDialog)·¬
····//{{AFX_MSG_MAP(CAboutDlg)¬
····//·No·message·handlers¬
····//}}AFX_MSG_MAP¬
END_MESSAGE_MAP()¬
//·App·command·to·run·the·dialog¬
void·CLyrasApp::OnAppAbout()¬
{·¬
····CAboutDlg·aboutDlg;¬
····aboutDlg.DoModal();¬
}¬
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

바로 위의 OnAppAbout() 함수에 의해 대화상자가 사용자에게 보여진다.
aboutDlg.DoModal();의 의미는 프로그램에서 About 대화상자를 열었을 경우 이 대화상자를 종료 하기 전까지는
About 대화상자를 벗어나 이 프로그램내의 다른 명령을 내릴수 없다는 뜻이다.
Comments