哈哈,小弟通过一番查阅。终于找到了正解。单文本文档要切换视图,首先要考虑的还是视图和文档的关联。正如我在1楼问题中的做法,可以在BOOL CMyApp::InitInstance()中CSingleDocTemplate* pDocTemplate的构造函数那pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMainFrame),
// main SDI frame window
RUNTIME_CLASS(CMyView));
//改变这个类的类型就可以达到切换视图的效果
AddDocTemplate(pDocTemplate);
但是这个办法有个重大的缺点,就是只能在程序运行改好。程序运行后便无法更改视图了。
通过多次尝试和查阅资料,兄弟终于找到了运行时程序切换视图的方法:
思路:
1,使用VC6编译器菜单中插入,通过需要的视类CView,CEditView,等派生出自己需要的类。例如我需要切换的类有2个,CSwitchView ,CMyEditView .还有一个是默认的CMyView类。那么通过插入的时候要插入3个类:
一个CSwitchView ,派生自CView。
一个CMyEditView,派生自CEditView。
还有一个CDefaultView,派生自CMyView同类型的类,用来还原被替换的默认视类。
之后将三个插入类的无参构造函数由protected:改为public:
2,在CMainFram中加入三个成员变量:
public:
CSwitchView* m_stv;
CMyEditView* m_mev;
CDefaultView* m_dfv;
3,在适当的切换函数(按照我1楼的做法应该是在菜单消息响应函数中)中new 出需要切换的类。
例如:
m_stv=new CSwtichView();
//在这里可以看出为什么改变无参构造函数的权限
4,使用视类Create函数,利用他的参数中有CContext变量,使之与文档类相关连。
例如替换函数在CMainFrame中(以后的代码也默认为写在CMainFrame类的某个函数中)。
CMyDocument* pDoc=(CMyDocument*)GetDocment();
CContext ctx;
ctx.m_pCurrentDoc=pDoc;
//得到主窗口客户区大小。
CRect m_clientrt,rt2,rt3;
GetClientRect(&m_clientrt);
//调整这个区域大小,使之与工具条,状态条相融合。
m_wndStatusBar.GetClientRect(&rt3);
m_wndToolBar.GetClientRect(&rt2);
m_clientrt.top=m_clientrt.top+rt2.bottom;
m_clientrt.bottom=m_clientrt.bottom-rt3.bottom;
//我的这个方法有点笨,欢迎知道简单方法的朋友发帖交流。
m_stv->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,m_clientrt,(CMainFrame*)AfxGetMainWnd(),AFX_IDW_PANE_FIRST + 1,&tempcontext);
//这里有个小技巧,创建单文本的视图类,其Id必须是AFX_IDW_PANE_FIRST,我们这里先用AFX_IDW_PANE_FIRST+1,因为还没有替换默认的那个视图类,直接使用AFX_IDW_PANE_FIRST的话,Id就与现在正在使用的类的Id重了。
5,用我们Create的视类与默认的视类换ID。
CView* currentview= GetActciveView();
//得到现在正在使用类的指针
int nID=m_stv->GetDlgCtrlID();//保留原来Create时的ID
m_stv->SetDlgCtrlID(AFX_IDW_PANE_FIRST);//换ID为我们最想用的AFX_IDW_PANE_FIRST
currentview->SetDlgCtrlID(nID);//把老ID换给被换下来的类。
6,用ShowWindow()显示换上的类,隐藏换下来的类。
currentview->ShowWindow(SW_HIDE);
m_stv->ShowWindow(SW_SHOW);
7,SetActiveView()与RecalcLayout(),设置活动类并重新展开窗口。
SetActiveView(m_tryview);
RecalcLayout();
哈哈,这样就完成了单文本文档的替换,偷天换日啊。完成类的插入,构造函数权限的改变,成员变量的声明后。完整的代码:
m_stv=new CSwtichView();
CMyDocument* pDoc=(CMyDocument*)GetDocment();
CContext ctx;
ctx.m_pCurrentDoc=pDoc;
CRect m_clientrt,rt2,rt3;
GetClientRect(&m_clientrt);
m_wndStatusBar.GetClientRect(&rt3);
m_wndToolBar.GetClientRect(&rt2);
m_clientrt.top=m_clientrt.top+rt2.bottom;
m_clientrt.bottom=m_clientrt.bottom-rt3.bottom;
m_stv->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,m_clientrt,(CMainFrame*)AfxGetMainWnd(),AFX_IDW_PANE_FIRST + 1,&tempcontext);
CView* currentview= GetActciveView();
int nID=m_stv->GetDlgCtrlID();
m_stv->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
currentview->SetDlgCtrlID(nID);
currentview->ShowWindow(SW_HIDE);
m_stv->ShowWindow(SW_SHOW);
SetActiveView(m_tryview);
RecalcLayout();
替换其他的类使用的方法和上面类似,不再累述,如果有更简单方法的朋友,还请发帖回复交流。。。:)
[[it] 本帖最后由 VanHorn 于 2008-6-30 20:26 编辑 [/it]]