강몬드의 프로그래밍 이야기

Doc-View구조 본문

카테고리 없음

Doc-View구조

강몬드 2015. 6. 2. 16:06

프로젝트 위자드를 사용하여 프로젝트를 생성하면(기본 프로그램 작성에서 설명) 다음과 같이 각 기능을 가진 파일들이 생성된다(프로젝트 이름을 Test로 만들었을 경우를 예로하여 설명).

App : MainFrame을 생성하는 역할을 수행한다(CTestApp).

MainFrame : 타이틀바, 메뉴, 툴바, 상태바 등 프로그램의 바깥 부분을 관리하는 역할을 수행한다(CMainFrame).

ChildFrame : MDI 프로그램일 경우 만 있다. MDI 창의 타이틀등 바깥 부분을 관리하는 역할을 수행한다(CChildFrame).

View : 클라이언트 영역(프로그래머 또는 사용자가 그릴 수 있는 영역)을 관리하는 기능을 수행한다. 실제 화면에 표시하는 루틴을 이 파일에 추가한다(CTestView).

Document : 각 View마다 생성되는 것으로 메모리 내용에 해당하는 부분을 여기에서 관리한다(CTestDoc).

기능들을 살펴 보면 View Class에 메모리 내용을 모두 넣고 Document Class는 없어도 되지 않을까 하는 생각이 들지도 모른다. 또한 초보자들 중에 간혹 이렇게 프로그램하는 사람들이 있고 또한 이렇게 하여도 프로그램 수행되는데는 문제가 없다. 그러나 프로그래밍시 되도록 기능별로 파일을 분리하여 작성하는 것이 좋으므로 화면 출력 루틴은 View에 메모리 및 파일 관리 루틴은 Document에 프로그램하도록 마이크로소프트사에서 권장하고 또한 기본적으로 파일이 생성되도록 만들어 놓았으므로 되도록 그 규칙에 따라 프로그램하는 것이 좋다.

Document의 메모리 내용은 대부분 View에서 사용한다. View에서 사용시 다음 문장과 같이 GetDocument함수를 이용하여 Document를 얻는다.

CTestDoc *pDoc = pView->GetDocument(); 

 

그러나 간혹 ChildFrame에서 MainFrame에서 App에서 또한 대화 상자 등 DocView구조와 관계없는 루틴에서 Document 내용이 필요할 경우가 있다. View가 아닌 루틴에서 Document를 구하기 위한 전체 구조를 보면 다음과 같다.

DocView 구조와 상관없는 루틴에서 Document를 구하는 방법이 가장 복잡하므로 살펴보면 다음과 같다.

    CTestApp *pApp = (CTestApp*)AfxGetApp(); //App구함

    CMainFrame *pMainFrm = (CMainFrame*)pApp->m_pMainWnd) //MainFrame구함

    CChildFrame *pChildFrm = (CChildFrame*)pMainFrm->MDIGetActive();  //Active된 ChildFrame구함

    CTestView *pView = pChildFrm->GetActiveView(); //View 구함

    CTestDoc *pDoc = pView->GetDocument();   //Document 구함

단계별로 클래스를 구하므로 위 루틴만 이해하면 어디서든지 Document를 구할 수 있을 것이다. 예를 들어 ChildFrame에서 Document를 구하는 방법은 다음과 같다.

    CTestView *pView = GetActiveView(); //Active된 View 구함

    CTestDoc *pDoc = pView->GetDocument();   //Document 구함

지금까지의 설명은 MDI 프로그램을 기준으로 하였다. SDI 프로그램은 ChildFrame이 없으므로 이 과정만 빠지면 된다. SDI 프로그램에서 DocView 구조와 상관없는 루틴에서 Document를 구하는 방법은 다음과 같다.

    CTestApp *pApp = (CTestApp*)AfxGetApp(); //App구함

    CMainFrame *pMainFrm = (CMainFrame*)pApp->m_pMainWnd) //MainFrame구함

    CTestView *pView = pMainFrm->GetActiveView(); //Active된 View 구함

    CTestDoc *pDoc = pView->GetDocument();  //Document 구함

C프로그램에 익숙해져 있는 사람들은 왜 이렇게 복잡한 과정을 거쳐 메모리 내용(Document 내용)을 사용하는지 의아해 할 것이다. 그냥 Global 변수로 잡고 사용하면 될 것을... 물론 MFC에서도 Global변수를 사용할 수 있다. 그러나 Global 변수는 작은 프로그램에서는 사용법이 간단하여 편하나 프로그램이 커지게 되면 어디에서나 Access가 가능하므로 버그가 발생했을 때 그 원인을 추적하기가 정말 어려워 지므로 권하지 않는다. 또한 Document는 MDI 창마다 생성되는 내용이므로 Global 변수로 구현하기가 쉽지 않을 것이다.

  메모리 내용을 모두다 Document에만 넣는 것은 아니다. MDI 창마다 생성되지 말아야 할 내용, 즉 MDI 창들에서 공통으로 사용하는 내용은 App나 MainFrame에 넣어서 구성하여야만 한다.

Comments