77范文网 - 专业文章范例文档资料分享平台

第5章(5)

来源:网络收集 时间:2019-03-16 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:http://www.it315.org

3) 获取一个设备描述表。

CClientDC dc(this);

4) 定义一个指向画刷对象的指针变量,将新创建的画刷选入设备描述表,并将返

回的旧画刷保存在我们定义的指向画刷对象的指针变量中。

CBrush *pOldBr=dc.SelectObject(&br);

5) 在获取的设备描述表上,从原来保存的鼠标按下的点的位置到鼠标抬起的点的

位置内画一矩形,由于我们定义的带颜色的画刷已经选给设备描述表了,因此,设备描述表就用我们定义的带颜色的画刷来填充这块区域。

dc.Rectangle(CRect(m_ ptOrigin,point));

或者 dc.Rectangle(m_ptOrigin.x,m_ptOrigin.y,point.x,point.y);

6) 绘图工作结束,将旧的画刷选回设备描述表。

dc.SelectObject(pOldBr);

本例与上一个讲述画刷的例子基本类似,只不过多添加了一个位图资源,以及在创建画刷时不一样而已。添加其他的资源与添加位图资源类似,如果我们要添加那种在工作台的资源面板中已经存在的资源,如Dialog、Menu、Icon和String Table等,不需要右击顶层的EX05_04 resources结点,只需要右击要添加的资源名称如Dialog,然后选择Insert即可。

5.5.3 字体的使用

本节的内容不仅仅是向读者讲解字体的使用方法,还包括了和文本操作有关的许多知识,在开始两个实例之前,先让我们熟悉一下下面提到的内容。

一. WM_CHAR消息:

对于这个消息,有的读者可能已经很熟悉了,由于本节的例子中用到这个消息,因此在这里帮助大家重温一遍。当用户按动某一个键,系统将发出WM_KEYDOWN和WM_KEYUP消息,并且这两个消息的参数中均提供该键的虚拟扫描码。但有时用户按下某个键, 只想得到一条表示用户输入了某个字符的消息,TranslateMessage将WM_KEYDOWN, WM_KEYUP消息对转换成一条WM_CHAR消息,并在消息补充参数中提供该字符的编码。 二. CString类

在MFC中将对字符串的操作都封装在Cstring类中,由于它提供了丰富的操作字符串的成员函数,因此对于字符串操作,用Cstring类是很方便的。下面列出了几个最常用的成员函数。

? void Empty( );

不带任何参数,该成员函数的作用是将某个字符串的内容清空。 ? CString Left( int nCount );

该成员函数的作用是取指定字符串的左面几个字符。参数nCount表示取字符的个数,执行该成员函数成功后,返回一个常量字符串。 ? CString Right( int nCount );

该成员函数的作用是取指定字符串的右面几个字符。参数nCount表示取字符的个数,执行该成员函数成功后,返回一个常量字符串。 ? void Format( LPCTSTR lpszFormat, ... );

void Format( UINT nFormatID, ... );

该成员函数的作用是得到一个格式化字符串,它的功能类似于C语言中的sprintf();

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:http://www.it315.org

如: CString str = \

str.Format(\现在的值是”SomData123

? int GetLength( )

该成员函数的作用是取得字符串的长度。函数调用成功返回一个整型值。

三. CRect、CSize和CPoint

CRect 类、CSize类和CPoint类是由Windows RECT、SIZE和POINT结构派生出来的,因此,它们继承了公用整数型数据成员,如下所示:

CRect left、top、right、bottom CSize cx、cy CPoint x、y

这三个类有大量的重载运算符,并且它们之间有许多互操作,如下: ? 添加一个CSize对象到一个CPoint对象;

? 从CPoint对象减去另一个CPoint,将产生一个CSize对象; ? 从CPoint对象减去一个CSize对象,将产生一个CSize; ? 把CSize或者CPoint对象添加到CRect对象; ? 从CRect对象减去CPoint或者CSize对象。

CRect类有与CPoint和CSize相关的成员函数。例如,CRect::TopLeft成员函数返回一个CPoint对象,CRect::Size成员函数返回一个CSize对象。从这一点可以看出,一个CSize对象是“两个CPoint对象的差”,并且可以通过CPoint对象的差来获得CRect对象。

四. 光标操作

这里的光标,指的是在编辑文本或代码时,在窗口闪烁的光标,也叫脱字符。常用的几个光标操作如下:

? void CreateSolidCaret( int nWidth, int nHeight );

该函数的作用是创建一个规定大小的光标。参数nWidth表示光标的宽度,参数nHeight代表光标的高度。

如: CreateSolidCaret(100,100); ShowCaret();

上面的代码将产生一个100象素*100象素大小的实心光标 ? void CreateCaret( CBitmap* pBitmap );

该函数用来产生一个位图光标。参数pBitmap指向一个位图对象。 如: bmp.LoadBitmap(IDB_BITMAP1); //bmp定义为成员变量, CreateCaret(&bmp); //产生位图光标

ShowCaret(); //显示光标

? void SetCaretPos( POINT point );

该函数用来定位光标显示的位置。参数point指定光标要显示的位置。 ? void ShowCaret( );

该函数使光标显示在屏幕上。

五. OnDraw()和OnPaint()的区别

区别一:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。而OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC生成的程序代码时,在视图类只有OnDraw而没有OnPaint的原因。

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:http://www.it315.org

区别二:本章的前一部分已经讲过了,要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。如下所示:

//CView默认的标准的重画函数 void CView::OnPaint() {

CPaintDC dc(this); OnPreparDC(&dc);

OnDraw(&dc); //调用了OnDraw }

既然OnPaint最后也要调用OnDraw, 通常我们不必编写重写的 OnPaint 处理成员函数,因此我们一般会在OnDraw函数中进行绘制。 5.5.3.1 一个简单的文字处理程序 本例所要实现的功能是一个简单的文字处理程序,用户由键盘敲入字符并显示在屏幕上,如果按的是退格键则删除一个字符,若按的是回车键则另起一行继续输入字符。本例的关键点是,在窗口刚刚创建时生成一个字体,然后根据字体来调整光标的大小,显示在屏幕上,用户每敲入一个字符,判断它是否是退格符或回车符,并且随着字符的键入时刻调整光标的显示位置。完整例程请参见光盘中的例子代码EX05_05。下面将详细的讲述程序编制的步骤。 ? 步骤1:新建一个单文档-视图结构的MFC应用程序,工程名为EX05_05或用户自定义。 ? 步骤2:在工程的CEX05_05View类中加入WM_CREATE消息的处理函数OnCreate。

当窗口产生之后,会发出WM_CREATE消息,如果想让窗口一产生,就拥有光标,就应在OnCreate中加入代码,并且由于光标的大小是应跟字体匹配,所以创建字体的过程也在OnCreate函数中。需要注意的是WM_CREATE消息只是代表窗口刚刚产生,此时窗口还不可见,因此在OnCreate中不能调用那些依赖于窗口完全激活状态的Windows函数。如:GetClientRect().代码如清单5-01:

清单5-01工程EX05_05中CEX05_05View::OnCreate函数代码

——————————————————————————————————————— 1 int CEX05_05View::OnCreate(LPCREATESTRUCT lpCreateStruct) 2 { 3 if (CView::OnCreate(lpCreateStruct) == -1) 4 return -1; 5 // TODO: Add your specialized creation code here 6 CClientDC dc(this); 7 CFont fn;

8 fn.CreatePointFont(200,\华文行楷\9 TEXTMETRIC tm;

10 dc.SelectObject(&fn); 11 dc.GetTextMetrics(&tm);

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:http://www.it315.org

12 13 14 15 }

CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight); ShowCaret(); return 0;

代码中的6~8行首先创建一个DC和字体,9~11行将字体选入DC并取得当前字体的信息,最后12~13行创建脱字符并显示。 在第9行代码中定义了一个新的结构体TEXTMETRIC读者可能不熟悉,该结构体包含大量的数据成员,定义如下: typedef struct tagTEXTMETRIC { /* tm */ int tmHeight;

int tmAscent; int tmDescent;

int tmInternalLeading; int tmExternalLeading; int tmAveCharWidth;

int tmMaxCharWidth; int tmWeight; BYTE tmItalic;

BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmFirstChar; BYTE tmLastChar; BYTE tmDefaultChar; BYTE tmBreakChar;

BYTE tmPitchAndFamily; BYTE tmCharSet; int tmOverhang;

int tmDigitizedAspectX; int tmDigitizedAspectY;

} TEXTMETRIC;

TEXTMETRIC结构体包含了物理字体的基本信息。常用的数据成员包括tmHeight(字体的高度)、tmAveCharWidth(字体中字符的平均宽度),tmMaxCharWidth(字体中最宽字符的宽度)等等,有的读者可能不理解为什么在这个结构体中要定义平均字符宽度和最大字符宽度,而不定义字符宽度,看看w和i这两个字符,如果单纯的说取字符的宽度,那么是取w的宽度还是i的宽度呢?这下,读者理解了吧。其他一些数据成员的详解请参照MSDN。 第11行代码中调用的GetTextMetrics函数是设备描述表类CClientDC由基类派生过来的成员函数,原形如下:

BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;

GetTextMetrics函数只有一个参数lpMetrics是指向结构体TEXTMETRIC的指针,该函数的功能是获取当前设备描述表中保存的字体的信息,并将这些基本信息填入指向结构体TEXTMETRIC的指针变量中,如果用户需要用到字体信息,就可以通过tm.数据成员的形式来访问了。 取得设备描述表中当前的字体信息之后,就可以根据字体的高度和宽度来调整脱字符的

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:http://www.it315.org

大小了,由于一个字符的宽度往往比真正脱字符的宽度大好几倍,因此,我们在定义脱字符的宽度时,采用了字体字符平均宽度的1/8。

? 步骤3:在工程的CEX05_05View类中加入WM_CHAR消息的处理函数OnChar。

在OnChar函数中,要根据用户在键盘中输入的字符的不同分别进行处理。如果是退格键,那么删除一个字符;如果是回车键,那么另起一行,到下一行继续输入字符;如果是其他的字符,那么依次显示在窗口上。在输出字符到屏幕上的时候,并不是真的一个一个字符输出,因为这样操作的话,每次都要计算下一个字符输出的x坐标位置,我们所做的是,当用户输入一个字符时首先放到字符串中,然后每次都以x坐标为0的点为起始位置输出该字符串,每当用户输入一个字符,字符串长度加一,然后输出该字符串,所以给人的感觉就像是每次输入一个字符一样。当遇到回车时,将字符串清空,并且输出字符串的起始位置的y坐标增加一个字体的高度,x坐标不变始终为0,开始新的一行的输出。

1) 首先,在工程的CEX05_05View类中添加成员变量CStringm_strInput,该变量用

来保存用户在键盘上输入的字符。添加成员变量CPoint m_ptOrigin,用来记录字符串的输出位置,并在CEX05_05View类的构造函数中初始化为(0,0)。

CEX05_05View::CEX05_05View() {

m_ptOrigin=0; }

2) 在OnChar函数中需要再次生成字体,因为在OnCreate函数中定义的字体是局部类

型,而且在那里获取的设备描述表在函数OnCreate结束之后释放了,因此在OnChar函数中,我们需要重新获取一个设备描述表,并且需要再次生成字体,将该字体选入设备描述表。代码如下:

CClientDC dc(this); CFont newFn;

newFn.CreatePointFont(200,\隶书\CFont *pOldFn=dc.SelectObject(&newFn); TEXTMETRIC tm;

dc.GetTextMetrics(&tm);

CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight); ShowCaret();

3) 接着在OnChar函数中处理回车键。原本字符串是在(0,0)的位置输出的,那么

当回车时,另起一行到下一行,因此x坐标值不变,y坐标值增长,每次增长的高度至少是设备描述表中字体的高度。代码如下:

if(0x0d==nChar) {

m_ptOrigin.x=0;

m_ptOrigin.y+=tm.tmHeight; m_strInput.Empty(); }

代码中的0x0d代表回车符,也可以用'\\15'表示,0x08代表退格符。注意,代码

m_ptOrigin.y+=tm.tmHeight;等同于m_ptOrigin.y= m_ptOrigin.y+tm.tmHeight; 4) 在OnChar函数中处理退格键。当敲入一个退格键时,应删除屏幕上的一个字,但

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库第5章(5)在线全文阅读。

第5章(5).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/524769.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: