MFC——4.文本编程

Lesson4:文本编程

 

本文主要讲了在MFC中的文本编辑,并以简单的文本编辑为例,对光标显示、字符串输出、键盘按键输出字符,文字颜色字体设置和文字渐变效果进行了详细讲解。


1.      光标显示

文本编辑一般都会有一个光标,光标是在窗口创建之后才出现的,所以在view类里添加一个OnCreate消息处理程序,用于显示一闪一闪的光标。

int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
         if(CView::OnCreate(lpCreateStruct) == -1)
                   return -1;
          // TODO:  在此添加您专用的创建代码
         CClientDCdc(this);                                                                //定义一个cclientdc类的对象dc(创建设备描述表)
         TEXTMETRIC tm;                                            //定义一个文本结构体变量tm,用于保存得到的文本结构信息
         dc.GetTextMetrics(&tm);                                   //获得一个文本结构体,后面会用到它的成员变量宽度和高度
         //CreateSolidCaret(tm.tmAveCharWidth/ 8, tm.tmHeight);     //获得一个插入符(宽度,高度)
         //ShowCaret();                                             //显示插入符
 //也可以用设计的位图代表光标
         //CBitmap bitmap;
         //这里定义了一个局部的对象,当oncreate函数执行完毕后,bitmap这个对象完成析构,会将相关联的资源销毁,就看不到位图了,所以应该把它定义为view的成员变量
         bitmap.LoadBitmap(IDB_BITMAP1);
         CreateCaret(&bitmap);
         ShowCaret();
         return 0;
}

GetTextMetrics函数:函数功能是得到字体的度量信息,因为CDC类的GetTextMetrics成员函数要求参数是一个TEXTMETRIC结构体的指针,所以我们就定义一个TEXTMETRIC结构体的变量,将变量地址传给GetTextMetrics,通过GetTextMetrics函数用设备描述表中当前字体信息填充这个结构体。

 

2.      文字显示

ondraw函数:窗口发生重绘时,窗口中的文字或图形就被擦除掉。为了让文字一直保持在view类的窗口中,在Windows程序中提供的WM_PAINT函数,可以在WM_PAINT消息函数中将内容再输出,同样,在MFC中提供了一个类似WM_PAINT的函数,ondraw函数。

void CTextView::OnDraw(CDC* pDC)
{
         CTextDoc* pDoc =GetDocument();
         ASSERT_VALID(pDoc);
         if (!pDoc)
                   return;
         // TODO:  在此处为本机数据添加绘制代码
         CString str;                     //定义一个字符串对象
         str = "维新科学技术培训中心";    //初始化
         pDC->TextOut(50,50, str);       //输出字符串
 
         CSize sz =pDC->GetTextExtent(str);
 
         str.LoadString(IDS_WEIXIN);     //通过字符串标示符,输出字符串
         pDC->TextOut(0,200, str);

         //通过路径层将输出的文章圈起来,对比下面画了线条后两行字的状态,一个被网格覆盖,一个没有覆盖
         //实现路径层和剪裁区域的互操作达到相应效果。
         pDC->BeginPath();                                    //在beginpath和endpath之间的矩形框 没有被线条穿过
         pDC->Rectangle(50,50, 50 + sz.cx, 50 + sz.cy);      //用一个矩形框把字符框起来,配合slectclippath 进行操作
         pDC->EndPath();
         pDC->SelectClipPath(RGN_DIFF);                       //互操作类型取决于SelectClipPath的参数
        
         //画网格
         for (int i = 0;i<300; i += 10)
         {
                   pDC->MoveTo(0,i);
                   pDC->LineTo(300,i);
                   pDC->MoveTo(i,0);
                   pDC->LineTo(i,300);
         }
}

CString类:字符串操作类,没有基类,一个CString对象可以有可变长度的字符组成。在C语言中,利用char指针操作字符串时,一旦分配了堆内存,那么内存大小就定了,要想另外多存,就要重新分配大小。而CString函数在操作字符串时,我们不需要配内存大小,在类的内部都完成了。

                                    

字符串加载方法1:                        

CString str("tianjin");     /* 也可以这样赋值:   CString str; str=" tianjin ";   */

pDC->TextOut(50, 50, str);              //使用类成员函数输出字符串

        

字符串加载方法2:     

str.LoadString(IDS_nan); //在资源视图的string table中添加一个字符串,名字为IDS_nan

pDC->TextOut(50, 150, str);


3.      输入字符

对于一个文本编辑器,当从键盘上按键时,应该显示出所按的键对应的字符,所以应该对按键消息onchar进行响应。按键中特殊的键是回车和退格键。并且在字符输入中常常需要改变文字的颜色和字体。

3.1 设置字体

字体设置中,在view类里定义一个CFont类型的变量m_font保存设置的字体,在菜单里增加一个按钮用来响应设置字体事件,按钮的ID为IDM_FONT,添加处理程序如下。

void CTextView::OnFont()
{
         // TODO:  在此添加命令处理程序代码
         CFontDialog dlg;
         if (IDOK ==dlg.DoModal())   //弹出字体对话框,然后选择,点击ok确认选择
         {
                   if(m_font.m_hObject)
                            m_font.DeleteObject();       //如果字体已绑定,则删除字体,否则第二次选择字体报错
                   m_font.CreateFontIndirectA(dlg.m_cf.lpLogFont);   //选择字体
                  
                   //Invalidate();   // 窗口重绘
         }
} 

3.2 设置颜色

颜色设置中,在view类里定义一个   COLORREF类型的变量m_clr保存设置的颜色,在菜单里增加一个按钮用来响应设置颜色事件,按钮的ID为IDM_COLOR,添加处理程序如下。

void CTextView::OnColor()
{
         // TODO:  在此添加命令处理程序代码
         CColorDialog dlg;
         dlg.m_cc.Flags |= CC_RGBINIT|CC_FULLOPEN;    //将先前标记和初始化或组合起来
         dlg.m_cc.rgbResult =m_clr;
         if (IDOK ==dlg.DoModal())
         {
                   m_clr =dlg.m_cc.rgbResult;
         }
}

3.3   输入显示

其中 CString m_strLine初始化为空,用来保存输入的字符串CPoint m_ptOrigin初始化为0,用来保存光标位置。

void CTextView::OnChar(UINT nChar,UINT nRepCnt, UINT nFlags)
{
         // TODO:  在此添加消息处理程序代码和/或调用默认值
         //设置字体
         CClientDC dc(this);
         dc.SetTextColor(m_clr);  //将设置的颜色选择到设备描述表中,改变文字颜色
         //CFont font;
         //font.CreatePointFont(300,"华文行楷", NULL);
         CFont *pOldFont =dc.SelectObject(&m_font);//将字体选择到设备描述表中,并保存以前的字体到指针pOldFont
        
         //按键处理
         TEXTMETRIC tm;
         dc.GetTextMetrics(&tm);
         CreateSolidCaret(tm.tmAveCharWidth/ 8, tm.tmHeight);      //修改字体后,如果没有这句代码显示不了光标,不知道为什么
         if (0x0d == nChar)    //回车键处理(0x0d)
         {
                   m_strLine.Empty();//清空字符串,与下面光标位置没有关系
                   m_ptOrigin.x= 0; //设置新的光标x,y位置
                   m_ptOrigin.y+= tm.tmHeight;
         }
         else if (0x08 == nChar)  //删除键处理(0x08),删除字符可以通过将最后一个字符设置为背景色,就看上去删除了字符
         {
                   COLORREF clr= dc.SetTextColor(dc.GetBkColor());//获得背景色之前,保存先前的文本颜色到clr
                   dc.TextOut(m_ptOrigin.x,m_ptOrigin.y, m_strLine);//输出字符,即现在字符都看不到了,和背景色一样
                   m_strLine =m_strLine.Left(m_strLine.GetLength() - 1);//取左边总数减1个字符
                   dc.SetTextColor(clr);
         }
         else
         {
                   m_strLine +=(char)nChar;
         }
 
         //输入字符后,光标跟着移动,m_ptOrigin的位置只与鼠标点击位置有关
         CSize sz =dc.GetTextExtent(m_strLine);
         CPoint pt;
         pt.x = m_ptOrigin.x +sz.cx;
         pt.y = m_ptOrigin.y;
 
         SetCaretPos(pt);      //设置光标并显示
         ShowCaret();
 
         dc.TextOut(m_ptOrigin.x,m_ptOrigin.y, m_strLine);//输出字符,现在输出的就是看到的字符
 
         dc.SelectObject(pOldFont);//恢复到以前的字体
         CView::OnChar(nChar, nRepCnt,nFlags);
}

在文本编辑中,当我们点击鼠标时,光标应跟着移动。通过OnLButtonDown捕获这个消息

void CTextView::OnLButtonDown(UINT nFlags, CPoint point)
{
         // TODO:  在此添加消息处理程序代码和/或调用默认值
         SetCaretPos(point);     //设置鼠标点击位置为光标位置
         m_strLine.Empty();      //点击鼠标后,位置已换,因此要清空字符串,从新开始计算输入字符串的长度
         m_ptOrigin = point;
         CView::OnLButtonDown(nFlags,point);
} 

4.      字符颜色渐变效果

为了产生渐变效果,我们可以用一个定时器,在定时器里进行颜色渐变。添加WM_ONTIEMR消息进行处理。

在oncreate函数中设置一个定时器,当窗口产生的时候就调用这个定时器。

void CTextView::OnTimer(UINT_PTR nIDEvent=1)
{
         // TODO:  在此添加消息处理程序代码和/或调用默认值
                   //产生渐变的速度
         m_nWidth += 5;//按5个像素点增加
         CClientDC dc(this);
         TEXTMETRIC tm;
         dc.GetTextMetrics(&tm);
         CRect rect;
         rect.left = 0;
         rect.top = 200;
         rect.right = m_nWidth;
         rect.bottom = rect.top+ tm.tmHeight;
 
         //颜色
         dc.SetTextColor(RGB(255,0, 0));
         CString str;
         str.LoadString(IDS_WEIXIN);
         dc.DrawText(str, rect,DT_LEFT);
         //在150处再次输出字符串
         rect.top = 150;
         rect.left = 50;
         rect.bottom = rect.top+ tm.tmHeight;
         dc.DrawText(str, rect,DT_RIGHT);
         //如果显示结束,又从新显示
         CSize sz =dc.GetTextExtent(str);
         if (m_nWidth>sz.cx)
         {
                   m_nWidth =0;
                   dc.SetTextColor(RGB(0,255, 0));
                   dc.TextOut(0,200, str);
         }
         CView::OnTimer(nIDEvent);
}

 

 


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值