发现了一个教程,但是弄了半天都不知道为什么做错,大家帮忙一下,我发现我运行的时候有断言错误,在定义SwitchToView函数CView* pOldActiveView = (CView*)pFrame->GetActiveView();出错,还有一个是野指针的问题:OnInitDialog()函数
((CFrameWnd*)this)->SetActiveView(m_pView1);我就发现这个两个问题,不知道是我操作错了,还是什么,你们帮我看看,谢谢,原文如下:在MFC的SDI和MDI文档结构中能很方便的嵌入多视图,而有时候则要在对话框中嵌入多视图,下面是方法。
1.插入三个对话框
ID分别为IDD_VIEW1_FORM,IDD_VIEW2_FORM,IDD_VIEW3_FORM,把三个对话框的属性Style设为Child,Border设为None,映射CView1,CView2,CView3分别对应三个对话框,CView1,CView2,CView3都派生自CFormView。
2.在对话框中加入三个成员变量:
CView1 *m_pView1;
CView2 *m_pView2;
CView3 *m_pView3;
3.映射对话框WM_INITDIALOG消息,在OnInitDialog()函数中加入创建视图窗口的代码.
(注意一定要用(CView*)把三个成员变量的类型转换成CView*类型,不然调用的就是CFormView::Create,但是CFromView的Create是protected类型,不能调用)
//create view1
m_pView1 = new CView1;
ASSERT(m_pView1 != NULL);if (!((CView*)m_pView1)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view1 failed"));
return TRUE;
}m_pView1->ShowWindow(SW_HIDE);
m_pView1->OnInitialUpdate();
//create view2
m_pView2 = new CView2;
ASSERT(m_pView2 != NULL);if (!((CView*)m_pView2)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view2 failed"));
return TRUE;
}m_pView2->ShowWindow(SW_HIDE);
m_pView2->OnInitialUpdate();
//create view3
m_pView3 = new CView3;
ASSERT(m_pView3 != NULL);if (!((CView*)m_pView3)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view3 failed"));
return TRUE;
}m_pView3->ShowWindow(SW_HIDE);
m_pView3->OnInitialUpdate();//move view in the dialog
CRect rect;
GetWindowRect(&rect);
ScreenToClient(rect);
rect.DeflateRect(200, 0, 0, 0);
m_pView1->MoveWindow(&rect);
m_pView2->MoveWindow(&rect);
m_pView3->MoveWindow(&rect);((CFrameWnd*)this)->SetActiveView(m_pView1);
m_pView1->ShowWindow(SW_SHOW);
m_pView1->SetDlgCtrlID(AFX_IDW_PANE_FIRST); ...... 在对话框中按顺序加入三个radio box,在第一个radio box中勾上group选项(三个radio box 靠左边放,注意不要被嵌入的视图覆盖住。。在映射按钮消息函数中加入SwitchToView函数。(SwitchToView用来切换视图)
void Cxxxxx::OnRadio1()
{
SwitchToView(IDD_VIEW1_FORM);
}void Cxxxxx::OnRadio2()
{
SwitchToView(IDD_VIEW2_FORM);
}void Cxxxxx::OnRadio3()
{
SwitchToView(IDD_VIEW3_FORM);
}SwitchToView的函数定义为:
void Cxxxxx::SwitchToView(UINT uViewID)
{
//the following statement is important!!!
CFrameWnd *pFrame = (CFrameWnd*)this;//only for debug
ASSERT_VALID(pFrame);
CView *pNewActiveView = NULL;
CView* pOldActiveView = (CView*)pFrame->GetActiveView();switch(uViewID)
{
case IDD_VIEW1_FORM:
pNewActiveView = m_pView1;
break;
case IDD_VIEW2_FORM:
pNewActiveView = m_pView2;
break;
case IDD_VIEW3_FORM:
pNewActiveView = m_pView3;
break;
default:
AfxMessageBox(_T("invalid view id"));
return;
}ASSERT(pOldActiveView!=NULL && pNewActiveView!=NULL);if (pNewActiveView == pOldActiveView)
return;pNewActiveView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
pFrame->SetActiveView(pNewActiveView);if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView1)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW1_FORM);
else if(pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView2)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW2_FORM);
else if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView3)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW3_FORM);
//set the identity of current active view
pNewActiveView -> SetDlgCtrlID(AFX_IDW_PANE_FIRST);
}
((CFrameWnd*)this)->SetActiveView(m_pView1);我就发现这个两个问题,不知道是我操作错了,还是什么,你们帮我看看,谢谢,原文如下:在MFC的SDI和MDI文档结构中能很方便的嵌入多视图,而有时候则要在对话框中嵌入多视图,下面是方法。
1.插入三个对话框
ID分别为IDD_VIEW1_FORM,IDD_VIEW2_FORM,IDD_VIEW3_FORM,把三个对话框的属性Style设为Child,Border设为None,映射CView1,CView2,CView3分别对应三个对话框,CView1,CView2,CView3都派生自CFormView。
2.在对话框中加入三个成员变量:
CView1 *m_pView1;
CView2 *m_pView2;
CView3 *m_pView3;
3.映射对话框WM_INITDIALOG消息,在OnInitDialog()函数中加入创建视图窗口的代码.
(注意一定要用(CView*)把三个成员变量的类型转换成CView*类型,不然调用的就是CFormView::Create,但是CFromView的Create是protected类型,不能调用)
//create view1
m_pView1 = new CView1;
ASSERT(m_pView1 != NULL);if (!((CView*)m_pView1)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view1 failed"));
return TRUE;
}m_pView1->ShowWindow(SW_HIDE);
m_pView1->OnInitialUpdate();
//create view2
m_pView2 = new CView2;
ASSERT(m_pView2 != NULL);if (!((CView*)m_pView2)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view2 failed"));
return TRUE;
}m_pView2->ShowWindow(SW_HIDE);
m_pView2->OnInitialUpdate();
//create view3
m_pView3 = new CView3;
ASSERT(m_pView3 != NULL);if (!((CView*)m_pView3)->Create(NULL, NULL, WS_CHILD,
CRect(0, 0, 0, 0), this, NULL, NULL))
{
AfxMessageBox(_T("Create view3 failed"));
return TRUE;
}m_pView3->ShowWindow(SW_HIDE);
m_pView3->OnInitialUpdate();//move view in the dialog
CRect rect;
GetWindowRect(&rect);
ScreenToClient(rect);
rect.DeflateRect(200, 0, 0, 0);
m_pView1->MoveWindow(&rect);
m_pView2->MoveWindow(&rect);
m_pView3->MoveWindow(&rect);((CFrameWnd*)this)->SetActiveView(m_pView1);
m_pView1->ShowWindow(SW_SHOW);
m_pView1->SetDlgCtrlID(AFX_IDW_PANE_FIRST); ...... 在对话框中按顺序加入三个radio box,在第一个radio box中勾上group选项(三个radio box 靠左边放,注意不要被嵌入的视图覆盖住。。在映射按钮消息函数中加入SwitchToView函数。(SwitchToView用来切换视图)
void Cxxxxx::OnRadio1()
{
SwitchToView(IDD_VIEW1_FORM);
}void Cxxxxx::OnRadio2()
{
SwitchToView(IDD_VIEW2_FORM);
}void Cxxxxx::OnRadio3()
{
SwitchToView(IDD_VIEW3_FORM);
}SwitchToView的函数定义为:
void Cxxxxx::SwitchToView(UINT uViewID)
{
//the following statement is important!!!
CFrameWnd *pFrame = (CFrameWnd*)this;//only for debug
ASSERT_VALID(pFrame);
CView *pNewActiveView = NULL;
CView* pOldActiveView = (CView*)pFrame->GetActiveView();switch(uViewID)
{
case IDD_VIEW1_FORM:
pNewActiveView = m_pView1;
break;
case IDD_VIEW2_FORM:
pNewActiveView = m_pView2;
break;
case IDD_VIEW3_FORM:
pNewActiveView = m_pView3;
break;
default:
AfxMessageBox(_T("invalid view id"));
return;
}ASSERT(pOldActiveView!=NULL && pNewActiveView!=NULL);if (pNewActiveView == pOldActiveView)
return;pNewActiveView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
pFrame->SetActiveView(pNewActiveView);if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView1)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW1_FORM);
else if(pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView2)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW2_FORM);
else if (pOldActiveView -> IsKindOf(RUNTIME_CLASS(CView3)))
pOldActiveView -> SetDlgCtrlID(IDD_VIEW3_FORM);
//set the identity of current active view
pNewActiveView -> SetDlgCtrlID(AFX_IDW_PANE_FIRST);
}
不能CFrameWnd *pFrame = (CFrameWnd*)this(this指针代表对话框)
因为他们属于不同的类,Cwnd* p=(Cwnd*) this;这样是可以的,因为CDialog是从
Cwnd中派生的!学编程的时候,不要人家怎么写,你也跟着怎么写,要理解人家的意图!根据自己的需要去做!其实你完全没必要做转换操作,直接保存一个CView * m_pNewActiveView
做全局变量,不就可以了吗?
俺的程序从网上抄的,这样在dialog中挂了一个frameint
CCommonScriptDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
// Because the CFRameWnd needs a window class, we will create
// a new one. I just copied the sample from MSDN Help.
// When using it in your project, you may keep CS_VREDRAW and
// CS_HREDRAW and then throw the other three parameters.
CString strMyClass = AfxRegisterWndClass( CS_VREDRAW |
CS_HREDRAW,
::LoadCursor( NULL, IDC_ARROW ),
( HBRUSH )::GetStockObject( WHITE_BRUSH ),
::LoadIcon( NULL, IDI_APPLICATION ) ); // Create the frame window with "this" as the parent
m_pFrame = new CCommonScriptFrame();
m_pFrame->SetID( IDR_TOOLBAR_COMMON_SCRIPT_CN, IDR_TOOLBAR_COMMON_SCRIPT_EN ); m_pFrame->Create( strMyClass, _T( "Common Script Tool View" ) , WS_CHILD,
CRect( 0, 0, 1, 1 ), this );
//m_pFrame->ShowWindow( SW_SHOW );
m_pFrame->MoveWindow( 0, 0, 300, 300 ); return 0;
}
{
if (CDialogFrame::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CCreateContext ccc;
ccc.m_pNewViewClass = RUNTIME_CLASS( CConnect_Spy_View );
ccc.m_pCurrentDoc = NULL;
ccc.m_pNewDocTemplate = NULL;
ccc.m_pLastView = NULL;
ccc.m_pCurrentFrame = this; // Because the CFRameWnd needs a window class, we will create
// a new one. I just copied the sample from MSDN Help.
// When using it in your project, you may keep CS_VREDRAW and
// CS_HREDRAW and then throw the other three parameters.
//CString strMyClass = AfxRegisterWndClass( CS_VREDRAW |
// CS_HREDRAW,
// ::LoadCursor( NULL, IDC_ARROW ),
// ( HBRUSH )::GetStockObject( WHITE_BRUSH ),
// ::LoadIcon( NULL, IDI_APPLICATION ) ); m_pView = ( CConnect_Spy_View * )( this->CreateView( &ccc ) );
::SendMessage( m_pView->GetSafeHwnd(), WM_INITIALUPDATE, 0, 0 ); this->SetActiveView( ( CView * )m_pView );
return 0;
}这样又在frame中加载了一个view,这里是formview,这个view中你想加嵌套再加载一个frame也行,分隔成多个view也行,加载toolbar,状态条等都行。
void Cxxxxx::OnRadio1()
{
SwitchToView(IDD_VIEW1_FORM);
}void Cxxxxx::OnRadio2()
{
SwitchToView(IDD_VIEW2_FORM);
}void Cxxxxx::OnRadio3()
{
SwitchToView(IDD_VIEW3_FORM);
}改成
void CXXX::OnRadio1()
{
m_pView1->ShowWindow(SW_SHOW);
m_pView1->OnInitialUpdate();
}void CXXX::OnRadio2()
{
m_pView2->ShowWindow(SW_SHOW);
m_pView2->OnInitialUpdate();
}void CXXX::OnRadio3()
{
m_pView3->ShowWindow(SW_SHOW);
m_pView3->OnInitialUpdate();
}程序就可以运行了。
error C2248: 'CView1::CView1' : cannot access protected member declared in class 'CView1'
view1.h(20) : see declaration of 'CView1::CView1'
m_pView = new CMyView;
if (!m_pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST, NULL))
{
EndDialog(IDABORT);
}
CMyDoc* pDoc = new CMyDoc;//不需要DOC类,注释掉
pDoc->AddView(m_pView);//不需要DOC类,注释掉
m_pView->SendMessage(WM_INITIALUPDATE, 0, 0);
不要用SetActiveView(),因为是CFrameWnd的函数,用CDialog盗用这个函数,是会报错的。
切换时只需显示隐藏相应的对象就行了。