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) 이제 컴파일해 보면 툴바도 없고, 메뉴도 없고, 상태바도 없는 썰렁한 윈도우가 하나 뜨는 것을 볼 수 있다.