按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
》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…》li