第五章-文本编程

来源:互联网 发布:java实现多张图片上传 编辑:程序博客网 时间:2024/06/06 01:49

1.CWnd::CreateSolidCaret创建插入符,ShowCaret()显示插入符。GetTextMetrics(),获得当前字体的一些信息。CWnd::CreateCaret()创建图象插入符

 bitmap.LoadBitmap(IDB_BITMAP1);//此处的bitmap为成员变量!!!

 CreateCaret(&bitmap);

 ShowCaret();

 TEXTMETRIC tm;//字体结构体

 dc.GetTextMetrics(&tm);//

 m_ptOrigin.y+=tm.tmHeight;//获得字体高度。


void CreateSolidCaret( int nWidth, int nHeight );//创建插入符
void CreateCaret( CBitmap* pBitmap );//创建位图插入符
void ShowCaret( );//显示插入符
void HideCaret( );//隐藏插入符
static void PASCAL SetCaretPos( POINT point );//移动插入符号
说明:
1)创建插入符要在窗口创建完成之后,CreateSolidCaret函数创建的插入符被初始化为隐藏,所以需要调用ShowCaret()将其显示。
2)使用CreateCaret函数创建位图插入符的时候,不能使用局部的位图对象关联位图资源。(与资源相关联的C++对象,当它析构的时候会同时把与它相关联的资源销毁。)


获取当前字体信息的度量:CDC::GetTextMetrics
BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;
说明:
typedef struct tagTEXTMETRIC {  /* tm */
    int  tmHeight;//字体高度。Specifies the height (ascent + descent) of characters.
    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;

 

获取字符串的高度和宽度(区别字符串的长度):
CDC::GetTextExtent
CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
CSize GetTextExtent( const CString& str ) const;
说明:
The CSize class is similar to the Windows SIZE structure。
typedef struct tagSIZE {
    int cx;//the x-extent 
    int cy;//the y-extent 
} SIZE;


2.VC中CString::LoadString(ID号),比较方便。

 

3.路径层的概念:有两种方法创建路径层:

 (1)

        pDC->BeginPath();

        pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);

        pDC->EndPath();

        pDC->SelectClipPath(RGN_DIFF);

  (2)

       CSize sz=pDC->GetTextExtent(str);

       CRgn rn;

       rn.CreateRectRgn(0,50,sz.cx,sz.cy);

       pDC->SelectClipRgn(&rn,RGN_DIFF);

路径层有什么作用?可以保护我们先前的文本或者图像不被后来画的覆盖。

 

BOOL BeginPath( );
//在这作图定义路径层剪切区域
BOOL EndPath( );
BOOL SelectClipPath( int nMode );//调用这个函数来使当前路径层剪切区域与新剪切区域进行互操作。   
//在这覆盖作图(包含前定义的路径层区域)定义新的剪切区域

说明:
1)SelectClipPath Selects the current path as a clipping region for the device context, combining the new region with any existing clipping region by using the specified mode. The device context identified must contain a closed path.
////
nMode:RGN_AND,RGN_COPY,RGN_DIFF,RGN_OR,RGN_XOR
RGN_AND   The new clipping region includes the intersection (overlapping areas) of the current clipping region and the current path.
RGN_COPY   The new clipping region is the current path.
RGN_DIFF   The new clipping region includes the areas of the current clipping region, and those of the current path are excluded.
RGN_OR   The new clipping region includes the union (combined areas) of the current clipping region and the current path.
RGN_XOR   The new clipping region includes the union of the current clipping region and the current path, but without the overlapping areas.
2)应用:当作图的时候,如果想要在整幅图形其中的某个部分和其它部分有所区别,我们可以把这部分图形放到路径层当中,然后指定调用指定互操作模式调用SelectClipPath( int nMode )函数来使路径层和覆盖在其上新绘图剪切区域进行互操作,达到特殊效果。



4.文本字符串一些函数:
COLORREF GetBkColor( ) const;//得到背景颜色
virtual COLORREF SetBkColor( COLORREF crColor );//设置背景颜色
BOOL SetTextBkColor( COLORREF cr );//设置文本背景颜色
virtual COLORREF SetTextColor( COLORREF crColor );//设置文本颜色
virtual BOOL TextOut( int x, int y, LPCTSTR lpszString, int nCount );//输出文本
BOOL TextOut( int x, int y, const CString& str );
CString Left( int nCount ) const;//得到字符串左边nCount个字符
int GetLength( ) const;//得到字符串长度


5.字体CFont::CFont 
CFont( );//构造函数
//Constructs a CFont object. The resulting object must be initialized with CreateFont, CreateFontIndirect, CreatePointFont, or CreatePointFontIndirect before it can be used.
选用字体事例代码组:
CClientDC dc(this);
CFont font;//构造字体对象
font.CreatePointFont(300,"华文行楷",NULL);//初始化字体对象,与字体资源相关联
CFont *pOldFont=dc.SelectObject(&font);//将新字体选入DC
...
dc.SelectObject(pOldFont);//恢复原字体
说明:
1)构造字体对象时候,必须初始化。(初始化是将字体对象与字体资源相关联)。
2)初始化对象时候,选用的字体也可以是系统字体,但不一定都有效,据测试选用。


 CFont font;//创建字体对象

 font.CreatePointFont(300,"华文行楷",NULL);//设置

 CFont *pOldFont=dc.SelectObject(&font);//将字体选择到DC中

 TEXTMETRIC tm;//创建字体信息对象

 dc.GetTextMetrics(&tm);//获得当前字体信息

 if(0x0d==nChar)//处理回车键

 {

 m_strLine.Empty();

 m_ptOrigin.y+=tm.tmHeight;

 }

 else if(0x08==nChar)//处理退格键

 {

 COLORREF clr=dc.SetTextColor(dc.GetBkColor());

 dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);

  m_strLine=m_strLine.Left(m_strLine.GetLength()-1);

 dc.SetTextColor(clr);

 }

 else

 {

 m_strLine+=nChar;

 }

 CSize sz=dc.GetTextExtent(m_strLine); CPoint pt;//处理光标的位置

 pt.x=m_ptOrigin.x+sz.cx;

 pt.y=m_ptOrigin.y; SetCaretPos(pt);

 dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);//输出字体 dc.SelectObject(pOldFont);//将原先的字体选择回去。有了CEditView和CRichEditView之后,就没有那么辛苦了。

 

5.模拟卡啦OK变色的步骤。

  (1)设置定时器

  (2)在定时器中加入代码

 平滑变色
CDC::TextOut()是一个字母一个字母的输出,达不到平滑效果。
CDC::DrawText():将文字的输出局限于一个矩形区域,超出矩形区域的文字都被截断。利用这一特点,可每隔些时间增加矩形大小,从而可实现人眼中的平滑效果。
CWnd::SetTimer():设置定时器。按设定的时间定时发送WM_TIMER消息。

 

具体代码如下:(编完一个之后,注释掉前面的,继续编)

 

我这里把第五讲分成两个程序,把最后一个卡拉OK输出单独出来了,怕太混乱了。

CXXView:

[html] view plain copy
  1. private:  
  2.     CBitmap cbitmap;  
  3.     CPoint m_orgpt;  
  4.     CString cstring;  
  5.     CPoint cppt;  


位图:

 

OnDraw:

[html] view plain copy
  1. void CMyTextView::OnDraw(CDC* pDC)  
  2. {  
  3.     CMyTextDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     // TODO: add draw code for native data here  
  6.       
  7.     /*this->CreateSolidCaret(10,20);//创建一个光标  
  8.     this->ShowCaret();*/   //显示光标,这两个函数都是CWnd的成员函数  
  9.   
  10.       
  11.     /*TEXTMETRIC tm;               //这个结构体可以获取字体的信息  
  12.     pDC->GetTextMetrics(&tm);  
  13.     this->CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);//创建一个大小高度比较正常的光标  
  14.     this->ShowCaret();*/  
  15.   
  16.       
  17.     /*cbitmap.LoadBitmap(BITMAPID);//cbitmap资源一般设置成为成员变量  
  18.     this->CreateCaret(&cbitmap);//创建了一个位图光标,一闪一闪  
  19.     this->ShowCaret();*/  
  20.   
  21.     /*  
  22.     //CString cstring("大家好,欢迎一起学习MFC");  
  23.     CString cstring="大家好,欢迎一起学习MFC";  
  24.     pDC->TextOut(100,100,cstring);*/  
  25.   
  26.     /*CString cstring;  
  27.     cstring.LoadString(IDS_MYBOLG);  
  28.     pDC->TextOut(100,100,cstring);*/  
  29.   
  30.   
  31.     /*CString cstring("Hello,欢迎大家一起学习MFC");  
  32.     CSize cs=pDC->GetTextExtent(cstring);//区别跟TextMetric的不同,这里是根据字符串来获取的  
  33.     pDC->TextOut(100,100,cstring);  
  34.     pDC->BeginPath();  
  35.     pDC->Rectangle(100,100,cs.cx+100,cs.cy+100);//如果没有上下的XXPath,则显示一被白色画刷填充的矩形  
  36.     pDC->EndPath();  
  37.   
  38.       
  39.     //SelectClipPath的参数,大家不妨多试几种,看看效果  
  40.     //RGN_AND   RGN_COPY   RGN_DIFF   RGN_OR   RGN_XOR    
  41.     pDC->SelectClipPath(RGN_DIFF);  
  42.     for(int i=0;i<300;i+=10)//花了横竖很多线条,交叉着  
  43.     {  
  44.         pDC->MoveTo(i,0);  
  45.         pDC->LineTo(i,300);  
  46.   
  47.         pDC->MoveTo(0,i);  
  48.         pDC->LineTo(300,i);  
  49.     }*/  
  50.   
  51.     TEXTMETRIC tm;  
  52.     pDC->GetTextMetrics(&tm);  
  53.   
  54.     this->CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);  
  55.     this->ShowCaret();  
  56.   
  57.   
  58. }  


CXXView右键,添加一个WM_Char消息:

生成OnChar方法

[html] view plain copy
  1. <span style="font-size:10px;">void CMyTextView</span>::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.   
  5.     CClientDC ccdc(this);  
  6.     TEXTMETRIC tm;  
  7.     ccdc.GetTextMetrics(&tm);  
  8.   
  9.     CFont cfont;  
  10.     cfont.CreatePointFont(130,"宋体",NULL);  
  11.   
  12.     CFont *pcf=ccdc.SelectObject(&cfont);  
  13.   
  14.     if(0x0D==nChar)//换行  
  15.     {  
  16.   
  17.         cstring.Empty();//换行清空  
  18.         m_orgpt.y=m_orgpt.y+tm.tmHeight;//横坐标不变,纵坐标向下一个字符的高度  
  19.     }  
  20.     else if (0x08==nChar)//删除键  
  21.     {  
  22.           
  23.         COLORREF bkcolor=ccdc.GetBkColor();//获取背景颜色  
  24.         COLORREF oldcolor=ccdc.SetTextColor(bkcolor);//设置字体颜色为背景颜色,并且保留设置前的字体颜色  
  25.         ccdc.TextOut(m_orgpt.x,m_orgpt.y,cstring);//用背景颜色输出文字  
  26.         cstring=cstring.Left(cstring.GetLength()-1);//去掉最后一个字符  
  27.         ccdc.SetTextColor(oldcolor);//重新设置原来的字体颜色  
  28.       
  29.     }  
  30.     else  
  31.     {  
  32.         cstring+=nChar;//插入字符  
  33.     }  
  34.       
  35.     CSize cs=ccdc.GetTextExtent(cstring);//获取字体矩形的对象  
  36.     CPoint cpt;  
  37.     cpt.x=m_orgpt.x+cs.cx;  
  38.     cpt.y=m_orgpt.y;  
  39.     this->SetCaretPos(cpt);//重新设置光标的位置  
  40.     ccdc.TextOut(m_orgpt.x,m_orgpt.y,cstring);//输出字符串  
  41.   
  42.     ccdc.SelectObject(pcf);  
  43.   
  44.     CView::OnChar(nChar, nRepCnt, nFlags);  
  45. }  


感觉还是不完美,比如删除,当删除一行之后,应该跳回到上一行的最后,这里都没有判断,请自行测试

 

下面是单独出来的卡拉OK显示

成员变量:

[html] view plain copy
  1. private:  
  2.     CString cstring;  
  3.     int m_width;  


构造函数:

[html] view plain copy
  1. CJustTextView::CJustTextView()  
  2. {  
  3.     // TODO: add construction code here  
  4.     cstring="";  
  5.     m_width=0;  
  6. }  


OnDraw函数:

[html] view plain copy
  1. void CJustTextView::OnDraw(CDC* pDC)  
  2. {  
  3.     CJustTextDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     // TODO: add draw code for native data here  
  6.       
  7.     cstring="hello,welcome to myblog,欢迎大家一起学习MFC";  
  8.   
  9.     pDC->TextOut(0,200,cstring);  
  10.   
  11.     this->SetTimer(1,50,NULL);  
  12.   
  13.   
  14.   
  15.   
  16. }  


CXXView右键,添加一个WM_TIMER消息:

自动成成OnTimer方法

[html] view plain copy
  1. void CJustTextView::OnTimer(UINT nIDEvent)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.       
  5.     CClientDC ccdc(this);  
  6.     TEXTMETRIC tm;  
  7.     ccdc.GetTextMetrics(&tm);  
  8.   
  9.     CSize cs=ccdc.GetTextExtent(cstring);  
  10.     COLORREF oldcolor=ccdc.SetTextColor(RGB(255,0,0));  
  11.     if(1==nIDEvent)  
  12.     {  
  13.     m_width+=5;  
  14.       
  15.     CRect crect;  
  16.     crect.left=0;  
  17.     crect.top=200;  
  18.     crect.right=m_width;  
  19.     crect.bottom=crect.top+tm.tmHeight;  
  20.   
  21.     ccdc.DrawText(cstring,&crect,DT_LEFT);  
  22.   
  23.     crect.left=0;  
  24.     crect.top=150;  
  25.     crect.right=m_width;  
  26.     crect.bottom=crect.top+tm.tmHeight;  
  27.   
  28.     ccdc.DrawText(cstring,&crect,DT_RIGHT);  
  29.   
  30.     if(m_width>cs.cx)  
  31.     {  
  32.         m_width=0;  
  33.         ccdc.SetTextColor(RGB(0,255,0));  
  34.         ccdc.TextOut(0,200,cstring);  
  35.   
  36.         COLORREF bkcolor=ccdc.GetBkColor();  
  37.         ccdc.SetTextColor(bkcolor);  
  38.         ccdc.TextOut(0,150,cstring);  
  39.           
  40.     }  
  41.       
  42.     }  
  43.   
  44.       
  45.     CView::OnTimer(nIDEvent);  
  46. }  

0 0