第 2章 文档和视内容摘要:
1,通过视类与用户交互
2,通过视类与用户交互返回目录
2.1 通过视类与用户交互学习目标
1,在程序中响应鼠标消息
2,在程序中响应键盘消息
2.1
返回第 2章程序的实现步骤
1,利用 AppWizard生成单文档程序框架 (DocView )
2,为视类添加数据成员
2.1
BOOL m_bMouseDown; //标识鼠标左键是否按下
HCURSOR m_hCross; //十字型鼠标句柄
HCURSOR m_hArrow; //标准型鼠标句柄
CPoint m_ptOld; //临时点
CPoint m_ptStart; //画线的起始点
3,在构造函数中初始化成员变量
CDocViewView::CDocViewView()
{
m_bMouseDown = false;
m_hCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
m_hArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
}
2.1
voidCDocViewView:,OnLButtonDown (UINT nFlags,CPoint point)
{
// TODO,Add your message handler code here and/or call default
m_bMouseDown = true; // 鼠标左键按下
m_ptStart = point; // 画线的起点
m_ptOld = point; // 临时点
SetCapture(); // 将鼠标消息发送到视窗口
CRect rect;
GetClientRect(&rect); // 得到客户窗口的大小
ClientToScreen(&rect); // 将当前窗口坐标转换成屏幕坐标
ClipCursor(&rect); // 把鼠标限定在其参数指定的矩形区域内
SetCursor(m_hCross); // 设置鼠标形状为十字形
CView::OnLButtonDown(nFlags,point);
}
4.为视类添加鼠标动作响应函数
2.1
voidCMyDrawView::OnMouseMove(UINT nFlags,CPoint point)
{
// TODO,Add your message handler code here and/or call default
if( m_bMouseDown )
{
CClientDC dc(this);
dc.SetROP2( R2_NOT );
dc.MoveTo(m_ptStart ); //这两行代码擦除从起点 ( 鼠标按下点 ) 到
dc.LineTo(m_ptOld ); //上次鼠标移动到的位置之间的临时线
dc.MoveTo(m_ptStart ); //这两行代码从起点到鼠标当前位置画线
dc.LineTo(point); //
m_ptOld = point; //鼠标当前位置在下一次鼠标移动事件看来就是 "旧位置 "
}
CView::OnMouseMove(nFlags,point);
}
4.为视类添加鼠标动作响应函数
voidCMyDrawView::OnLButtonUp(UINT nFlags,CPoint point)
{
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); //
SetCursor(m_hArrow); //设置鼠标形状为标准箭头形
}
CView::OnLButtonUp(nFlags,point);
}
2.1
程序的实现步骤 _2
1.为视类添加数据成员为视类添加数据成员
2.1
intm_nLine; //记录已输入字符行数
CString m_strDisplay; //保存当前字符串的变量
2,在构造函数中初始化成员变量
CDocViewView::CDocViewView()
{
// TODO,add construction code here
m_nLine = 0;
m_bMouseDown = false;
m_hCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
m_hArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
}
3.为视类添加键盘消息响应函数 2.1
voidCDocViewView::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
if(nChar == VK_RETURN) //如果按下回车键
{
m_strDisplay.Empty();
m_nLine++;
}
elseif(m_strDisplay.GetLength() < 64) //当前行字符数小于 64
m_strDisplay += nChar;
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
intnLineHeight = tm.tmHeight + tm.tmExternalLeading;
dc.TextOut(0,m_nLine * nLineHeight,m_strDisplay);
CView::OnChar(nChar,nRepCnt,nFlags);
}
基本知识
1,AfxGetApp()
LoadStandardCursor(IDC_CROSS);
2.GetClientRect(&rect); // 得到客户窗口的大小
3.ClientToScreen(&rect); // 将当前窗口坐标转换成屏幕坐标
4.ClipCursor(&rect); // 把鼠标限定在其参数指定的矩形区域内
5.SetCursor(m_hCross); // 设置鼠标形状为十字形
2.1
2.2 利用文档类处理数据学习目标
1,在文档类中保存数据
2.2
返回第 2章程序的实现步骤
1,添加类 CLine
2.2
class CLine,publicCObject
{
public:
CPoint m_ptStart;
CPoint m_ptEnd;
CLine();
CLine(CPointpt1,CPoint pt2);
virtual~CLine();
voidDraw(CDC *pDC);
};
2.2CLine::CLine()
{
}
CLine::CLine(CPointpt1,CPoint pt2)
{
m_ptStart.x = pt1.x;
m_ptStart.y = pt1.y;
m_ptEnd.x = pt2.x;
m_ptEnd.y = pt2.y;
}
CLine::~CLine()
{
}
voidCLine::Draw(CDC *pDC)
{
pDC->MoveTo(m_ptStart);
pDC->LineTo(m_ptEnd);
}
程序的实现步骤
2,在文档类中添加保存数据的变量
2.2
public:
CString m_strLastLine;
CStringList m_strList;
CPtrList m_LineList;
3.修改视类成员函数 OnButtonUp()和 OnChar()
程序的实现步骤 2.2voidCDocViewView::OnLButtonUp(UINT nFlags,CPoint point){
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);
CDocViewDoc *pDoc = GetDocument(); //得到文档类指针
CLine*pLine = new CLine(m_ptStart,point); //创建 CLine对象
pDoc->m_LineList.AddTail((void*) pLine); //将 pLine加入到链表中
}
SetCursor(m_hArrow); //设置鼠标形状为标准箭头形
CView::OnLButtonUp(nFlags,point);
}
程序的实现步骤voidCDocViewView::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags){
CDocViewDoc *pDoc = GetDocument();
if(nChar==VK_RETURN)
{
pDoc->m_strList.AddTail(m_strDisplay);
pDoc->m_strLastLine.Empty();
m_strDisplay.Empty();
m_nLine++;
}
elseif(m_strDisplay.GetLength()<64)
{
m_strDisplay+= nChar;
pDoc->m_strLastLine = m_strDisplay;
}
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
intnLineHeight=tm.tmHeight+ tm.tmExternalLeading;
dc.TextOut(0,m_nLine*nLineHeight,m_strDisplay);
CView::OnChar(nChar,nRepCnt,nFlags);
}
2.2
程序的实现步骤 2.2
voidCDocViewDoc::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);
}
}
4,在文档类中添加重画直线和重写文本的函数程序的实现步骤 2.2
voidCDocViewDoc::DrawText(CDC *pDC)
{
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
intnLineHeight = tm.tmHeight + tm.tmExternalLeading;
CString str;
intline = 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 );
}
程序的实现步骤 2.2
voidCDocViewView::OnDraw(CDC* pDC)
{
CDocViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO,add draw code for native data here
pDoc->DrawLine(pDC);
pDoc->DrawText(pDC);
}
5.修改视类成员函数 OnDraw()
返回第 2章