/********************************************************************************/
/* 뷰 전환 경우 1(뷰가 겹쳐있을때)
/********************************************************************************/
┏━━━━━━━┳━━━━━━━━━━━┓
┃ ┃ ┃
┃ ┃ ┃
┃ ┃ ┃
┃ 폼뷰 ┃ 뷰(CBaseView) ┃ 새로만드는 뷰(CTestView)
┃(CMenuView) ┃ ┃
┃ ┃ ┃
┃ ┃ ┃
┗━━━━━━━┻━━━━━━━━━━━┛
<위와 같이 폼뷰가 있고, 기본 베이스 뷰가 오른쪽에 위치하고 새로만드는 뷰까지 총 세개의 뷰가 있다>
1. 폼뷰 생성( 라디오 버튼을 두개 만든다. CMenuView )
2. 새로운 뷰 생성( CTestView )
3. 메뉴에 뷰를 전환하기 위해 두개의 메뉴 추가
4. 메인프레임의 OnCreateClient에서
if (!m_wndSplitter.CreateStatic(this, 1, 2))
{
TRACE0("Fail to create splitter window.\n");
return FALSE; // failed to create
}
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMenuView), CSize(100, 100), pContext);
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CBaseView), CSize(100, 100), pContext);
m_pTestView = new CTestView;
m_pTestView->Create( NULL, NULL, 0, CRect(0,0,0,0), &m_wndSplitter, 10, pContext );
//뷰의 포인터 객체 초기화 방법 1////////////////////////////////////////////////////////
m_pMenuView = (CMenuView *)m_wndSplitter.GetPane(0, 0);
m_pBaseView = (CMFC0608View *)m_wndSplitter.GetPane(0, 1);
//////////////////////////////////////////////////////////////////////////////////////
SetActiveView( (CView*)m_wndSplitter.GetPane(0, 0) );
return TRUE;
//베이스뷰 포인터 객체 초기화 방법 2///////////////////////////////////
//베이스뷰의 OnCreate에서
CMainFrame *pFrame = (CMainFrame *)GetParentFrame();
pFrame->m_pBaseView = this;
//메뉴뷰의 OnCreate에서
CMainFrame *pFrame = (CMainFrame *)GetParentFrame();
pFrame->m_pMenuView = this;
/////////////////////////////////////////////////////////////////////
//※위의 두가지의 베이스뷰 포인터 객체 초기화방법중 한가지를 쓰면됨
5. 메뉴에서 베이스뷰 메뉴와 테스트뷰를 클릭했을경우 뷰 전환
void CMainFrame::OnBaseview() //베이스뷰 클릭했을때
{
if( !m_bChange ) return; //메인프레임의 생성자에서 FALSE로 초기화
CView *pOldView, *pNewView;
pOldView = m_pTestView;
pNewView = m_pBaseView;
pNewView->ShowWindow( SW_SHOW );
pOldView->ShowWindow( SW_HIDE );
pOldView->SetDlgCtrlID( pNewView->GetDlgCtrlID() );
pNewView->SetDlgCtrlID( m_wndSplitter.IdFromRowCol(0, 1) );
m_wndSplitter.RecalcLayout();
CButton* pButton = (CButton *)m_pMenuView->GetDlgItem( IDC_RADIO1 );
CButton* pButton2 = (CButton *)m_pMenuView->GetDlgItem( IDC_RADIO2 );
pButton->SetCheck(1);
pButton2->SetCheck(0);
m_pMenuView->UpdateData(FALSE);
}
void CMainFrame::OnTestview() //테스트뷰 클릭했을때
{
CView *pOldView, *pNewView;
pOldView = m_pBaseView;
pNewView = m_pTestView;
pNewView->ShowWindow( SW_SHOW );
pOldView->ShowWindow( SW_HIDE );
pOldView->SetDlgCtrlID( pNewView->GetDlgCtrlID() );
pNewView->SetDlgCtrlID( m_wndSplitter.IdFromRowCol(0, 1) );
m_wndSplitter.RecalcLayout();
CButton* pButton = (CButton *)m_pMenuView->GetDlgItem( IDC_RADIO1 );
CButton* pButton2 = (CButton *)m_pMenuView->GetDlgItem( IDC_RADIO2 );
pButton->SetCheck(0);
pButton2->SetCheck(1);
m_pMenuView->UpdateData(FALSE);
m_bChange = TRUE;
}
6. CTestView의 생성자와 소멸자, 메인프레임의 OnBaseview와 OnTestview를 public속성으로 변경
//메인프레임 해더에서//////////////
public:
CMFC0608View *m_pBaseView;
CTestView *m_pTestView;
CMenuView *m_pMenuView;
afx_msg void OnBaseview();
afx_msg void OnTestview();
//////////////////////////////////
//테스트뷰 해더에서//////////////
public:
CTestView();
virtual ~CTestView();
//////////////////////////////////
7. 메뉴뷰에서 라디오 버튼을 클릭했을때 뷰 전환
void CMenuView::OnRadio1()
{
CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
pFrm->OnBaseview();
}
void CMenuView::OnRadio2()
{
CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
pFrm->OnTestview();
}
/********************************************************************************/
/* 뷰 전환 경우 2(스플리터로 뷰가 나눠져 있을때)
/********************************************************************************/
┏━━━━━━━┳━━━━━━━┳━━━━━━━┓
┃ ┃ ┃ ┃
┃ ┃ ┃ CView2 ┃
┃ ┃ ┃ ┃
┃ ┃ CBaseView ┣━━━━━━━┫
┃ CMenuView ┃ ┃ ┃
┃ ┃ ┃ CView3 ┃
┃ ┃ ┃ ┃
┃ ┣━━━━━━━┻━━━━━━━┫
┃ ┃ ┃
┃ ┃ CView1 ┃
┃ ┃ ┃
┗━━━━━━━┻━━━━━━━━━━━━━━━┛
<레이아웃>
1. 메인프레임 해더에서
CSplitterWnd m_wndSplitter;
CSplitterWnd m_wndSplitter2;
CSplitterWnd m_wndSplitter3;
CSplitterWnd m_wndSplitter4;
CMenuView* m_pMenuView;
CMFC0609View* m_pBaseView;
CView1* m_pView1;
CView2* m_pView2;
CView3* m_pView3;
BOOL m_bView; //생성자에서 FALSE로 초기화
2. 메인프레임의 OnCreateClient에서
m_wndSplitter.CreateStatic(this, 1, 2)
m_wndSplitter2.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD | WS_VISIBLE | WS_BORDER,
m_wndSplitter.IdFromRowCol(0, 1))
m_wndSplitter3.CreateStatic(&m_wndSplitter2, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER,
m_wndSplitter2.IdFromRowCol(0, 0))
m_wndSplitter4.CreateStatic(&m_wndSplitter3, 2, 1, WS_CHILD | WS_VISIBLE | WS_BORDER,
m_wndSplitter3.IdFromRowCol(0, 1))
CRect rt;
GetClientRect( &rt );
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMenuView), CSize(1, 1), pContext); //폼뷰
m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CView1), CSize(1, 1), pContext);
m_wndSplitter3.CreateView(0, 0, RUNTIME_CLASS(CMFC0609View), CSize(1, 1), pContext);
m_wndSplitter4.CreateView(0, 0, RUNTIME_CLASS(CView2), CSize(1, 1), pContext);
m_wndSplitter4.CreateView(1, 0, RUNTIME_CLASS(CView3), CSize(1, 1), pContext);
SetActiveView( (CView*)m_wndSplitter.GetPane(0, 0) ); //처음 포커스를 줄 뷰를 선택한다.
//뷰 클래스 포인터 객체 초기화
m_pMenuView = (CMenuView *)m_wndSplitter.GetPane( 0, 0 );
m_pBaseView = (CMFC0609View *)m_wndSplitter2.GetPane( 1, 0 );
m_pView1 = (CView1 *)m_wndSplitter3.GetPane( 0, 0 );
m_pView2 = (CView2 *)m_wndSplitter4.GetPane( 0, 0 );
m_pView3 = (CView3 *)m_wndSplitter4.GetPane( 1, 0 );
m_bView = TRUE;
return TRUE;
3. 메뉴설정( 원래사이즈, 베이스뷰, view1, view2, view3, 폼뷰 )
void CMainFrame::OnResize() //원래 사이즈로
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, rt.Width() / 3, 10);
m_wndSplitter2.SetRowInfo(0, rt.Height() / 3 * 2, 10);
m_wndSplitter3.SetColumnInfo(0, rt.Width() / 3, 10);
m_wndSplitter4.SetRowInfo(0, rt.Height() / 3, 10);
m_wndSplitter.RecalcLayout();
m_wndSplitter2.RecalcLayout();
m_wndSplitter3.RecalcLayout();
m_wndSplitter4.RecalcLayout();
}
void CMainFrame::OnView1()
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, 0, 1);
m_wndSplitter2.SetRowInfo(0, 0, 1);
m_wndSplitter.RecalcLayout();
m_wndSplitter2.RecalcLayout();
}
void CMainFrame::OnView2()
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, 0, 1);
m_wndSplitter2.SetRowInfo(0, rt.Height(), 1);
m_wndSplitter3.SetColumnInfo(0, 0, 1);
m_wndSplitter4.SetRowInfo(0, rt.Height(), 1);
m_wndSplitter.RecalcLayout();
m_wndSplitter2.RecalcLayout();
m_wndSplitter3.RecalcLayout();
m_wndSplitter4.RecalcLayout();
}
void CMainFrame::OnView3()
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, 0, 1);
m_wndSplitter2.SetRowInfo(0, rt.Height(), 1);
m_wndSplitter3.SetColumnInfo(0, 0, 1);
m_wndSplitter4.SetRowInfo(0, 0, 1);
m_wndSplitter.RecalcLayout();
m_wndSplitter2.RecalcLayout();
m_wndSplitter3.RecalcLayout();
m_wndSplitter4.RecalcLayout();
}
void CMainFrame::OnFormview()
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, rt.Width(), 1);
m_wndSplitter.RecalcLayout();
}
void CMainFrame::OnBaseview()
{
CRect rt;
GetClientRect( &rt );
m_wndSplitter.SetColumnInfo(0, 0, 1);
m_wndSplitter2.SetRowInfo(0, rt.Height(), 1);
m_wndSplitter3.SetColumnInfo(0, rt.Width(), 1);
m_wndSplitter.RecalcLayout();
m_wndSplitter2.RecalcLayout();
m_wndSplitter3.RecalcLayout();
}
4. 메인프레임의 OnSize오버라이드
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
if( !m_bView ) return;
OnResize();
}
[출처] 여러개의 뷰를 만들고 뷰 전환|작성자 토토로