View / Document / Frame 의 분리
이번에 해 볼 것은 MFC의 AppWizard가 기본적으로 만들어주는 코드에서 View / Document / Frame을 차례대로 분리해 보려고 한다. 우선은 View부터 먼저 떼어내보자. 여기서 프로젝트 이름을 Hack 이라고 정했다. 우선 AppWizard(exe)에서 옵션은 기존에 있는 그대로 적용하여 SDI 프로젝트를 하나 만든다. (비주얼 C++ 6 최종분석, 베스트북)
- View의 제거
1) 프로젝트에서 HackView.h / cpp 파일을 지운다.
2) Hack.cpp 파일에서 #include "HackView.h" 부분을 지운다.
3) Hack.cpp 파일에서 다음 부분을 고친다.
원래 이런 내용을
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CHackDoc),
RUNTIME_CLASS(CMainFrame),
// main SDI frame window
RUNTIME_CLASS(CHackView));
// 고치기 전
AddDocTemplate(pDocTemplate);
이렇게 고친다.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CHackDoc),
RUNTIME_CLASS(CMainFrame),
// main SDI frame window
NULL);
//
고친 후
AddDocTemplate(pDocTemplate);
4) 그런 다음 컴파일하면 뷰가 없어진 것을 확인할 수 있다.
(뭔가 달라진 게 조금 보일 것이다)
- Document의 제거 (View의 제거 후)
1) 프로젝트에서 HackDoc.h / cpp 파일을 지운다.
2) Hack.cpp 파일에서 #include "HackDoc.h" 부분을 지운다.
3) Hack.cpp 파일에서 다음 부분을 고친다. Document 까지 지워버리면 DocTemplate가
전혀 필요가 없기 때문이다.
View를 제거할 때 고쳤던 내용을
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CHackDoc),
RUNTIME_CLASS(CMainFrame),
// main SDI frame window
NULL);
AddDocTemplate(pDocTemplate);
모두 지우고 다음과 같이 고친다.
// 메인 윈도우를 위한 클래스
변수 선언
CMainFrame *pFrame = new CMainFrame();
// 프레임 제작
pFrame->LoadFrame(IDR_MAINFRAME);
// 메인 윈도우로 지정
m_pMainWnd = pFrame;
4) MainFrm.h 파일을 열어서 CMainFrame()을 protected
속성에서 public 속성으로 바꾼다.
5) 그런 다음 컴파일을 한다. View를 제거했을 때와 같은 창이 뜬다. Document는
눈에 띄지 않으니까.
- Frame의 제거 (View/Document 제거 후)
1) 프로젝트에서 리소스 파일을 모두 지운다. (*.rc *.ico, *.bmp 등)
2) MainFrm.cpp 파일을 열어 OnCreate() 함수를 보자.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct)
== -1)
return
-1;
if (!m_wndToolBar.CreateEx(this,
TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
|
CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed
to create toolbar\n");
return
-1; // fail to create
}
if (!m_wndStatusBar.Create(this)
||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed
to create status bar\n");
return
-1; // fail to create
}
// TODO: Delete these three
lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
앞의 소스 대부분을 지워 다음과 같이 만든다.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct)
== -1)
return
-1;
return 0;
}
3) MainFrm.h 파일을 열어 다음 두 멤버변수를 지운다. 보다시피 상태바와 툴바를 위한 것이다.
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
4) Hack.cpp 파일을 열어 Document를 제거할 때 고쳤던 부분을 보자.
// 메인 윈도우를 위한 클래스
변수 선언
CMainFrame *pFrame = new CMainFrame();
// 프레임 제작
pFrame->LoadFrame(IDR_MAINFRAME);
// 메인 윈도우로 지정
m_pMainWnd = pFrame;
리소스를 지워버렸기 때문에 이 부분에서 문제가 발생한다. 다음과 같이 고친다.
CMainFrame *pFrame = new
CMainFrame();
LPCTSTR new_class = AfxRegisterWndClass
(CS_HREDRAW|CS_VREDRAW,
LoadCursor(IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH));
pFrame->Create(new_class,
NULL,
WS_OVERLAPPED|WS_SYSMENU,
CRect(0, 0, 300, 100));
m_pMainWnd = pFrame;
5) 이제 컴파일해 보면 툴바도 없고, 메뉴도 없고, 상태바도 없는 썰렁한 윈도우가 하나 뜨는 것을 볼 수 있다.