本实例CSDN代码下载链接:http://download.csdn.net/detail/shortcoder/5838413
基本思想:
1、获取设备DC
2、设置画笔、起点坐标、终点坐标
3、DC画线
步骤:
1、新建一个基于对话框的MFC程序
2、在Dlg类中添加成员函数:每次重绘都要保留所画的直线,故设置坐标数组
CPoint m_begin[100];//起点坐标数组,最大100个点
CPoint m_end[100];//终点坐标数组,最大100个点
CPen *m_pen; //画笔
int flag; //用于标记左键的状态 0未按下 1按下
int count; //直线的条数
3、在构造函数中对新加的变量进行初始化:
count = 0; //直线个数为0
m_begin[count].x = m_end[count].x = 0;//构造函数,初始化起点、终点坐标为0
m_begin[count].y = m_end[count].y = 0;
flag = 0; //标记鼠标左键未按下
m_pen = new CPen(0,0,RGB(255,255,255));//初始化画笔,粗细、颜色
4、在paint函数中写如for循环:
else
{
for(int i=0;i<count;i++)//每次重绘即画出已保存的所有直线
{
CClientDC dc(this);//客户区DC //获取客户区DC
dc.MoveTo(m_begin[i]);//直线
dc.LineTo(m_end[i]);
}
CDialog::OnPaint();
}
5、给对话框添加鼠标左键按下、抬起和鼠标移动消息处理:
void CMy20130728Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
flag = 1; //标记鼠标左键按下
m_begin[count] = m_end[count] = point;//设置起点、终点左边为鼠标按下的位置
CDialog::OnLButtonDown(nFlags, point);
}
void CMy20130728Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
CClientDC dc(this);//客户区DC //获取客户区DC
flag = 0; //标记鼠标左键未按下
m_end[count] = point;//设置终点为左键抬起时的位置
dc.MoveTo(m_begin[count]);//直线
dc.LineTo(m_end[count]);
count++; //每次左键抬起,直线个数 +1
CDialog::OnLButtonUp(nFlags, point);
}
void CMy20130728Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
if(flag==1)
{
CClientDC dc(this);//客户区DC
dc.SelectObject(m_pen);//设置画笔
dc.SetROP2(R2_XORPEN);//设置反色,
dc.MoveTo(m_begin[count]);
dc.LineTo(m_end[count]);//在上一条直线的位置以反色再画一条直线
//等同于一条直线画两次,第二次会反色覆盖,即等于未画线
m_end[count] = point;//设置终点坐标为当前鼠标所在的位置
dc.MoveTo(m_begin[count]);//画直线
dc.LineTo(m_end[count]);
}
CDialog::OnMouseMove(nFlags, point);
}
这样一个简单的画直线的MFC对话框程序就OK了。
扩展:
1、设置画笔时可以设置画笔宽度和颜色,可以在对话框上加入按钮或菜单,根据用户需求进行画笔的设置
2、直线工具实现后,可实现矩形、圆形、三角形...
3、实现自由画笔
4、SetROP2函数的两个参数R2_NOT与R2_NOTXORPEN的使用效果,以下为该两种绘画模式举例:
- R2_NOTXORPEN绘画模式
你用红色画笔在黑色背景上画一条直线,显示红色,但你再用这只笔在刚画的直线上重画一遍,就相当于把开始画的红线擦除掉了,划线的地方显示为背景色。 - R2_NOT绘画模式
同样有在同一个地方画两次相当于什么都没画的功能,不过R2_NOT绘画模式第一次画的时候显示颜色并不是你选定的画笔颜色,而是默认的颜色。 -