友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

C语言实例教程(PDF格式)-第43部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


RUNTIME_CLASS(CMdiView));  



AddDocTemplate(pDocTemplate);  



// 。。。  



return TRUE;  



}  



每次打开一个新文档时都调用CDocument的函数OnNewDocument。该函 

数被定义如下:  



class CMdiDoc : public CDocument  



{  



// 。。。  



// Overrides  



// ClassWizard generated virtual function overrides  



//{{AFX_VIRTUAL(CMdiDoc)  



public:  



virtual BOOL OnNewDocument();  



virtual void Serialize(CArchive& ar);  



//}}AFX_VIRTUAL  



// 。。。  



}  



当调用此函数时可以得到一个新的MDI子窗口,它由CDMIChildWnd派 

生出来。这些子窗口保存着各种已打开的文档,所有的细节都是由 


…………………………………………………………Page 499……………………………………………………………

MFC库处理。而每个MDI子窗口都支持由类CView派生出的普通类型的 

视窗。         这意味着可以同以前一样不受约束地使用WM_CHAR和 

WM_MOUSEMOVE这类消息。  



  l 注意:  



  l 如果读者对这一部分的理解不太清楚,建议再看看6。5视类一节 

   中有关视类层次结构的介绍。  



在8。4生成视一节中的最后,我们曾经提到过,可以用调用函数 

UpdateAllViews来维护所需要的众多视窗的同时协调工作。当任意一 

个视窗修改了文档之后就可调用该函数,这样可确保除了第一个调用 

该函数进行修改的视窗外所有视窗均调用函数OnUpdate。在前面的那 

个例子中,我们就如上所述的调用了该类。  



函数UpdateAllViews 的原型为:  



void UpdateAllViews( CView* pSender; LPARAM lHint = 0L; CObject* pHint = NULL );  



其中LONG型参数lHint通常所包含的信息与视窗对文档所做的修改有 

关;pHint总是指向一个对象,该对象有助于处理更新。为简单起 

见,只需将这些值赋为NULL。  



但另一方面,我们还需要将函数OnUpdate加到视窗类中,以处理由其 

它视窗引发的更新,因此需要处理函数CView::OnUpdate:  



virtual void OnUpdate( CView* pSender; LPARAM lHint; CObject* pHint );  



其中参数pSender为一指向修改了文档的指针 (当所有文档均需要更 

新时可以设置该参数为NULL),参数lHint内存放着有关这些修改的 

信息,函数最后一个参数pHint则为一存放该修改信息的内容的指 

针。  



这样,当任意一个视窗修改了文档时,它就调用pDoc

》UpdateAllViews,该函数又调用与该文档相关联的其它所有视窗中 

的OnUpdate来更新所有显示。由此,在系统中的所有视窗就可以一起 

协调工作了。当在任意一个视窗中键入任何内容时,在其它视窗中也 

可以见到这些内容被显示出来。  


…………………………………………………………Page 500……………………………………………………………

                                                 



                        图8。24 类CSplitterWnd的层次  



在程序中处理多文档,但同时,我们也可以通过分离窗口支持一个文 

档的多个视。分离窗口是这样一种窗口,它们在一个视窗中被分成几 

个相关联的部分,虽然它们在视窗中是分离的,但它们同样协同工 

作,任一窗口中所做的修改同样地反应到其它窗口中。  



MFC中支持分离窗口的类是CSplitterWnd,该类的层次结构如图 

8。24。  



因为CSplitterWnd类由CWnd类派生而来,它就可以使用它被授权使用 

的那一些CWnd类的成员函数。  



class CMdiSplitFrm : public CMDIChildWnd  



{  



DECLARE_DYNCREATE(CMdiSplitFrm)  



protected:  



CMdiSplitFrm(); // protected constructor used by dynamic creation  



// add and remove member functions here。  



// 。。。  



//}}AFX_DISPATCH  



DECLARE_DISPATCH_MAP()  



DECLARE_INTERFACE_MAP()  



}  



   l 注意:  



   l 在这里,涉及到一个创建新类的问题。如 图,打开ClassWizard, 

    选择Add Class。。然后,我们键入想要生成类CMdiSplitFrm。并在 

    Base class的下拉列表中选择splitter作为该类的基类。如 图 

    8。25所示。  


…………………………………………………………Page 501……………………………………………………………

                                            



                图8。25 利用Class Wizard加入一个新类  



我们在下面的程序中使用了上面介绍的一些概念,我们的程序也可以 

良好的运行,但仍有许多工作要做。我们的程序使用前面提到的方法 

生成了一个支持窗口分割的MDI,但是,在参考我们的程序建立起你 

自己的应用程序之后,我们想,你一定会发现,我们的程序离一个好 

用的编辑器仍有很长的距离。不过,通过我们的逐步完善,我们完全 

可以将它做得更好。  



下面我们给出一个程序运行的画面 (如图8。26)。同时,我们也给出 

一部分关键的源代码,在需要自己添加的部分,我们会以具有底纹的 

文本标出,希望读者注意这些地方。  



                                              



                  图8。26 分割窗口的一个运行画面  



// MdiDoc。h : interface of the CMdiDoc class  


…………………………………………………………Page 502……………………………………………………………

#if !defined(AFX_MDIDOC_H__6A6E4F01_1FC8_11D2_BC8B_E95B8191F13C__INCLUDED_)  



// 。。。  



class CMdiDoc : public CDocument  



{  



protected: // create from serialization only  



CMdiDoc();  



DECLARE_DYNCREATE(CMdiDoc)  



CSize m_sizeDoc;  



// Attributes  



public:  



CString data_string'100';  



long line_number;  



// Operations  



public:  



CSize GetDocSize(){return m_sizeDoc;}   



// Overrides  



// 。。。  



protected:  



protected:  



//{{AFX_MSG(CMdiDoc)  



// 。。。  



//}}AFX_MSG  



DECLARE_MESSAGE_MAP()  



};  



// 。。。  



#endif // !defined(AFX_MDIDOC_H__6A6E4F01_1FC8_11D2_BC8B_E95B8191F13C__INCLUDED_)  


…………………………………………………………Page 503……………………………………………………………

    



// MdiDoc。cpp : implementation of the CMdiDoc class  



#include 〃stdafx。h〃  



// CMdiDoc  



// 。。。  



IMPLEMENT_DYNCREATE(CMdiDoc; CDocument)  



BEGIN_MESSAGE_MAP(CMdiDoc; CDocument)  



//{{AFX_MSG_MAP(CMdiDoc)  



// 。。。  



//}}AFX_MSG_MAP  



END_MESSAGE_MAP()  



// CMdiDoc construction/destruction  



CMdiDoc::CMdiDoc()  



{  



// TODO: add one…time construction code here  



line_number=0;  



m_sizeDoc=CSize(800;1000);  



}  



// 。。。  



BOOL CMdiDoc::OnNewDocument()  



{  



if (!CDocument::OnNewDocument())  



return FALSE;  



// 。。。  



return TRUE;  



}  


…………………………………………………………Page 504……………………………………………………………

// CMdiDoc serialization  



void CMdiDoc::Serialize(CArchive& ar)  



{  



if (ar。IsStoring())  



{  



arTextOut(0;yval;pDoc…》data_string'loop_index';  



pDoc…》data_string'loop_index'。GetLength());  



yval+=tm。tmHeight;  



}  



// TODO: add draw code for native data here  



}  



/////////////////////////////////////////////////////////////////////////////  



// CMdiView printing  



// CMdiView diagnostics  



// 。。。  



#ifdef _DEBUG  



void CMdiView::AssertValid() const  



 {  



CView::AssertValid();  



}  



// 。。。  



// CMdiView message handlers  


…………………………………………………………Page 508……………………………………………………………

void CMdiView::OnChar(UINT nChar; UINT nRepCnt; UINT nFlags)   



{  



// TODO: Add your message handler code here and/or call default  



CMdiDoc *pDoc=GetDocument();  



CClientDC dc(this);  



OnPrepareDC(&dc);  



if(nChar=='r'){  



pDoc…》line_number++;  



}  



else{  



pDoc…》data_string'pDoc…》line_number'+=nChar;  



TEXTMETRIC tm;  



dc。GetTextMetrics(&tm);  



dc。TextOut(0;(int)pDoc…》line_number*tm。tmHeight;  



pDoc…》data_string'pDoc…》line_number';  



pDoc…》data_string'pDoc…》line_number'。GetLength());  



}  



pDoc…》UpdateAllViews(this;0l;NULL);  



pDoc…》SetModifiedFlag();  



CView::OnChar(nChar; nRepCnt; nFlags);  



}  



void CMdiView::OnUpdate(CView* pSender; LPARAM lHint; CObject* pHint)   



{  



// TODO: Add your specialized code here and/or call the base class  



Invalidate();  



}  


…………………………………………………………Page 509……………………………………………………………

void CMdiView::OnInitialUpdate()   



{  



CView::OnInitialUpdate();  



// TODO: Add your specialized code here and/or call the base class  



}  



// Mdi。h : main header file for the MDI application  



#if !defined(AFX_MDI_H__6A6E4EF9_1FC8_11D2_BC8B_E95B8191F13C__INCLUDED_)  



// 。。。  



/////////////////////////////////////////////////////////////////////////////  



// CMdiApp:  



// See Mdi。cpp for the implementation of this class  



//  



class CMdiApp : public CWinApp  



{  



public:  



CMdiApp();  



// Overrides  



// ClassWizard generated virtual function overrides  



//{{AFX_VIRTUAL(CMdiApp)  



public:  



virtual BOOL InitInstance();  



//}}AFX_VIRTUAL  



// 。。。  



DECLARE_MESSAGE_MAP()  



};  



// 。。。  


…………………………………………………………Page 510……………………………………………………………

#endif // !defined(AFX_MDI_H__6A6E4EF9_1FC8_11D2_BC8B_E95B8191F13C__INCLUDED_)  



    



// Mdi。cpp : Defines the class behaviors for the application。  



#include 〃stdafx。h〃  



#include 〃Mdi。h〃  



#include 〃MdiSplitFrm。h〃  



#include 〃MainFrm。h〃  



// 。。。  



// CMdiApp  



// 。。。  



// CMdiApp construction  



// 。。。  



// The one and only CMdiApp object  



CMdiApp theApp;  



// CMdiApp initialization  



// 。。。  



CMultiDocTemplate* pDocTemplate;  



pDocTemplate = new CMultiDocTemplate(  



IDR_MDITYPE;  



RUNTIME_CLASS(CMdiDoc);  



RUNTIME_CLASS(CMdiSplitFrm); // custom MDI splitter frame  



RUNTIME_CLASS(CMdiView));  



AddDocTemplate(pDocTemplate);  



// 。。。  



return TRUE;  



}  


…………………………………………………………Page 511……………………………………………………………

// CAboutDlg dialog used for App About  



class CAboutDlg : public CDialog  



{  



public:  



// 。。。  



};  



// 。。。  



/////////////////////////////////////////////////////////////////////////////  



// CMdiApp mands  



//尽管类CSplitter是我们这节的重点,但由于在该类中我们并没有添加什么新的东西,而  



//有关该类的基础知识我们在讲解中已经作了解释,此处不再列出。  



              第七节 添加对多文档类型的支持  



在本章前面的部分,我们已经比较详细地对多文档类型支持的一些问 

题。在本节中,我们只计划再简单地作一回顾,在本节的最后部分, 

我们则简单地谈谈程序对打印的支持手段。  



在程序中加入多文档的支持,从技术上来说,只是需要将窗口的直接 

基类从单文档界面的CFrameWnd换成多文档程序的CMDIFrameWnd就可 

以了。但是,由于多文档程序的特殊性,也出现了一些需要不同处理 

的问题。对每个文档来说,它们所关联的视类 (或其派生类)总是仅 

仅对应于唯一的文档,因此,对各个文档的数据的管理实际上与单文 

档程序没有什么区别,但是,由于多个文档的出现,对它们的管理就 

成为主要的问题。  



我们不妨先将问题简化。每一个文档可以有多个视,但每个视只能对 

应于一个确定的文档。因此,多文档程序需要解决的问题仅仅是多个 

文档的数据管理方法的问题 (对视图的管理我们在前面一节中已经作 

出了比较详细的解释)。对多文档程序来说,最初的文档模板只支持 

主窗口,但每次打开一个新文档时都调用CDocument的函数 

OnNewDocument,建立一个有CMDIChildWnd派生的新的MDI子窗口,这 

些窗口中保存着各种已打开的文档,所有的细节都由MFC库处理。例 

如,当用户单击File菜单下的New菜单项时,将生成另外一个文档并 

打开其窗口。但是,每个文档中初始时都是一片空白,因此还需加上 


…………………………………………………………Page 512……………………………………………………………

能对不同的窗口事件作出反应的代码。每个MDI子窗口都支持由类 

CView派生的普通类型的视窗,这就意味着可以同以前一样不受约束 

地使用各类消息。而对各类消息的单独处理,读者不妨参考对应各章 

的讲解。  



作为文档/视结构的一个组成部分,在本章我们并没有对打印和打印 

预览这一部分内容进行讲述。由于篇幅的有限,在本书中我们将不单 

独讲述如何添加和完善应用程序的打印支持。这里仅指出一点:在我 

们建立非基于对话框的程序时,如果我们选择了打印支持,那么,系 

统已经为我们完成了绝大部分的工作。但如果我们没有在最初的设计 

中选择打印支持,那么,我们就需要考虑对它自己实现了。MFC提供 

了标准打印对话框CPrintDialog来简化打印操作。读者如果有这方面 

的需要,请参考系统的帮助文件。  


…………………………………………………………Page 513……………………………………………………………

           第九章 图形设备接口  



事实上,图形设备接口 (Graphics Device Interface,GDI)是指这样 

的一个可执行程序,它处理来自Windows应用程序的图形函数调用, 

然后把这些调用传递给合适的设备驱动程序,由设备驱动程序来执行 

与硬件相关的函数并产生最后的输出结果。GDI可以看作是一个应用 

程序与输出设备之间的中介,一方面,GDI向应用程序提�
返回目录 上一页 下一页 回到顶部 赞(10) 踩(10)
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!