八宝书库 > 文学其他电子书 > C语言实例教程(PDF格式) >

第64部分

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

小说: C语言实例教程(PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 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';  



返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的