在vs2010中,單文檔程序切換不同視圖怎麼辦?

haolly 2013-06-10 02:28:23
網上找了些代碼,可是看不懂啊。
它的代碼主要是:
一:在App類的Initinstance函數中創建視圖:
m_pView = (CView*)((CMainFrame*)m_pMainWnd)->GetActiveView();
m_pFormView = (CView*)new CMyFormView;
CCreateContext context;
context.m_pCurrentDoc = ((CMainFrame*)m_pMainWnd)->GetActiveDocument();
UINT uid = AFX_IDW_PANE_FIRST + 1;
CRect rt;
m_pFormView->Create(NULL, NULL, WS_CHILD, rt, m_pMainWnd, uid, &context);

二:然後在菜單切換視圖時調用下面的函數:
void CSDIMultiViewApp::ShowView(void)
{
LONG lId = GetWindowLong(m_pView->m_hWnd, GWL_ID);
::SetWindowLong(((CMainFrame*)m_pMainWnd)->GetActiveView()->m_hWnd, GWL_ID,
GetWindowLong(((CMainFrame*)m_pMainWnd)->m_hWnd, GWL_ID));
::SetWindowLong(m_pView->m_hWnd, lId, GWL_ID);
::ShowWindow(((CMainFrame*)m_pMainWnd)->GetActiveView()->m_hWnd, SW_HIDE);
((CMainFrame*)m_pMainWnd)->SetActiveView(m_pView);
((CMainFrame*)m_pMainWnd)->RecalcLayout();
::ShowWindow(m_pView->m_hWnd, SW_SHOWMAXIMIZED);
}

void CSDIMultiViewApp::ShowForm(void)
{
LONG lId = GetWindowLong(m_pFormView->m_hWnd, GWL_ID);

::SetWindowLong(((CMainFrame*)m_pMainWnd)->GetActiveView()->m_hWnd, GWL_ID,
GetWindowLong(((CMainFrame*)m_pMainWnd)->m_hWnd, GWL_ID));
::SetWindowLong(m_pFormView->m_hWnd,lId, GWL_ID);
//SetWindowLong(m_pFormView->m_hWnd,lId, GWL_ID)最後兩個參數有問題吧?

::ShowWindow(((CMainFrame*)m_pMainWnd)->GetActiveView()->m_hWnd, SW_HIDE);

((CMainFrame*)m_pMainWnd)->SetActiveView(m_pFormView);
((CMainFrame*)m_pMainWnd)->RecalcLayout();

::ShowWindow(m_pFormView->m_hWnd, SW_SHOWMAXIMIZED);
//这些代码能解释下不?
}


可是我有十几个视图要切换,总不能都在Initinstance函数中创建吧?
我想在点击菜单切换视图时才创建。哪位大神告诉我该怎么办?
...全文
153 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wushuang443 2014-11-05
  • 打赏
  • 举报
回复
这种切换不切实际。销毁旧的视图。创建新的视图。
schlafenhamster 2013-06-13
  • 打赏
  • 举报
回复
“有值,但现实是红色的” 不是0; 就是对的 再 F10 单步下去。。。。
haolly 2013-06-13
  • 打赏
  • 举报
回复
哈哈,解决了。我把RecalcLayout();这句放到最后就可以了
haolly 2013-06-12
  • 打赏
  • 举报
回复
引用 9 楼 schlafenhamster 的回复:
F9 断点在 CView* pOldView = GetActiveView(); 运行,停到断点时 看 指针是不是有 值。。。,再 F10 单步 下去
有值,但现实是红色的
schlafenhamster 2013-06-12
  • 打赏
  • 举报
回复
F9 断点在 CView* pOldView = GetActiveView(); 运行,停到断点时 看 指针是不是有 值。。。,再 F10 单步 下去
haolly 2013-06-12
  • 打赏
  • 举报
回复
引用 7 楼 schlafenhamster 的回复:
“这是旧视图” 说明新视图 没有产生。 单步调试 看看。
不会啊。调试也看不出什么啊%>_<%
schlafenhamster 2013-06-12
  • 打赏
  • 举报
回复
“这是旧视图” 说明新视图 没有产生。 单步调试 看看。
haolly 2013-06-12
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
void CMainFrame::SwitchViews(int ID) 你改过的代码,给我们看看
void CMainFrame::SwitchViews(int nForm)
{
	CView* pOldView = GetActiveView();
	CView* pNewView;
	CCreateContext cc;
	cc.m_pCurrentDoc = pOldView->GetDocument();
	CString title;
	switch(nForm)
	{
		case IDD_NEWFORM:
			pNewView = (CView*) new CNewform;
			title+=_T("New form");
			break;
		case IDD_CHANGEFORM2_FORM:
			pNewView = (CView*) new Cchangeform2View;
			title+= _T("Original view");
			break;
	}
	pNewView->Create(NULL,NULL,WS_CHILD|WS_BORDER,CFrameWndEx::rectDefault,
					this,nForm,&cc);
	pNewView->OnInitialUpdate();
	SetActiveView(pNewView);
	pNewView->ShowWindow(SW_SHOW);

	SetWindowLong(pNewView->m_hWnd,GWL_ID,AFX_IDW_PANE_FIRST);
	RecalcLayout();

	pOldView->DestroyWindow();
	SetWindowText(title);
}


void CMainFrame::OnMenuOrig()
{
	// TODO: 在此添加命令处理程序代码
	CView *pOldView=(CView *)GetActiveView();
	if (pOldView->GetRuntimeClass()==RUNTIME_CLASS(Cchangeform2View))
	{
		return;
	}
	SwitchViews(IDD_CHANGEFORM2_FORM);
}


void CMainFrame::OnNewView()
{
	// TODO: 在此添加命令处理程序代码
	CView *pOldView=(CView *)GetActiveView();
	if (pOldView->GetRuntimeClass()==RUNTIME_CLASS(CNewform))
	{
		return;
	}
	SwitchViews(IDD_NEWFORM);
}
schlafenhamster 2013-06-12
  • 打赏
  • 举报
回复
void CMainFrame::SwitchViews(int ID) 你改过的代码,给我们看看
haolly 2013-06-12
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
"需要重新最小化后再打开,才能显示"
显示 的是什么 ? 新 view 还是 没 变 ?




点一下就这样
schlafenhamster 2013-06-12
  • 打赏
  • 举报
回复
"需要重新最小化后再打开,才能显示" 显示 的是什么 ? 新 view 还是 没 变 ?
haolly 2013-06-12
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:

void CMainFrame::SwitchViews(int ID)
{
	CView* pOldActiveView = GetActiveView();
	CView* pNewActiveView;
	CCreateContext cc;
	cc.m_pCurrentDoc=pOldActiveView->GetDocument();
	CString title=cc.m_pCurrentDoc->GetPathName();;
// which one
	switch (ID)
	{
	case 1://
		pNewActiveView=(CView*) new CWinOh51View;
		title += " Binary View";
		break;
	case 2://
		pNewActiveView=(CView*) new CFormatView;
		title += " Formated View";
		break;
	case 3://
		pNewActiveView=(CView*) new CFlashView;
		title += " Flash View";
		break;
	case 4://
		pNewActiveView=(CView*) new CHexView;
		title += " Hex View";
		break;
	}
// Create new 
	pNewActiveView->Create(0,0,0,CFrameWnd::rectDefault,this,ID,&cc);	
	pNewActiveView->OnInitialUpdate();
	SetActiveView(pNewActiveView);
	pNewActiveView->ShowWindow(SW_SHOW);
// Exchange view window ID's so RecalcLayout() works.
	SetWindowLong(pNewActiveView->m_hWnd, GWL_ID,AFX_IDW_PANE_FIRST);
	RecalcLayout();
//If we use: delete pOldActiveView,
//we got : Warning: calling DestroyWindow in CWnd::~CWnd,
//OnDestroy or PostNcDestroy in derived class will not be called.
	pOldActiveView->DestroyWindow();
// new title
	SetWindowText(title);
}
//
void CMainFrame::OnSwitchViews() 
{
	// TODO: Add your command handler code here
	CView *pOldView=(CView *)GetActiveView();
//CHexView
	if(pOldView->IsKindOf(RUNTIME_CLASS(CWinOh51View)))
	{
		SwitchViews(2);//CFormatView
	}
	else if (pOldView->IsKindOf(RUNTIME_CLASS(CFormatView)))
	{
		SwitchViews(3);//CFlashView
	}
	else if (pOldView->IsKindOf(RUNTIME_CLASS(CFlashView)))
	{
		SwitchViews(4);//CHexView
	}
	else //(pOldView->IsKindOf(RUNTIME_CLASS(CHexView)))
	{
		SwitchViews(1);//CWinOh51View
	}
}

不怎麼管用啊,在菜单项点击后,没反应,需要重新最小化后再打开,才能显示
schlafenhamster 2013-06-10
  • 打赏
  • 举报
回复

void CMainFrame::SwitchViews(int ID)
{
	CView* pOldActiveView = GetActiveView();
	CView* pNewActiveView;
	CCreateContext cc;
	cc.m_pCurrentDoc=pOldActiveView->GetDocument();
	CString title=cc.m_pCurrentDoc->GetPathName();;
// which one
	switch (ID)
	{
	case 1://
		pNewActiveView=(CView*) new CWinOh51View;
		title += " Binary View";
		break;
	case 2://
		pNewActiveView=(CView*) new CFormatView;
		title += " Formated View";
		break;
	case 3://
		pNewActiveView=(CView*) new CFlashView;
		title += " Flash View";
		break;
	case 4://
		pNewActiveView=(CView*) new CHexView;
		title += " Hex View";
		break;
	}
// Create new 
	pNewActiveView->Create(0,0,0,CFrameWnd::rectDefault,this,ID,&cc);	
	pNewActiveView->OnInitialUpdate();
	SetActiveView(pNewActiveView);
	pNewActiveView->ShowWindow(SW_SHOW);
// Exchange view window ID's so RecalcLayout() works.
	SetWindowLong(pNewActiveView->m_hWnd, GWL_ID,AFX_IDW_PANE_FIRST);
	RecalcLayout();
//If we use: delete pOldActiveView,
//we got : Warning: calling DestroyWindow in CWnd::~CWnd,
//OnDestroy or PostNcDestroy in derived class will not be called.
	pOldActiveView->DestroyWindow();
// new title
	SetWindowText(title);
}
//
void CMainFrame::OnSwitchViews() 
{
	// TODO: Add your command handler code here
	CView *pOldView=(CView *)GetActiveView();
//CHexView
	if(pOldView->IsKindOf(RUNTIME_CLASS(CWinOh51View)))
	{
		SwitchViews(2);//CFormatView
	}
	else if (pOldView->IsKindOf(RUNTIME_CLASS(CFormatView)))
	{
		SwitchViews(3);//CFlashView
	}
	else if (pOldView->IsKindOf(RUNTIME_CLASS(CFlashView)))
	{
		SwitchViews(4);//CHexView
	}
	else //(pOldView->IsKindOf(RUNTIME_CLASS(CHexView)))
	{
		SwitchViews(1);//CWinOh51View
	}
}

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧