回 帖 发 新 帖 刷新版面

主题:MFC学习进阶05

大家好,我们了解了文档类,下面我们来看看视图类的清单:

//the file of cskeletonView.h

#ifndef _SKELETONVIEW_H_
#define _SKELETONVIEW_H_

class CSkeletonView:public CView{
public:
CSkelttonView();
virtual ~CSkeletonView();

public:
//获得一个该视指向的文档的指针
CSkeletonDoc* GetDocument();
//这个函数是在创建窗口之前,调用来改变窗口风格的
virtual BOOL PreCreateWindow(CREATESTRUCT&cs);
//当文档数据提供给视图,这个函数被调用。它是唯一能图形化表示提交的文档数据的函数
virtual void OnDraw(CDC* pDC);

public:
#ifdef _DEBUG
virtual void AssertValid()const;
virtual void Dump(CDumpContext&dc)const;
#endif

protected:
DECLARE_MESSAGE_MAP()
DECLARE_DYNCREATE(CSkeletonView)

};//end of class CSkeletonView

#ifndef _DEBUG
//这里有两个相同的函数,在宏中的是调试版本,上面的是发布版本
inline CSkeletonDoc* CSkeletonView::GetDocument()
{
return (CSkeletonDoc*)m_pDocument;
}
#endif

#endif


下面是该头文件的实现文件:SkeletonView.cpp
//the file of SkeletonView.cpp

#include"StdAfx.h"
#include"SkeletonDoc.h"
#include"SKeletonView.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[]=__FILE__;
#endif

BEGIN_MESSAGE_MAP(CSkeletonView,CView)
END_MESSAGE_MAP()

IMPLEMENT_DYNCREATE(CSkeletonView,CView)

CSkeletonView::CSkeletonView()
{}

CSkeletonView::~CSkeletonView()
{}

BOOL CSkeletonView::ProCreateWindow(CREATESTRUCT&cs){
//这里可以添加代码
return CView::PreCreateWindow(cs);
}

void CSkeletonView::OnDraw(CDC*pDC)
{
CSkeletonDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);

//这里可以添加代码
}

#ifdef _DEBUG
void CSkeletonView::AssertValid()const
{
CView::AssertValid();
}

void CSkeletonView::Dump(CDumpContext&dc)const
{
CView::Dump(dc);
}

CSkeletonDoc* CSkeletonView::GetDocument()
{
ASSERT(m_pDocument->lsKindOf(RUNTIME_CLASS(CSkeletonDoc)));
return (CSkeletonDoc*)m_pDocument;
}

#endif


ASSERT_VALID宏类似于ASSERT,它通常用于检测对象的完整性。ASSERT_VALID首先检查对象指针是

否为空,然后调用此对象的AssertValid()函数,如果出现错误,程序立即停止。

以上完成了视图类和文档类,然而一个运用程序要用文档/视图结构,必须还要运用程序的支持,比如说创

建,还有调用。还要为他们提供资源吧。好我们来看看其他部分的变化。
1。创建文档,视图类,必须修改原运用程序,需要一个改进的InitInstance()成员函数。下面看

看它的清单:
BOOL CSkeletonApp::InitInstance(){
//定义一个指向文档模板的指针,这里印证了文档,视图是靠文档模板来联系的
CSingleDocTemplate* pDocTemplate;
//新建一个文档模板
pDocTemplate=new CSingleDocTemplate(IDR_SKELETON,RUNTIME_CLASS(CSkeletonDoc),
RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CSkeletonView));
//添加这个文档模板
addDocTemplate(pDocTemplate);

CCommandLineInfo cmdInfo;
//CCommandLineInfo类在运用程序启动时协助分析命令行。可以用来封装命令行解释。
ParseCommandLine(cmdInfo);
//这个成员函数是CWinApp的,用来解析命令行并将每个参数传递给

CCommandLineInfo::ParseParam.通常紧接着调用ProcessShellCommand()函数。果然,下面就是

if(!ProcessShellCommand(cmdInfo)) return FALSE;
//处理有命令行传来的界面的命令。

m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();

return TRUE;
}//END

下面我们把这个和以前的版本比较一下:
以前的清单是:
BOOL CSkeletonApp::InitInstance()
{
    m_pMainWnd=new CMainFrame;
    ASSERT(m_pMainWnd);
    if(((CMainFrame*)m_pMainWnd)->Create(NULL,NULL))
    {
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }//end of if
    
    return FALSE;
}//END OF CSkeletonApp::IninInstance
1。很明显的区别是:前一个创建的东西比后一个多,后一个只有主窗口
2。从体积上来看:前一个多了命令命令解析功能

2。还有一个变化就是,在删除了CMainFrame::Create(),添加了CMainFrame::PreCreateWindow()
它的清单为:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& ca)
{
//这里添加代码
return CFrameWnd::PreCreateWindow(cs);
}//end
我不清楚有什么好处,或者是原因。但现在我们只要记住就行了

3。另外还有资源的添加。这些资源被定义为文档信息的字符串(说实话,不懂里面的意思)。下

面的清单给出了程序中用到的字符串资源,包含了新的IDR_SKELETON文档字符串。

STRINGTABLE
BEGIN
AFX_IDS_APP_TITLE "skeleton"
IDR_SKELETON "Skeleton\n\n\n\n\n\n\n"
END

IDR_SKELETON文档字符串包含了一个字符串集合,定义了文档性能。每个子字符串用(\n)分开,下面是子

字符串的格式:“App(运用程序名)\nDocName(新文档的却省文档名)\nDocType(描述文档类型的类型名)
\nFileType(描述文件类型的类型名)\n.Exi(文档文件的扩展名)\nRegType(窗口关联的文档文件类型)
\nRegName(文档文件类型的刻读名称)”
根据上面的东西,我们可以看出例子中提供了App这个标识,因为没有定义文档类型,所以其他的为空

文档字符串到底有什么用呢?如果用IDR_SKELETON文档字符串标识文档性质,文档模板就能找到运用程序资

源,如图标,菜单;除此之外,如果标识的是资源文件,文档模板就可以自动的发现他们并与运用程序联系

起来。(总的说来,就是让资源好找点)

下面有一个用IDR_SKELETON标识的菜单资源,清单如下:
IDR_SKELETON MENU
BEGIN
POPUP"&File"
BEGIN
  MENUITEM"E&xit",ID_APP_EXIT//ID_APP_EXIT把菜单项与退出运用程序的代码联系起来
END
END

以上就是文档/视图结构与原来的程序的不同,主要的就是程序类创建了文档模板,窗口类中创建,资源字

符串的不同,至于后来提到的菜单就可以先放一放。
好,这次就到这里了!

回复列表 (共2个回复)

沙发

这些有点深奥了,不太明白,支持你

板凳

再接再厉...支持LZ

我来回复

您尚未登录,请登录后再回复。点此登录或注册