MFC界面编程基础(07):文本编程

上一篇:MFC界面编程基础(06):简单绘图下一篇:MFC界面编程基础(08):菜单(一)

创建插入符

在我们使用文本编辑器的时候,在这些文本处理程序的编辑窗口中都有一条闪烁的竖线,将之称为插入符。插入符可以用于提示用户:你输入的文字信息将在这个插入符所在的位置显示出来。
在程序中想要创建插入符,可以利用CWnd类的CreateSolidCaret()函数,该函数原型:
void CreateSolidCaret(int nWidth,int nHeight);
函数的两个参数分别代表插入符的宽度和高度,如何让插入符适合于当前字体的大小呢?首先我们需要得到设备描述表中当前字体的信息,然后根据字体信息来调整插入符的大小。可以通过调用CDC类的GetTextMetrics成员函数得到设备描述表中当前字体的度量信息。函数原型如下:
BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics)const
我们使用CreateSolidCaret函数创建插入符之后,该插入符初始状态是隐藏的,必须调用ShowCaret()函数来显示插入符
在前边我们已经讲过,视类窗口始终位于框架窗口之上,对窗口客户区的鼠标和键盘操作实际上都是在视类窗口上进行的,因此应该在视类窗口上创建插入符
插入符的创建应该在窗口创建之后进行,可以在WM_CREATE消息的响应函数OnCreate中添加创建插入符的代码。
在这里插入图片描述
根据上述代码有同学可能会有疑问,为什么创建插入符时,要将字体的平均宽度除以8,这是一个经验,此时可以达到最优。

字符输入

想要实现字符的输入功能,也就是当我们按下键盘上某个键之后,要把该字符输出到程序窗口上,这就需要捕获键盘按下(WM_CHAR)这一消息。我们需要利用TextOut函数在窗口输出字符串,TextOut函数原型:
BOOL TextOut(int x ,int y ,const CString& str);
参数:

  • x 指定文本起点的X逻辑坐标。
  • y 指定文本起点的Y逻辑坐标。
  • str 包含字符的CString对象。

根据函数我们可以知道输出字符时我们需要提供字符的x,y坐标,但是这是有难度的,因为每个字符在屏幕所占的宽度都不一样,所以我们获取下一个输入点的坐标就不太容易实现。所以我们可以采用一种简单的方式,把每次输入的字符都保存到一个字符串中,当每次输入新的字符时,我们就在窗口当前插入符的位置重新把字符串输出一次。
需要注意的到的几个问题:

  • 程序在当前插入的符的位置输出字符。也就是说程序运行时,如果鼠标左键单击窗口中的某个位置,那么插入符就移动到这个地方,随后输入的字符都应该在此位置往后输出。把插入符移动到鼠标左键的单击处,可以利用CWnd类的SetCaretPos函数来实现,函数声明如下:
    static void PASCAL SetCaretPos( POINT point );
    参数: point 指定了插字符的新的x和y坐标(客户坐标)。
  • 用来存储输入字符的字符串取值变化问题。
    当鼠标左键单击窗口中一个新的地方时,插入符就会移动到这个位置,那么以后输入的字符都应该从这个位置开始输出,以前输入的字符不应该再从此位置输出,依次需要把存储字符的字符串清空。
  • 每次输入的字符串都应该在当前插入符的位置,也就是鼠标单击的位置开始显示。这样就需要把鼠标左键单击的坐标保存起来,以便在On_Char函数中使用。
  • 在输出字符时,还需要考虑到回车字符的处理,按下回车后,插入符应切换到下一行,随后的输入也应该新的一行开始输出,前面介绍过GetTextMetrics函数,可以获得当前设备描述表中字体高度信息。
  • 在输出字符时,还需要另外一个字符处理,退格键。按下退格键需要删除屏幕上位于插入符前面的那个字符。我们可以采取最简单的实现方式,先将文本颜色设置为背景色,在窗口中将字符串输出一次,然后将字符串中最后一个字符删掉,再把文本颜色设置为原来是颜色,将字符串再输出一次。屏幕上就看到了正确的删除效果。获取背景颜色可以使用CDC类的GetBKColor函数。而设置文本颜色我们可以使用CDC类提供的另一个成员函数SetTextColor函数,这个函数将会返回文本之前的颜色。如果想要实现从字符串中删除一个字符,可以使用CString类的Left函数。函数原型: CString Left(int nCount) const;返回一个CString对象,即返回指定字符串左边指定数目(nCount参数指定)的字符。

完成上述代码之后,执行程序,可以在窗口中插入字符了,但是插入符的位置没有改变,一般情况我们需要插入随着字符的输入而移动,我们知道可以利用SetCaretPos函数来设置插入符的位置,但是移动的位置如何确定呢?实际上对于同一行输入来说,插入符横向移动的距离就是输入字符的宽度,纵坐标是没有改变的。可以利用函数GetTextExtent得到字符串的宽度。

核心代码实现:

在这里插入图片描述
在这里插入图片描述

设置字体

MFC中提供了CFront类专门来设置字体。这个类派生于CGdiObject类,封装了一个Windows图形设备接口的字体。在编程时,在构造了一个CFont对象后,还必须利用该类提供的几个初始化函数之一对该对象进行初始化,然后才能使用这个对象。
CFont提供的几个初始化函数如下表:
在这里插入图片描述

这些初始化函数的主要作用就是讲CFront这个C++对象与字体资源关联起来。
在程序中与其他GDI对象一样,当创建了一个字体对象并初始化后,还必须将他选入设备描述表,之后这个新字体才能发挥作用。这个可以利用CDC类的SelectObject函数来实现,同样函数会返回先前的字体,我们可以保存这个字体,在使用完新字体之后,再把设备描述表中的字体恢复为先前的字体。
在这里插入图片描述

字体变色功能实现

我们平时在唱卡拉OK时,应该注意到歌曲字幕会随着曲调的播放有一个平滑的变色过程。如何在程序中实现这种变色效果呢?

如果我们先把字体输出到屏幕上,接着把文本的颜色设置为新的颜色,然后一个字符一个字符的输出显示该字符串,也可以达到一种变色效果,但不能达到平滑的变色效果。为了达到卡拉OK那种平滑的变色效果我们需要利用CDC类提供的另一个文字输出的函数DrawText来实现,该函数声明如下:

int DrawText(const CString& str, LPRECT lpRect, UNIT nFormat);

该函数实际上是把文字输出局限在一个矩形范围内。当初始输出文本是先把矩形的宽度设置为一个较小的值,然后不断加大矩形的宽度,这样就可以不断的增加显示文字的内容,从而实现文字平滑变色的效果。
文字变色是一个不断变化、自行进行的过程,这意味着我们需要不断的调用DrawText函数,同时增大包含文本的矩形宽度。要实现这个功能,我们需要用到定时器,通过定时器自动控制文字颜色的进程。
利用CWnd类的SetTimer成员函数可以设置定时器。函数原型如下:

UINT SetTimer(UINT nIDEvent, UINT nElapse,
void (CALLBACK EXPORT*lpfnTimer) (HWND, UINT, UINT, DWORD) );

返回值:
如果函数成功,则返回新定时器的标识符。应用程序可以将这个值传递给KillTimer成员函数以销毁定时器。如果成功,则返回非零值;否则返回0。
参数:

  • nIDEvent 指定了不为零的定时器标识符。
  • nElapse 指定了定时值;以毫秒为单位。
  • lpfnTimer 指定了应用程序提供的TimerProc回调函数的地址,该函数被用于处理WM_TIMER消息。如果这个参数为NULL,则WM_TIMER消息被放入应用程序的消息队列并由CWnd对象来处理

具体步骤如下:

  • 在视类的OnCreate函数中设置定时器。
  • 在视类中对定时器消息进行处理,因此需要给视类添加WM_TIMER消息的响应函数
  • 需要使DrawText的函数的第二个参数,即显示文字的矩形范围不断增加,所以需要设置一个变量,让它旳值不断增加,实现矩形宽度的不断增加。
    核心代码实现:
    在这里插入图片描述
上一篇:MFC界面编程基础(06):简单绘图下一篇:MFC界面编程基础(08):菜单(一)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值