[MFC] 3장: MFC 프로그램 기본 구조
[ 교재 ]
열혈강의 Visual C++ 2008 MFC 윈도우 프로그래밍
저자 최호성 / 출판사 프리렉
3장: MFC 프로그램 기본 구조
1. 윈도우들의 구성과 기본 구조
<CreateDemo 예제 윈도우의 구성>
↑ 지난 번 스터디에서 실습했던 CreateDemo 프로그램이 어떤 윈도우로 구성되어 있으며, 각각이 서로 어떤 관계를 맺고 있는지 말해 주는 그림. 원하는 윈도우를 제어하려면 어떤 클래스의 어떤 멤버 함수에 코딩해야 하는지 직관적으로 알아야 함.
<각 클래스 간의 관계>
응용 프로그램(App)+문서(Doc) 이런 것들이 서로 유기적으로 관계되어 있음. ToolBar(도구 모음), StatusBar(상태 표시줄), View(뷰) 윈도우는 모두 MainFrame의 자식 윈도우라는 점에서 동등. 하지만 두 Bar(바) 윈도우는 CMainFrame 클래스의 멤버 변수로 구성원이지만 View(뷰) 윈도우는 그렇지 않다. 때문에 나중에 각 윈도우에 접근하는 방법이 달라짐.
<SDI 구조>
프레임 윈도우, 뷰 윈도우, 도큐먼트, 응용 프로그램의 네 객체가 유기적으로 연계되어 있음.
이것을 다 합쳐서 SDI(Single Document Interface) 구조라고 함.
SDI 구조에 맞추어 각 윈도우 클래스가 생성된다.
이 과정에서 CMainFrame 클래스, CCreateDemoView 클래스, CCreateDemoDoc 클래스가 서로 얽혀서 생성된다. 이와 관련된 코드는 CCreateDemoApp 클래스의 InitInstance() 함수에 들어 있다.
BOOL CCreateDemoApp::InitInstance()
{
생략…
// 응용 프로그램의 문서 템플릿을 등록합니다. 문서 템플릿은
// 문서, 프레임 창 및 뷰 사이의 연결 역할을 합니다.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CCreateDemoDoc),
RUNTIME_CLASS(CMainFrame),// 주 SDI 프레임 창입니다.
RUNTIME_CLASS(CCreateDemoView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
<CCreateDemoApp을 초기화 하는 InitInstance() 가상 함수>
CWinApp 클래스가 응용 프로그램 자체이며 응용 프로그램과 관련된 많은 정보를 담을 멤버를 다양하게 갖고 있다.
멤버 변수 | 기능 |
m_hInstance | 현재 응용 프로그램의 인스턴스 핸들입니다. WinMain( ) 함수의 첫 번째 파라미터인 hInstance와 같은 것입니다. |
m_lpCmdLine | WinMain( ) 함수의 lpCmdLine 파라미터와 같은 것입니다. 프로그램을 실행하였을 때 명령줄(Command-line) 정보가 들어 있습니다. |
m_nCmdShow | WinMain( ) 함수의 마지막 파라미터인 nCmdShow와 같은 것입니다. |
m_pActiveWnd | 응용 프로그램의 최상위 프레임 윈도우에 대한 포인터입니다. SDI 구조에서 이 값은 CMainFrame 클래스 객체의 포인터입니다. |
m_pszAppName | 응용 프로그램의 제목에 해당하는 문자열의 포인터입니다. CreateDemo 예제의 경우 이 값이 CreateDemo였습니다. 문자열의 좀더 정확한 정보는 문자열 테이블(String Table)에 들어 있는 AFX_IDS_APP_TITLE에 해당하는 값입니다. |
m_pszExeName | 빌드한 실행 파일에서 확장자( .exe)를 제외한 파일명입니다. |
<CWinApp 클래스>
응용 프로그램은 일반적으로 지원해야 할 기능이 아주 많다. 예를 들어 프로그램을 시작에 필요한 각종 정보를 로딩해야 한다. 예전에는 이런 정보를 INI 파일에 저장했지만 최근엔 레지스트리(Registry)에 저장하는 경우가 많다. 그리고 프로그램 아이콘과 같은 리소스도 설정하고 로딩해야 한다.
CWinApp 클래스에는 InitInstance() 외에도 Run(), ExitInstance() 가상 함수가 있다.
- InitInstance(): 응용 프로그램이 초기화 되는 시점에서 호출됨.
- Run(): 메시지 루프가 시작되는 메서드. 이 함수가 반환되면 프로그램은 종료됨.
- ExitInstance(): 응용 프로그램이 종료되는 시점(Run() 함수가 반환한 시점)에 호출됨.
그래서 InitInstance, Run, ExitInstance 가상 함수가 각각 실행될 때 무엇을 할지 정하는 것이 MFC 프로그램의 주요 골자라고 할 수 있다.
결론:
MFC로 윈도우 프로그래밍을 하는 핵심은 어떻게 코딩할 것인지가 아니라 어디에 코딩할 것인가이다.
MFC는 Win32 API와 달리 WinMain() 함수도 보이지 않을뿐더러 기본구조가 정해져 있어서 개발자는 흐름을 따라야 한다. 그래서 원하는 결과를 얻으려면 어디에 코딩해야 할지를 아는 것이 매우 중요하다.
2. "새 문서 열기" 메시지박스 출력
- 클래스 뷰 -> OnNewDocument 더블클릭
- 소스코드 AfxMessageBox(_T("새로운빈문서")); 작성
- 실행 시 새로운 빈 문서라는 메시지박스 출력 : 처음 출력하는 문서창도 결국에는 새로운 문서를 출력하는 것이기 때문에 이런 메시지박스 출력
3. "기존 문서 열기 및 수정 사항저장" 메시지박스 출력
- Doc 클래스 -> 속성 -> OnOpenDocument 추가
- SetModifiedFlag는 위 의 출력 메시지와 같이 문서를 수정하거나 하지 않고 종료하더라도 위와 같은 메시지 출력
- 실행 -> 문서를 열면 다음과 같은 메시지 박스가 출력
4. "새 문서 열기" 메시지박스 출력
- CMainFrame -> 속성 -> WM_CLOSE(OnClose)메시지 추가
- 종료 시 메시지 박스 출력
5. 메세지 맵
- 윈 API의 switch & case 문과 비슷한 역할을 수행하는 구문
- 대응되는 메시지에 대한 함수 수행
- Win API switch & case 문
6. 실습 문제
1. 임의의 SDI 형식의 프로젝트를 만들고 CDocument 클래스에
OnOpenDocument()와 OnCloseDocument() 가상 함수를 재정의해 봅시다.
2. 재정의한 함수에서 AfxMessageBox() 함수를 이용하여 임의의 메시지 상자를 출력하도록 해봅시다.
'프로그래밍 실습 > MFC' 카테고리의 다른 글
[MFC] 6장: 마우스 입력 (0) | 2011.02.25 |
---|---|
[MFC] 5장: 키보드 입력 (1) | 2011.02.16 |
[MFC] 4장: MFC SDI 어플리케이션 흐름 (0) | 2011.02.16 |
[MFC] 2장: CWnd 클래스 (0) | 2011.02.16 |
[MFC] 1장: 윈도우 프로그래밍 모델 (0) | 2011.02.16 |