1.1.4 文档视图结构由于使用Visual C++ 6.0开发的程序,绝大部分是文档视图结构,所以下面介绍文档视图结构的相关知识。 一个商场有许多数据,为了便于处理,将这些数据库存放到数据库中。不同的员工对数据的要求不同,售货员关心的是商品的价格,人事经理关心的是员工的业绩。MFC将前者(数据库中的数据)抽象成文档,后者(人机交互)抽象成视图。与视图有关还有框架和文档模板,下面分别介绍。 ¡ 文档的本质:文档是用来保存数据以及关于数据的处理的,当程序响应“File→Open”或“File→New”的时候都会打开一份文档。文档可以拥有多个视图。文档和视图的关系可以这样理解:文档是被视图观察的对象。 ¡ 视图本质:视图在Windows中就是一个窗口,也就是一个可视化的矩形区域。视图是用来表示文档的数据的。但是每个视图必需依附于一个框架(SDI中是MainFrame,MDI是ChildFrame)。 ¡ 框架的本质:框架实际是也是一个Windows窗口。但是在框架上可以放置菜单、工具栏、状态栏等。而视图则放在框架的客户区。因此MFC中我们看到的窗口实际上Frame和View共同作用的结果。 在某一时刻,程序中只有一个活动的文档、框架和视图,即当前的文档、框架、视图。应用程序类管理文档模板,文档模板管理框架、视图、文档。 一般而言,写代码时,文档类和视图类改得较多,框架类改得比较少,文档模板类几乎不会被修改。下面突出重点,讲一下文档和视图类的相关内容。 1.文档和视图的相互访问文档与视图的关系是一对多关系。在MFC中,文档用CDocument类及其派生类处理,视图类由CView及其派生类处理。应用程序向导生成程序框架时,会自动为CXXView类生成GetDocument函数,可能通过此函数访问文档类。由于一个文档类对应多个视图类,可以遍历视图列表,代码如下: #include
"Ex010104View.h" //... void
CEx010104Doc::VisiteViews() {
CEx010104View * pView = NULL ;
for(POSITION pos = GetFirstViewPosition() ; NULL != pos ; )
{
pView = (CEx010104View *)GetNextView(pos);
//对视图进行相应操作
} } 2.视图类的刷新文档数据发生了变化,所有的视图必须作相应的更新,这时可以用CDocument类的UpdateAllView函数,其原型如下: void
UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL
); ¡ pSender:指向修改文档的视图的指针,为NULL表示刷新所有的视图。 ¡ lHint:表示关于修改的信息。 ¡ pHint:表示关于修改信息的CObject类指针。 此函数的实现如下: void
CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)
// walk through all views {
ASSERT(pSender == NULL || !m_viewList.IsEmpty());
// must have views if sent by one of them
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
if (pView != pSender) pView->OnUpdate(pSender,
lHint, pHint);
} } 从实现代码中可以看出,UpdateAllViews调用各视图的OnUpdate,OnUpdate会调用Invalidate(TRUE)刷新视图。由于OnUpdate类是虚函数,所以会调用的是派生类的OnUpdate,可以根据需要,重写OnUpdate函数。 3.CView类的OnInitialUpdate()函数新建或打开文档时,此函数会被调用,CView类的OnInitialUpdate()函数除了调用OnUpdate()函数之外,不做其他任何事情。如果想对视图进行初始化,可以在CView的派生类的OnInitialUpdate()函数进行。 4.CDocument类的DeleteContens()函数当文档关闭时,应用程序框架会自动调用此函数。如果需要对文档进行清理操作,就可重写此函数。
|
|