第十章、绘图控制

10.1简单绘图

建立一个单文档应用程序,取名为Graphic,此程序将实现点、直线、矩形和椭圆的绘图功能。
首先添加一个子菜单,菜单名为绘图,再添加四个菜单项,来控制不同图形的绘制。然后为四个菜单项添加视类命令消息响应函数。
当用户单击某个菜单项时,应该将用户的选择保存起来,因此添加一个视类的成员变量:m_nDrawType,私有类型,并在视类的构造函数中将其初始化为0。

在四个菜单项命令消息响应函数中将m_nDrawType设置为不同值:

void CGraphicView::OnDot() 
{
 // TODO: Add your command handler code here
 m_nDrawType=1;
}
void CGraphicView::OnLine() 
{
 // TODO: Add your command handler code here
 m_nDrawType=2;
}
void CGraphicView::OnRectangle() 
{
 // TODO: Add your command handler code here
 m_nDrawType=3; 
}
void CGraphicView::OnEllipse() 
{
 // TODO: Add your command handler code here
 m_nDrawType=4; 
}

在绘图时,可以用两个点来确定图形。当鼠标左键按下的时候,应该将此点保存起来。因此需要为视类添加一个私有类型的CPiont类型的成员变量:m_ptOrigin。并在视类的构造函数中初始化为(0,0)。

添加鼠标左键按下的消息响应函数,并在该消息响应函数中,保存按下点的坐标:

void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 m_ptOrigin=point;
 CView::OnLButtonDown(nFlags, point);
}

添加鼠标左键弹起消息响应函数,在鼠标左键松开时实现绘图功能:

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 CClientDC dc(this);
 switch(m_nDrawType)
 {
 case 1:
  dc.SetPixel(point,RGB(255,0,0));
  break;
 case 2:
  dc.MoveTo(m_ptOrigin);
  dc.LineTo(point);
  break;
 case 3:
  dc.Rectangle(CRect(m_ptOrigin,point));
  break;
 case 4:
  dc.Ellipse(CRect(m_ptOrigin,point));
  break;
 }
 CView::OnLButtonUp(nFlags, point);
}

运行,如图。
第十章、绘图控制_第1张图片
线条的颜色是由DC中的画笔决定的,为了绘制其他颜色的线条,需要构造一个画笔对象,指定一种颜色,然后将画笔选入设备描述表中。
在CClientDC dc(this);后面添加:

CPen pen(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(&pen);

如果不想用白色画刷填充,可以将画刷设置为透明的,在刚刚添加的代码下再添加:

CBrush *pBrush=CBrush::FormHandle((HBRUSH)GetStockObject
(NULL_BRUSH));
dc.SelectObject(pBrush);

FormHandle将画刷句柄转变为画刷对象指针。
运行结果如图。
第十章、绘图控制_第2张图片

10.2设置对话框

添加一个对话框,允许用户指定画笔的类型、线宽,然后按照指定的类型进行绘图操作。ID:IDD_DLG_SETTING,Caption:Setting,Font:宋体。

10.2.1设置线宽

给对话框添加一个静态文本框,Caption:线宽。设置一个编辑框,ID:IDC_LINE_WIDTH。如图。
第十章、绘图控制_第3张图片
接着为对话框资源添加对话框类:双击对话框资源,单机OK,将新的对话框名称设置为:CSettingDlg。单击OK,就创建好了关联IDD_DLG_SETTING对话框资源的对话框类。

接下来需要为编辑框控件关联一个成员变量:鼠标右键单击编辑框控件->ClassWizard->Member Variables。因为线宽不小于0,所以类型为UINT。如图。
第十章、绘图控制_第4张图片
然后在绘图子菜单下添加一个菜单项:设置,将其ID设置为IDM_SETTING,然后添加菜单项命令消息响应函数,用视类对消息进行响应,在该函数中调用DoMOdal函数显示对话框。

void CGraphicView::OnSetting() 
{
 // TODO: Add your command handler code here
 CSettingDlg dlg;
 dlg.DoModal();
}

由于会用到CSettingDlg类,需要在视类源文件中添加:
#include “SettingDlg.h”
运行如图。
第十章、绘图控制_第5张图片
在编辑框中输入线宽后,应该存起来。为视类添加一个私有成员变量:m_nLineWidth,类型也是UINT,接收对话框类中线宽值。并在构造函数中初始化为0。

void CGraphicView::OnSetting() 
{
 // TODO: Add your command handler code here
 CSettingDlg dlg;
 if(IDOK==dlg.DoModal())
 {
  m_nLineWidth=dlg.m_nLineWidth;
 }
}

先执行dlg.DoModal(),然后判断返回是否是OK,是的话存起来线宽。
然后就将创建画笔的代码改为:

CPen pen(PS_SOLID,m_nLineWidth,RGB(255,0,0));

运行,绘图的线条就是用户设置的线宽大小了。

但是再次打开设置对话框,线宽编辑框值又变回0了。
因为dlg是一个局部变量,再次运行,dlg的m_nLineWidth初始化为0。

void CGraphicView::OnSetting() 
{
 // TODO: Add your command handler code here
 CSettingDlg dlg;
 dlg.m_nLineWidth=m_nLineWidth;
 if(IDOK==dlg.DoModal())
 {
  m_nLineWidth=dlg.m_nLineWidth;
 }
}

因为对话框虽然关闭,但是对话框类对象仍然存在,它所保存的m_nLineWidth值也一直存在。

10.2.2设置线型

添加一个组框:Caption为线型,因为组框需要操作,ID修改为IDC_LINE_STYLE。
在组框内添加三个单选按钮,将第一个按钮Group属性勾选上,这三个按钮就是一组了,同样为这组按钮关联一个成员变量:m_LineSytle,选中第一个按钮默认为0,第二个为1,没选为-1。

接着为视类添加一个int型成员变量:m_nLineStyle,在构造函数中初始化为0。与之前操作一样,然后将用户选择的线型保存下来。

void CGraphicView::OnSetting() 
{
 // TODO: Add your command handler code here
 CSettingDlg dlg;
 dlg.m_nLineWidth=m_nLineWidth;
 dlg.m_nLineStyle=m_nLineStyle;
 if(IDOK==dlg.DoModal())
 {
  m_nLineWidth=dlg.m_nLineWidth;
  m_nLineStyle=dlg.m_nLineStyle;
 }
}

选择之前创建画笔代码中PS_SOLID,回到定义处,发现它的值本身就是0,PS_DASH是1,PS_DOT是2。因此可以将上述代码改为:

CPen pen(m_nLineStyle,m_nLineWidth,RGB(255,0,0));

运行如图。
第十章、绘图控制_第6张图片

你可能感兴趣的:(VC++孙)