在练习1中做出的结果下,如果我们略微改动下窗口的大小,原有的数据什么的全部都消失不见了!这是因为,当窗口要重画时,我们并没有对当前的内容进行保存,下面对其进行相关的修改使之趋于完善。首先,我们建立一个类对当前的画线信息进行存放,而字符则保存在CStringList的对象里。
1、建立Cline类
1>在Insert菜单下进行New Class,类型为Generic Class,名字为Cline
2>添加数据成员函数、构造函数及画线函数
class Cline
{
public:
Cline();
Cline(CPoint pt1,CPoint pt2);//构造函数
void Draw(CDC *pDC);//画线函数
virtual ~Cline();
CPoint m_pStart,m_pEnd;//新增画线变量
};
Cline::Cline(CPoint pt1,CPoint pt2)
{
m_pStart.x=pt1.x;
m_pStart.y=pt1.y;
m_pEnd.x=pt2.x;
m_pEnd.y=pt2.y;
}
void Cline::Draw(CDC *pDC)
{
pDC->MoveTo(m_pStart);
pDC->LineTo(m_pEnd);
}
说明:
a.MoveTo()将画笔移到指定位置,LineTo()从当前位置画到指定参数点;
2、在文档类中添加变量
//新增数据成员
public:
CString m_strLastLine;//存放最后一行字符
CStringList m_strList;//存放除最后一行外的所有字符
CPtrList m_LineList;//链表类型
3、修改视类成员函数OnButtonUp()与OnChar()
在视类cpp中增加include "line.h"后,再进行修改,下有说明位置为新增代码
void CSDIView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bMouseDown)
{
m_bMouseDown=false;
ReleaseCapture();
ClipCursor(NULL);
CClientDC dc(this);
dc.SetROP2(R2_NOT);
dc.MoveTo(m_ptStart);
dc.LineTo(m_ptOld);
dc.SetROP2(R2_COPYPEN);
dc.MoveTo(m_ptStart);
dc.LineTo(point);
CSDIDoc *pDoc=GetDocument();//得到文档类指针
Cline *pLine=new Cline (m_ptStart,point);//创建CLine对象
pDoc->m_LineList.AddTail( (void*) pLine);//将pLine加入链表中
SetCursor(m_hArrow);
}
CView::OnLButtonUp(nFlags, point);
}
void CSDIView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CSDIDoc *pDoc=GetDocument();//创建文档类指针
if(nChar==VK_RETURN)
{
pDoc->m_strList.AddTail(m_strDisplay);//将末行保存在m_strList当中
pDoc->m_strLastLine.Empty();//清空m_strLastLine
m_strDisplay.Empty();
m_nLine++;
}
else if(m_strDisplay.GetLength()<64)
{
m_strDisplay+=nChar;
pDoc->m_strLastLine=m_strDisplay;//保存末行
}
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
int nLineHeight=tm.tmHeight+tm.tmExternalLeading;
dc.TextOut(0,m_nLine*nLineHeight,m_strDisplay);
CView::OnChar(nChar, nRepCnt, nFlags);
}
4、在文档类中增添重画直线与重写文本函数
在文档类cpp中增加include "line.h"后,再进行修改,下有说明位置为新增代码
//新增成员函数
public:
void DrawLine(CDC *pDC);
void DrawText(CDC *pDC);
void CSDIDoc::DrawLine(CDC *pDC)
{
Cline *pLine;
POSITION pos=m_LineList.GetHeadPosition();//寻求链表头结点
for(;pos!=NULL;m_LineList.GetNext(pos))//继续下一结点
{
pLine=(Cline*) m_LineList.GetAt(pos);//寻求指定点结点
pLine->Draw(pDC);//调用画线函数
}
}
void CSDIDoc::DrawText(CDC *pDC)//同上
{
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
int nLineHeight=tm.tmHeight+tm.tmExternalLeading;
CString str;
int line=0;
POSITION pos=m_strList.GetHeadPosition();
for(;pos!=NULL;m_strList.GetNext(pos))
{
str=m_strList.GetAt(pos);
pDC->TextOut(0,line* nLineHeight,str);
line++;
}
pDC->TextOut(0,line*nLineHeight,m_strLastLine);
}
5、修改视类OnDraw()函数
void CSDIView::OnDraw(CDC* pDC)
{
CSDIDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(100,100,"Hello! Lsy!");
pDoc->DrawLine(pDC);
pDoc->DrawText(pDC);
// TODO: add draw code for native data here
}
说明:
a.当窗口重画时,一般窗口框架等由系统自动完成,但窗口中的文字和图形必须由程序代码实现;
b.重画时,OnDraw()函数调用。