오늘은.. 드디어 멀티 도큐먼트..
먼저 SDI 때와 다른점을 살펴보면..
CMainFrame 클래스가CMDIFrameWnd를 상속 받는다.
그리고CChildFrame 클래스는CMDIChildWnd를 상속받는다.
CMDIFrameWnd와CMDIChildWnd의아버지 클래스는 CFrameWnd이다.
App 클래스의InitInstance함수를 보면
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_BMPTYPE, // 메뉴와 연결된다.
RUNTIME_CLASS(CMDItest2Doc),
RUNTIME_CLASS(CChildFrame), // 차일드프레임..
RUNTIME_CLASS(CMDItest2View));
AddDocTemplate(pDocTemplate);
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame; // 부모 프레임..
if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) // 부모 프레임의 메뉴
return FALSE;
m_pMainWnd = pMainFrame;
// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();
* PreCreateWindow 함수.
프레임윈도우가 생성될때, 윈도우 속성을 바꿔주려면 PreCreateWindow함수를
오버라이딩하여 넘어온 인자를 수정하면 윈도우 속성이 변경된다.
그리고 차일드프레임의 한번 봐줘야 할 함수들은..
BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// 여기서 cs를 변경시키면 윈도우 속성이 변경된다.
if( !CMDIChildWnd::PreCreateWindow(cs) )
return FALSE;
cs.style = WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
| FWS_ADDTOTITLE | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
return TRUE; // CREATESTRUCT 구조체를 이용해 윈도 스타일을 셋팅..
}
void CChildFrame::ActivateFrame(int nCmdShow) // 활성화되었을때 실행되는거였던가 ㅡㅡa
{
// TODO: Modify this function to change how the frame is activated.
nCmdShow = SW_SHOWMAXIMIZED;
CMDIChildWnd::ActivateFrame(nCmdShow);
}
이제 창을 하나 더 추가 해보려면 우선..프레임과,독,뷰, 각각 클래스를 추가하여야한다.
프레임은 CMDIChildWnd , Doc 는 CDocument , 뷰는 에디트 뷰로.. 상속을 받아 생성했다.
그리고 밑에 부분을 App의 InitInstance 부분에 기본적으로 만들어진부분 밑에다가..끼어 넣는다.
헤더파일 인클루드도 빼먹지말고..
CMultiDocTemplate* pDocTemplate2; ////////////////////////////////////
pDocTemplate2 = new CMultiDocTemplate(
IDR_TXTTYPE, // 요부분이 리소스의 메뉴와 연결..
RUNTIME_CLASS(CMyEditDoc), // 생성한 클래스를 만든다.
RUNTIME_CLASS(CMyEditFrame),
RUNTIME_CLASS(CMyEditView));
AddDocTemplate(pDocTemplate2);
그리고 텍스트 창의 데이터를 저장하거나 불러오려면.. 텍스트 뷰에 대한 Doc클래스의
Serialize함수를 이용한다.CEditView클래스의 멤버함수인SerializeRaw함수만 호출하면
텍스트 데이터를 저장하거나 읽기를 알아서 수행한다.
void CMyEditDoc::Serialize(CArchive& ar)
{
((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
}
이렇게 하면 창이 두개가 있어 처음에 골라줘야 한다. 귀찮다.. 없애버리자..
암거나 고르면 기본적으로 창하나가 생성된다. 이것을 바꾸어 사용자가 새문서를 클릭했을때
그때 창이 생성되게 하려면 App의 InitInstance함수에서
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; // 요기부분 추가..
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
그럼이제 새파일을 눌르면 창이 생성되게 하려면..
App에OnFileNew를 오버라이드 하여..
void CMDItest2App::OnFileNew()
{ // 오늘 소스에서는 나중에 만든 에디트뷰가 달린걸 생성하게 하였다.
// TODO: Add your command handler code here
POSITION pos = GetFirstDocTemplatePosition( ); // 첫번째 Docd의 Position 값을 갖고온다.
CDocTemplate* pDocTemplate = GetNextDocTemplate(pos); //그값으로 DocTemplate 를 얻음.
pDocTemplate = GetNextDocTemplate(pos); // 에디트 뷰를 불러와야하니깐 한번더 간다.
pDocTemplate->OpenDocumentFile(NULL); // 오픈한다...NULL이면 새 파일..
}
그리고 일반뷰 창 생성 커맨드를 매뉴에다 만든다.
창이 생성되어 활성화 될때마다메뉴가 바뀌니 곳곳마다 추가한다.
그리고.. 밑에 함수..
void CMDItest2App::OnBmp() // 여기는 App
{
// TODO: Add your command handler code here
POSITION pos = theApp.GetFirstDocTemplatePosition( ); //
CDocTemplate* pDocTemplate = theApp.GetNextDocTemplate(pos);
pDocTemplate->OpenDocumentFile(NULL); // NULL이면 새 파일..
}
전역변수theApp를 이용하여 EditFrame,일반프레임에도 똑같이 만든다..
여기까지 대충 MDI 완료.. SDI에서 하던거 다 할수 있단다..
* 분할 뷰에서 분할바 못움직이게 하기.
CSplitterWnd 를 상속받아 나만의 CMySplitterWnd 클래스를 만들고 마우스 메세지를 가로챈다.
* 클래스의 재사용..
클래스들을 마우스로 선택후 마우스 오른쪽버튼을 눌러Add to Gallery항목을 선택하면
겔러리에 등록이 된다.
다른 프로젝트에서 사용하려면 컴포넌트 추가할때처럼.. Project - Add to Project -
Components and Control 을 선택하면 추가했을때의 프로젝트명으로 폴더가 있는데
그안에 파일들을 추가하면 된다.
* 리소스의 재사용..
메뉴의 파일 오픈하여 리소스파일을 불러오면 현재 리소스와 불러온 리소스가 양쪽으로 뜬다.
그럼 남은건 카피 앤 페이스트..