请教MDI中新建子窗口的问题!

zhstars 2008-07-15 10:30:39
我以前一直用SDI,现在用MDI,请教2个问题:
1.frame/doc/view是关联的,我新建子窗口做不同的工作,是不是每新建一个不同的view类就必须建一个新的frame/doc呢?
2.还是上面这个问题,一个doc能否对应多个不同的view呢?如果可以,则如何得到这些不通view的指针呢?

多谢各位!我结贴向来很及时的!
...全文
208 点赞 收藏 7
写回复
7 条回复
zhstars 2008年07月15日
补充一下,如果一个doc可以对应不同的view,请问代码是怎么实现的?
回复 点赞
zhstars 2008年07月15日
to gofqjyie:
那第二个问题呢?怎么取得不同View的指针呢?
回复 点赞
长尾巴的悟空 2008年07月15日
一分文档可以对应不同的view
回复 点赞
zhstars 2008年07月15日
你给的资料我自己有,而且看了好几遍了,还是没有弄明白!
回复 点赞
hua_yang 2008年07月15日
引用高手 guoxiny(狼)的一段,希望有所帮助

10) 从文档类取得视图类的指针
我是从http://download.cqcnc.com/soft/program/article/vc/vc405.html学到的,
从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题,我的体会
特别是文字处理CEditView当产生多个视图类时,这个功能是非常需要的。
CDocument类提供了两个函数用于视图类的定位:
GetFirstViewPosition()和GetNextView()
virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION& rPosition) const;

注意:GetNextView()括号中的参数用的是引用方式,因此执行后值可能改变。
GetFirstViewPosition()用于返回第一个视图位置(返回的并非视图类指针,而是一
个POSITION类型值),GetNextView()有两个功能:返回下一个视图类的指针以及用
引用调用的方式来改变传入的POSITION类型参数的值。很明显,在Test程序中,只有
一个视图类,因此只需将这两个函数调用一次即可得到CTestView的指针如下(需定
义一个POSITION结构变量来辅助操作):
CTestView* pTestView;
POSITION pos=GetFirstViewPosition();
pTestView=GetNextView(pos);

这样,便可到了CTestView类的指针pTestView.执行完几句后,变量pos=NULL,因为没
有下一个视图类,自然也没有下一个视图类的POSITION.但是这几条语句太简单,不
具有太强的通用性和安全特征;当象前面说的那样,当要在多个视图为中返回某个指
定类的指针时,我们需要遍历所有视图类,直到找到指定类为止。判断一个类指针指
向的是否某个类的实例时,可用IsKindOf()成员函数时行检查,如:
pView->IsKindOf(RUNTIME_CLASS(CTestView));
即可检查pView所指是否是CTestView类。

有了以上基础,我们已经可以从文档类取得任何类的指针。为了方便,我们将其作
为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。实现如下:
CView* CTestDoc::GetView(CRuntimeClass* pClass)
{
CView* pView;
POSITION pos=GetFirstViewPosition();

while(pos!=NULL){
pView=GetNextView(pos);
if(!pView->IsKindOf(pClass))
break;
}

if(!pView->IsKindOf(pClass)){
AfxMessageBox("Connt Locate the View.\r\n http://www.VCKBASE.com");
return NULL;
}

return pView;
}

其中用了两次视图类的成员函数IsKindOf()来判断,是因为退出while循环有三种
可能:

1.pos为NULL,即已经不存在下一个视图类供操作;
2.pView已符合要求。

1和2同是满足。这是因为GetNextView()的功能是将当前视图指针改变成一个视图
的位置同时返回当前视图指针,因此pos是pView的下一个视图类的POSITION,完全
有可能既是pos==NULL又是pView符合需要。当所需的视图是最后一个视图是最后一
个视图类时就如引。因此需采用两次判断。
使用该函数应遵循如下格式(以取得CTestView指针为例):
CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));
RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为
CRuntimeClass为指针。至于强制类型转换也是为了安全特性考虑的,因为从同一个
基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一
些可能出现的麻烦。

3.从一个视图类取得另一视图类的指针 综合1和2,很容易得出视图类之间互相获得
指针的方法:就是用文档类作中转,先用1的方法得到文档类的指针,再用2的方法,
以文档类的视图定位函数取得另一个视图类。同样,可以实现成一个函数:
(假设要从CTestAView中取得指向其它视图类的指针)
CView* CTestAView::GetView(CRuntimeClass* pClass)
{
CTestDoc* pDoc=(CTestDoc*)GetDocument();
CView* pView;
POSITION pos=pDoc->GetFirstViewPosition();
while(pos!=NULL){
pView=pDoc->GetNextView(pos);
if(!pView->IsKindOf(pClass))
break;
}
if(!pView->IsKindOf(pClass)){
AfxMessageBox("Connt Locate the View.");
return NULL;
}

return pView;
}
这个函数和2中的GetView()相比,一是多了第一句以取得文档类指针,二是在
GetFirstViewPosition()和GetNextView()前加上了文档类指针,以表示它们是文档
类成员函数。有了此函数;当要从CTestAView中取得CTestBView的指针时,只需如
下:CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView));
11)对于单文档中也可以加入多个文档模板,但是一般的开发就使用MDI方式开发
多文档模板,其方法与上述视图的获取方法很接近,这里稍做解释,如果不清楚,
请查阅MSDN,(以下四个内容(11、12、13、14)来源:
http://sanjianxia.myrice.com/vc/vc45.htm)

可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板
的位置;利用该值来调用CWinApp::GetNextDocTemplate函数,获得第一个
CDocTemplate对象指针。 POSITION GetFirstDocTemplate( ) const;
CDocTemplate *GetNextDocTemplate( POSITION & pos ) const;

第二个函数返回由pos 标识的文档模板。POSITION是MFC定义的一个用于迭代或对象
指针检索的值。通过这两个函数,应用程序可以遍历整个文档模板列表。如果被检索
的文档模板是模板列表中的最后一个,则pos参数被置为NULL。

12)一个文档模板可以有多个文档,每个文档模板都保留并维护了一个所有对应文
档的指针列表。
用CDocTemplate::GetFirstDocPosition函数获得与文档模板相关的文档集合中第一
个文档的位置,并用POSITION值作为CDocTemplate::GetNextDoc的参数来重复遍历与
模板相关的文档列表。函数原形为:
viaual POSITION GetFirstDocPosition( ) const = 0;
visual CDocument *GetNextDoc(POSITION & rPos) const = 0;

如果列表为空,则rPos被置为NULL.

13)在文档中可以调用CDocument::GetDocTemplate获得指向该文档模板的指针。
函数原形如下: CDocTemplate * GetDocTemplate ( ) const;
如果该文档不属于文档模板管理,则返回值为NULL。

14)一个文档可以有多个视。每一个文档都保留并维护一个所有相关视的列表。
CDocument::AddView将一个视连接到文档上,将该视加入到文档相联系的视的列表
中,并将视的文档指针指向该文档。当有File/New、File/Open、Windows/New或
Window/Split的命令而将一个新创建的视的对象连接到文档上时, MFC会自动调用
该函数,框架通过文档/视的结构将文档和视联系起来。当然,程序员也可以根据自
己的需要调用该函数。
Virtual POSITION GetFirstViewPosition( ) const;
Virtual CView * GetNextView( POSITION &rPosition) cosnt;

应用程序可以调用CDocument::GetFirstViewPosition返回与调用文档相联系的视的
列表中的第一个视的位置,并调用CDocument::GetNextView返回指定位置的视,并将
rPositon的值置为列表中下一个视的POSITION值。如果找到的视为列表中的最后一个
视,则将rPosition置为NULL.

15)从一个视图类取得另一视图类的指针
这个应用在多视的应用程序中很多见,一般如果自己在主程序或者主框架中做好变
量记号,也可以获得,还有比较通用的就是用文档类作中转,以文档类的视图遍历
定位,取得另一个视图类。这个功能从本文第10项中可以得到。
回复 点赞
zhstars 2008年07月15日
惯例,自己顶!
回复 点赞
zhstars 2008年07月15日
这个问题没有人会吗?敬请高人赐教!
回复 点赞
发动态
发帖子
界面
创建于2007-09-28

7975

社区成员

11.5w+

社区内容

VC/MFC 界面
社区公告
暂无公告