新建一个Text工程 1、 创建一个自定义的插入符,也就是光标: 在TextView.cpp中添加如下函数: int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) {//该函数是在窗口创建好之后就执行的函数。 if (CView::OnCreate(lpCreateStruct) == -1) return -1; CreateSolidCaret(2,20);//自己定义的光标的宽度和高度。 ShowCaret();//必须调用此函数来显示光标 return 0; } 2、 根据文本字体创建的插入符 int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; CClientDC dc(this); TEXTMETRIC tm;//定义一个结构体变量,该结构体里包含了文本字体的高度和宽度等信息 dc.GetTextMetrics(&tm);//该函数作用是根据文本字体的信息来填充这个结构体,如高度、宽度等 CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);//根据文本字体的高度和宽度来创建光标 ShowCaret(); return 0; } 3、 创建一个位图光标: ① 在TextView.h中定义一个私有变量CBitmap bitmap,位图是一个资源,不能在TextView.cpp中的函数中定义,因为资源在函数执行完时,会调用析构函数自动销毁。 ② 在TextView.cpp中的OnCreate()函数中如下定义: int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here bitmap.LoadBitmap(IDB_BITMAP1);//加载这个位图 CreateCaret(&bitmap);//该函数作用是用位图创建光标 ShowCaret(); return 0; } 4、 输出显示一个字符串 void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CString str; str="索广宇会成功的!"; pDC->TextOut(50,50,str);//第一种直接输出字符串,前两个参数是字符串输出地位置。 str.LoadString(IDS_PIAO);// IDS_PIAO是字符串资源的ID号 pDC->TextOut(0,120,str);//第二种加载字符串资源,从而输出资源中的字符串 } 5、 路径层和剪切区的交互作用 void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CString str; str="索广宇会成功的!"; pDC->TextOut(50,50,str); CSize sz=pDC->GetTextExtent(str);//该函数的作用是获得字符串的长度和宽度,存储在CSize对象中。 pDC->BeginPath(); pDC->Rectangle(50,50,50+sz.cx,50+sz.cy); pDC->EndPath();//这三句定义了一个矩形的路径层,把上面的str覆盖在路径层当中 pDC->SelectClipPath(RGN_DIFF);//该函数的作用是使路径层和当前的剪切区域,按指定的方式进行交互,以得到新的剪切区域,其实剪切区域也就相当于是当前的工作区域 for(int i=0;i<300;i+=10) {//这里是用线条画了一个网格,以显示路径层和剪切区域交互的结果 pDC->MoveTo(0,i); pDC->LineTo(300,i); pDC->MoveTo(i,0); pDC->LineTo(i,300); } } 6、 字符串的输入 概括来说就是先把字符串写到一个字符串对象里,再用TextOut进行输出: ① 在TextView.cpp中添加WM_CHAR和WM_ONLBUTTONDOWN消息接收函数,在TextView.h中定义两个私有变量: CPoint m_ptOrigin ; CString m_strLine,在构造函数中,初始化为:m_ptOrigin=0,m_strLine=””。 ② 在TextView.cpp中作如下操作: void CTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {//该函数作用是捕捉字符串消息,不是严格意义上的键盘消息 // TODO: Add your message handler code here and/or call default CClientDC dc(this); 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); CView::OnChar(nChar, nRepCnt, nFlags); } void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCaretPos(point);//用鼠标点击,设置光标的位置 m_ptOrigin=point;//把这个点保存起来,作为字符串输入的起始位置 m_strLine.Empty();//在设置了新的光标位置后,把字符串对象里面的内容清空 CView::OnLButtonDown(nFlags, point); } 拓: 改变一下字体的颜色: 在OnChar()函数中添加如下语句: CFont font;//定义一个字体对象 font.CreatePointFont(200,"华文行楷",NULL);//参数分别为字体大小、类型和… CFont *pOldFont=dc.SelectObject(&font); 7、 模拟卡拉OK字幕变色的功能: (1) 在TextView.h中,添加一个私有变量:int m_nWidth; (2) 在OnCreate()函数中添加一个定时器(按一定频率发送一个信号):SetTimer(1,100,NULL);//参数分别为定时器编号,发送时隔(单位是毫秒),不解释 (3) 在TextView.cpp中,做一下处理(添加一个接受定时器发送的信号的函数): void CTextView::OnTimer(UINT nIDEvent) {//该函数实现的是字幕逐渐变成红色后,再一次性变成绿色。 // TODO: Add your message handler code here and/or call default if(m_nWidth!=-1) { m_nWidth+=5; CClientDC dc(this); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left=0; rect.top=120; rect.right=m_nWidth; rect.bottom=rect.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); CString str; str.LoadString(IDS_SUO); dc.DrawText(str,rect,DT_LEFT);//该函数输出的是矩形框中的字符串,随着函数的不断执行,矩形框不断增大,就实现了字幕处理。 CSize sz; sz=dc.GetTextExtent(str); if(m_nWidth>sz.cx) { m_nWidth=-1; dc.SetTextColor(RGB(0,255,0)); dc.TextOut(0,120,str); } } CView::OnTimer(nIDEvent); }