友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
C语言实例教程(PDF格式)-第59部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
// MdiView。cpp : implementation of the CMdiView class
#include 〃stdafx。h〃
// CMdiView
// 。。。
IMPLEMENT_DYNCREATE(CMdiView; CView)
BEGIN_MESSAGE_MAP(CMdiView; CView)
//{{AFX_MSG_MAP(CMdiView)
ON_WM_CHAR()
//}}AFX_MSG_MAP
// Standard printing mands
ON_MAND(ID_FILE_PRINT; CView::OnFilePrint)
ON_MAND(ID_FILE_PRINT_DIRECT; CView::OnFilePrint)
ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview)
END_MESSAGE_MAP()
// 。。。
// CMdiView drawing
…………………………………………………………Page 507……………………………………………………………
void CMdiView::OnDraw(CDC* pDC)
{
CMdiDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
TEXTMETRIC tm;
pDC…》GetTextMetrics(&tm);
int yval=0;
for(int loop_index=0;loop_indexline_number;loop_index++)
{
pDC…》TextOut(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向应用程序提供了一个设
备无关的编程环境,另一方面,它又以设备相关的格式和具体的设备
打交道。
经常同图形设备接口相提并论的另一个概念是设备上下文 (Device
Context,DC)。设备上下文是一种Windows数据结构,它包括了与一
个设备 (如显示器或打印机)的绘制属性相关的信息。所有的绘制操作
通过一个设备上下文对象进行,该对象封装了实现绘制线条、形状和
文本的Windows API函数。设备上下文可以用来向屏幕、打印机和图
元文件输出结果。
在Windows应用程序中,我们通常在绘制之前调用BeginPaint函数,
然后在设备上下文中进行一系列的绘制操作,最后调用EndPaint函数
结束绘制。MFC类CPaintDC封装了这一过程。在构造CPaintDC对象的
同时,其构造函数自动调用BeginPaint函数;在消毁CPaintDC对象的
同时,其析构函数自动调用EndPaint函数。因此前面所讲述的过程可
以对应于下面的三个步骤:构造一个CDC对象,进行绘制操作,消毁
该CDC对象。在基于文档/视结构的应用程序框架中,这个过程被进一
步的简化。回忆前几章中讲述的内容,我们一般在视类的OnDraw成员
函数中处理有关重绘的操作。通过OnPrepareDC成员函数,框架自动
的向OnDraw成员函数传递一个类型为CPaintDC的设备上下文对象。我
们只需简单的通过该对象进行绘制,而不需要关心这一对象的构造和
消毁。这一过程由框架自动的完成,而且,隐藏在背后的设备上下文
在对OnDraw的调用返回时由框架进行释放。
除了上面的CPaintDC类外,MFC还提供了其它的一些封装不同设备上
下文的类。如CClientDC类,它所封装的设备上下文仅代表了一个窗
口的客户区。在CClientDC的构造函数中调用的不是BeginPaint函
数,而是GetDC函数;相应的,ReleaseDC函数在类CClientDC的析构
函数被自动调用。与此对应的还有另一个类CWindowDC,它所封装的
设备上下文代表的是整个窗口,不仅包括其客户区,也同时包括窗口
的边框及其它非客户区对象。
所有的设备上下文类中比较特殊的是类CMetaFileDC,通过
…………………………………………………………Page 514……………………………………………………………
CMetaFileDC对象所进行的绘制操作不是对一个实在的设备来进行
的,这些操作都被记录到一个Windows图元文件中。不象自动传递给
OnDraw成员函数的CPaintDC对象,如果要在这种情况下使用
CMetaFileDC对象的话,我们必须自己调用OnPrepareDC成员函数。
所有的这些设备上下文类都以类CDC作为其基类。
一般情况下,很多绘制操作都是在应用程序的视类的OnDraw成员函数
中进行的,前面说到过,当视类窗口收到消息WM_PAINT时,该消息对
应的处理函数OnPaint被调用,该处理函数构造一个CPaintDC对象,
并将指向该对象的指针传递给OnDraw成员函数。这里我们考虑这样一
种情况,如果我们正在编写的是一个通过鼠标在屏幕上绘图的应用程
序。这时我很显然需要为鼠标的移动消息添加消息处理函数,而且,
我们希望用户在移动鼠标的过程中立即就可以看到所绘制的内容,而
不是等到窗口收到WM_PAINT消息(即发生重绘事件)才调用成员函数
OnDraw绘制窗口。在这种情况下,我们更倾向于直接在鼠标消息处理
函数中进行绘制,这时,就需要创建一个设备上下文对象,然后通过
该对象调用一系列的绘制方法。
Windows本身是一个图形界面的操作系统,进行Windows程序设计随时
都会同设备上下文打交道,甚至在本书前面的章节中的一些示例程序
中我们也已经用到了设备上下文,只不过在当时我们回避了与设备上
下文有关的很多复杂东西。本章的目的之一就是系统的讨论这些前面
已经用到但没有加以阐述的概念和技巧,并补充一些尚未涉及的内
容,这些内容包括:
l 使用设备上下文进行绘制
l 绘图对象
l 直线与曲线
l 填充形状
l 字体和文本
l 颜色
l 坐标空间及变换
这些概念往往是交织起来的,哪怕是一个很简单的绘制操作,往往都
需要用到不只一个绘图对象,因此我们很难将它们人为的分割开来进
…………………………………………………………Page 515……………………………………………………………
行讲述。在本章上,各节的标题只代表了本节的侧重点,而对于某一
个概念的叙述或使用,则有可能分散在不只一个小节中。事实上,一
个应用程序是一个整体,它常常需要很多个部件共同协调工作才可以
正常工作。因此,出现这种情况是很自然的。
第一节 设备上下文
在MFC应用程序中,绘制操作通常涉及三类对象,一类是输出对象,
亦即设备上下文对象,包括CDC及其派生类;一类是绘制工具对象,
亦即前面所说的图形对象,如果CFont、CBrush和CPen等;另一类属
于Windows编程中需要用到的的基本数据类型,如CPoint、CSize和
CRect等。
不同的设备上下文类封装了不同类型的设备上下文类对象,如表9。1
所示
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!