|
摘要:本文以一个对话框程序为例,介绍如何在VC所提供的控件的窗口内绘制交互式图形的技巧和思路,并给出详细代码介绍和程序效果示例。
现在很多的图形系统和GIS软件都具有让用户自定义线型的功能。在众多的提供自定义线型功能的软件中,几乎都是通过对话框的方式为用户构建一个线型制作工具。其实,这样工具用VC开发起来显得十分简洁。下面以一个简单的对话框程序为大家提供一种开发思路。
首先,使用VC新建一个名为Defline对话框程序,并在其中添加一个图片框控件并将其后拖动到合适的大小,将ID号改为ID_STATIC_DRAW。接着添加七个按钮,分别将标题改为绘制直线、绘制圆、绘制区域、全部删除、删除图形、保存退出、放弃退出,并将对应的ID改为ID_BUTTON_LINE、 ID_BUTTON_CIRCLE 、ID_BUTTON_POLYRGN、ID_BUTTON_DELETEALL、ID_BUTTON_DELETEGRAPH、ID_BUTTON_SAVEQUIT、ID_BUTTON_EXIT。添加好控件和对话框如图1所示:
设计好界面后分别为各个按钮添加事件处理程序并为对话框添加以下事件:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
为了可以让用户在图片框控件所确定的窗口内自由画图形,需要将图片框控件的窗口和CDC类关联起来。根据VC的定义,控件窗口相当于多文档或单文档程序的视图,可以在其中进行各种绘制操作,所以,可以先在CDeflineDlg类中定义一个CDC型变量CDC * pStaticDC和一个CRect型变量CRect m_ClientRect,然后在OnInitDialog()函数中添加以下初始化代码:
CStatic* pST= (CStatic* )this->GetDlgItem(IDC_STATIC_DRAW); //获取对话框控件窗口指针
pST->GetClientRect(&m_ClientRect); //获取客户区窗口矩形
StaticDC=pST->GetDC( ); //初始化CDC变量,以便在控件窗口内绘图
经过上述步骤之后,便可以编写图形绘制的代码了。下面是本程序中所编写的绘图代码:
void CDeflineDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(m_CurrentDraw==1)
{
if(m_nCount==0)
{
m_ptS=point;
m_ptE=point;
m_nCount++;
}
else if(m_nCount==1)
{
m_nCount=0;
}
}
else if( m_CurrentDraw==2)
{
if(m_nCount==0)
{
m_ptS=point;
m_ptE=point;
m_nCount++;
}
else if(m_nCount==1)
{
m_nCount=0;
}
}
else if( m_CurrentDraw==3)
{
if(m_nCount==0)
{
m_ptS=point;
m_ptE=point;
}
pPoint[m_nHelpPolygon]=point;
m_nHelpPolygon++;
}
CDialog::OnLButtonDown(nFlags, point);
}
void CDeflineDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
pStaticDC->SetROP2(R2_NOTXORPEN);
if(m_CurrentDraw==1&&m_nCount==1)
{
if(m_ptE!=point)
{
this->DrawLine(m_ptS,m_ptE);
this->DrawLine(m_ptS,point);
m_ptE=point;
ReleaseCapture( );
}
}
if(m_CurrentDraw==2&&m_nCount==1)
{
if(m_ptE!=point)
{
this->DrawCircle(m_ptS,m_ptE);
this->DrawCircle(m_ptS,point);
m_ptE=point;
}
}
if(m_CurrentDraw==3&&m_nHelpPolygon!=0)
{
if(m_ptE!=point)
{
this->DrawLine(m_ptS,m_ptE);
this->DrawLine(m_ptS,point);
m_ptE=point;
}
}
CDialog::OnMouseMove(nFlags, point);
}
void CDeflineDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(m_CurrentDraw==3)
{
if(m_nHelpPolygon>=2)
{
this->DrawEnd( pPoint,m_nHelpPolygon);
m_nHelpPolygon=0;
}
}
CDialog::OnRButtonDown(nFlags, point);
}
以下是程序中的绘图函数代码:
void CDeflineDlg::DrawLine( CPoint ptS,CPoint ptE)
{
pStaticDC->MoveTo(ptS);
pStaticDC->LineTo(ptE);
}
void CDeflineDlg::DrawCircle(CPoint ptS,CPoint ptE)
{
float r= (float)sqrt((float)( (ptS.x-ptE.x)*(ptS.x-ptE.x)+(ptS.y-ptE.y)*(ptS.y-ptE.y)));
pStaticDC->Ellipse( ptS.x-r,ptS.y-r,ptS.x+r,ptS.y+r);
}
void CDeflineDlg::DrawEnd(CPoint*pt,int nCount)
{
if(nCount>2)
{
this->DrawLine(pt[nCount-1],pt[0]);
}
}
以上介绍了如何在控件窗口内开发绘图程序的一些基本操作。尤其值得注意的是在控件窗口内绘图时还要进行窗口坐标转换等,可以查阅MSDN。
|