MFC文本编程,首先必须创建一个插入符(即窗口中闪动的光标),如下:
int CMyTextView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CClientDC dc(this);
//获取文本度量
TEXTMETRIC textInfo;
dc.GetTextMetrics(&textInfo);
//创建插入符
CreateSolidCaret(textInfo.tmAveCharWidth/8,textInfo.tmHeight);
//显示插入符,默认不显示
ShowCaret();
return 0;
}
显示图形的插入符:
其中位图CBitmap变量要申明为View类的私有变量,与变量的生存周期有关
hbitmap.LoadBitmap(IDB_BITMAP1);
CreateCaret(&hbitmap);
//显示插入符,默认不显示
ShowCaret();
MFC下的窗口重绘内容可以写在View类的OnDraw()函数里面:
如下为在一个窗口固定位置输出一段字符串:
void CMyTextView::OnDraw(CDC* pDC)
{
CMyTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str;
str="我的第一个MFC字符串";
//CString类的赋值还可以用其成员函数LoadString()函数来加载字符串资源,字符串资源ID以及值都存储在String Table表里面
pDC->TextOut(100,100,str);
// TODO: add draw code for native data here
}
获取字符串的宽度和高度,创建新的路径层,不会覆盖原来的路径层,产生重叠。设置剪切区域,也就是在窗口的某个位置去划定一个小的区域,然后在该小区域中操作:
CString str;
str="我的第一个MFC字符串";
CSize size;
pDC->TextOut(100,100,str);
//获取字符串宽度和高度
size=pDC->GetTextExtent(str);
//创建新的路径层
pDC->BeginPath();
pDC->Rectangle(100,100,100+size.cx,100+size.cy);
pDC->EndPath();
//选择当前路径层作为一个剪切区域, 并用一定的模式将新的区域和已经存在的剪切区域联合起来
pDC->SelectClipPath(RGN_XOR );
for (int i=0;i<300;i+=5)
{
pDC->MoveTo(0,i);
pDC->LineTo(300,i);
pDC->MoveTo(i,0);
pDC->LineTo(i,300);
}
ps:getTextMetrics()是取得当前字符串的字符宽高信息,而 getTextExtent()是取得当前给定字符串的总宽度和高度信息
响应键盘消息并输出:
void CMyTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
TEXTMETRIC textinfo;
dc.GetTextMetrics(&textinfo);
//对不同的消息作出判断并处理
//如果是回车,则改变插入符的Y坐标
if (0x0d==nChar)
{
str_in.Empty();
cursorPoint.y+=textinfo.tmHeight;
}
//如果是退格,则将原来的字符串用背景色来输出,并去除左右边的一个字符然后用原色输出,以达到一中直接删除的效果
//人类的眼睛实在是太容易上当了
else if (0x08==nChar)
{
//获取背景色
COLORREF textcor=dc.GetBkColor();
//设置字符颜色,该函数返回没有设置字符颜色之前的颜色
COLORREF co=dc.SetTextColor(textcor);
dc.TextOut(cursorPoint.x,cursorPoint.y,str_in);
//去除一个字符
str_in=str_in.Left(str_in.GetLength()-1);
//将颜色返回为原来的颜色
dc.SetTextColor(co);
// dc.TextOut(cursorPoint.x,cursorPoint.y,str_in);
}
else
str_in+=nChar;
//获取输出字符后插入符移动后的坐标
CPoint po;
po.x=cursorPoint.x+dc.GetTextExtent(str_in).cx;
po.y=cursorPoint.y;
//设置插入符新的坐标位置
SetCaretPos(po);
dc.TextOut(cursorPoint.x,cursorPoint.y,str_in);
CView::OnChar(nChar, nRepCnt, nFlags);
}
//鼠标左键按下时,将插入符的位置移动到鼠标按下的位置,注意此时也要清空字符串,在新的位置输出以后的内容
void CMyTextView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
cursorPoint=point;
SetCaretPos(cursorPoint);
str_in.Empty();
CView::OnLButtonDown(nFlags, point);
}
设置字体:
CFont font;
//字体初始化,第一个参数为字符大小,单位为一个点的十分之一
font.CreatePointFont(120,"华文行楷",NULL);
//将字体选入设备描述表,返回的是原来的字体
CFont *old_font=dc.SelectObject(&font);
以上程序只是实现了一些基本的文字编辑功能,要实现一个完整的字处理程序还有很多要做的,MFC给我们提供了CEditView类和CRichEditView类帮助我们实现强大的字处理功能,直接让视图类继承其中一个类就具备了一些基本的文字处理功能。
文字平滑变色效果:
首先添加定时器:
在OnCreate()函数中添加定时器
//第二个参数为定时器的ID,第三个参数为定时器周期单位为毫秒,第三个参数为回调函数指针,为空则交给操作系统调用响应的函数处理该消息
::SetTimer(m_hWnd,1,100,NULL);
响应定时器:
void CMyTextView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//每次增加矩形宽度
m_with+=5;
CClientDC dc(this);
TEXTMETRIC textinformation;
dc.GetTextMetrics(&textinformation);
CRect rect;
rect.left=cursorPoint.x;
rect.top=cursorPoint.y;
//矩形的宽度在变化
rect.right=m_with;
rect.bottom=cursorPoint.y+textinformation.tmHeight;
dc.SetTextColor(RGB(255,0,0));
//在一个矩形范围内显示文字,第四个参数设定滑动的方向
dc.DrawText(str_in,&rect,DT_CENTER);
CSize strsize=dc.GetTextExtent(str_in);
//如果矩形长度超过了文字长度,则把矩形宽度置为0,以便文字重复滑动
if (m_with>strsize.cx)
{
m_with=0;
dc.SetTextColor(RGB(0,255,0));
dc.TextOut(cursorPoint.x,cursorPoint.y,str_in);
}
CView::OnTimer(nIDEvent);
}
PS:一个问题没解决,窗口重绘问题?且慢慢看下去,遇到解决方法再补充