经过多方寻找资料和反复试验,终于实现了在单文档程序中分割窗口,并且可以对视图进行随意切换,以下是比较详尽的步骤:
1,向导第四步,选高级,“使用分割栏”挑勾,原始view类为cmyview,派生自cview类
2,要想加入从其他view类派生的类,如cformview等,应该在stdafx.h中加入#include <afxcview.h>
3,加入新类ctview,派生自ctreeview,编辑初始化ctview::oninitialupdate() 代码如下
void ctview::oninitialupdate()
{
ctreeview::oninitialupdate();
// todo: add your specialized code here and/or call the base class
ctreectrl &treectrl=gettreectrl();
dword dwstyle=::getwindowlong(treectrl.m_hwnd,gwl_style);
dwstyle|=tvs_hasbuttons|tvs_haslines|tvs_linesatroot;
::setwindowlong(treectrl.m_hwnd,gwl_style,dwstyle);
htreeitem hroot,hcurpos;
tv_insertstruct tinsert;
tinsert.hparent=tvi_root;
tinsert.hinsertafter=tvi_last;
tinsert.item.mask=tvif_text|tvif_param;
tinsert.item.psztext="分类";
tinsert.item.lparam=0;
hroot=treectrl.insertitem(&tinsert);
char *plant[4]={"编程","小说","科学","人文"};
char *cell[4][5]={
{"vc++","delphi","bcb","",""},//主系统运行日志
{"武侠","侦探","言情","恐怖","悬疑"},
{"天文","地理","自然","",""},
{"社会科学","","","",""}
};
int i,j;
for(i=0;i<4;i++)
{
tinsert.hparent=hroot;
tinsert.item.psztext=plant[i];
hcurpos=treectrl.insertitem(&tinsert);
for(j=0;j<5;j++)
{
tinsert.hparent=hcurpos;
if(cell[i][j]!="")
{
tinsert.item.psztext=cell[i][j];
treectrl.insertitem(&tinsert);}
}
//treectrl.expand(hcurpos,tve_expand);
}
treectrl.expand(hroot,tve_expand);
}
4,加入cformview派生类,先加入一个对话框资源,在对话框属性中,指定styles->style:child
border:none,不选title bar 在more styles中不选可见。然后在新建的cformview的派生类cfview中指定对话框为刚建的对话框
5,因为每个cview派生类都已经继承了getdocument()函数,因此只要在调用时直接调用无需再在其中声明getdocument()函数了,调用后再进行类型强制转换应该就可以了。比方,在cmyview.h中注释掉
// attributes
// cmydoc* getdocument();
在cmyview.cpp中注释掉
//cmydoc* cmyview::getdocument() // non-debug version is inline
//{
//assert(m_pdocument->iskindof(runtime_class(cmydoc)));
//return (cmydoc*)m_pdocument;
//}
并在ondraw中试用如下代码
void cmyview::ondraw(cdc* pdc)
{
cmydoc* pdoc =(cmydoc*)cmyview:: getdocument();
assert_valid(pdoc);
// todo: add draw code for native data here
}
7,为了使新加的view派生类能够被方便的调用,可以将这些view派生类的构造函数由protected改为public
8,加入一个新类cmysplitter,派生自cmdichildwnd类,然后将代码中所有的cmdichildwnd改成csplitterwnd
在mainfrm.h中加入#include "mysplitter.h",并将csplitterwnd m_wndsplitter;改成
cmysplitter m_wndsplitter;
9,给cmysplitter类加入一个publice型成员函数
bool replaceview(int row, int col,cruntimeclass * pviewclass,size size);
编辑代码如下
bool cmysplitter::replaceview(int row, int col, cruntimeclass *pviewclass, size size)
{
ccreatecontext context;
bool bsetactive;
if ((getpane(row,col)->iskindof(pviewclass))==true)
return false;
// get pointer to cdocument object so that it can be used in the creation
// process of the new view
cdocument * pdoc= ((cview *)getpane(row,col))->getdocument();
cview * pactiveview=getparentframe()->getactiveview();
if (pactiveview==null || pactiveview==getpane(row,col))
bsetactive=true;
else
bsetactive=false;