CPen whitepen(PS_SOLID,1,RGB(255,255,255));
CPen* pOldPen;
pOldPen=clientDC.SelectObject (&whitepen);
clientDC.MoveTo (startpoint);
clientDC.LineTo (lastpoint);
clientDC.SelectObject (pOldPen);
CPen redpen(PS_DOT ,1,RGB(255,0,0));
pOldPen=clientDC.SelectObject (&redpen);
clientDC.MoveTo (startpoint);
clientDC.LineTo (point);
clientDC.SelectObject (pOldPen);
lastpoint=point;
//重绘所有输入结点前的序号
redrawnum();
//重绘连接线
LinkLineRedraw(startpoint,point);
//重绘物件
lineRedraw(startpoint,point);
}
这里,startpoint是鼠标按下开始连接时起始元件触点中心点坐
标,lastpoint是上一次鼠标移动所停留的点。为了实在连接时鼠标移动
的动画效果,我们要先擦除上一次移动画的线(用白笔),然后再从startpoint到当前点point画线。移动时由于不信的擦除重画,可能将先前已画的元件,输入结点前的序号,和已经连接好的线擦除。于是我们需要重绘。
重绘所有输入结点前的序号
redrawnum();
void CMyView::redrawnum()
{
CClientDC dc(this);
char buffer[20];
CPoint point;
//重绘所有Input前的序号
for(int i=0;i<numpoint.GetSize ();i++)
{
//将数字转换成字符,存于buffer中
_itoa(i+1,buffer,10);
point=numpoint.GetAt (i);
dc.TextOut (point.x ,point.y ,buffer);
}
}
由于每创建一个输入结点,就要相应地记录一个序号。这个序号的位置点记录在numpoint这个数组中。数组声明如下:
CArray<CPoint,CPoint> numpoint;
而数组的下标加1就为序号。
所以每次重绘为了方便,将所有序号都重绘。
重绘连接线
void CMyView::LinkLineRedraw(CPoint startpoint, CPoint point)
{
//将起点startpoint到终点point扩充成一个矩形drawrect
CRect drawrect(startpoint,point);
//rect用于产生连接线最大矩形
CRect rect;
//rectInter用于计算两个矩形的相交区域
CRect rectInter;
//point1和point2用于产生连接线最大矩形
CPoint point1;
CPoint point2;
drawrect.NormalizeRect ();
drawrect.InflateRect (1,1);
//遍历MyPointList链表
POSITION pos=MyPointList.GetHeadPosition ();
while(pos!=0)
{
//pPointArray用于指向点数组对象首址
CArray<CPoint,CPoint>* pPointArray=MyPointList.GetNext (pos);
point1=pPointArray->GetAt (0);
switch(pPointArray->GetSize ())
{
//分两种情况 :2个点和4,5个点的情况
case 2:
//2个点时
point2=pPointArray->GetAt (1);
break;
default:
//4,5个点时
point2=pPointArray->GetAt (3);
}
//用point1和point2设置矩形rect
rect.left =point1.x ;
rect.top =point1.y;
rect.right =point2.x;
rect.bottom =point2.y;
rect.NormalizeRect ();
rect.InflateRect (1,1);
//如果两个矩形相交,则要重绘
if(rectInter.IntersectRect (&drawrect,&rect))
{
DrawLinkLine(pPointArray);
}
}
}
主要的算法思想是:将起点startpoint到当前点point扩充成一个矩形drawrect,然后遍历连接线链表,将每根连接线扩充成一个矩形rect,再判断这两个矩形是否相交,若相交,则需要重绘这根连接线。
连接线链表声明如下:
CList<CArray<CPoint,CPoint>*,CArray<CPoint,CPoint>*>
MyPointList;
链表中每个结点是一个数组对象的地址,而这个数组中每个元素是一个点。这样一个数组就表示了一根连接线,而一个链表可以遍历所以连接线。
画提示连接的小圆圈函数:DrawMyCircle()
void CMyView::DrawMyCircle()
{
//此时全局变量circlepoint记录了要画圆圈的
//而pNodeNow指向了当前的物件
//将物件坐标中的circlepoint转换成VIEW中的坐标
int x,y;
x=pNodeNow->Orgpoint .x +circlepoint.x;
y=pNodeNow->Orgpoint .y +circlepoint.y;
CClientDC dc(this);
//创建一个黑色的画刷
CBrush brush(RGB(0,0,0));
//创建指针pOldBrush用于保存原来的画刷
CBrush* pOldBrush;
//将黑色的画刷选进设备装置DC,并用pOldBrush保存原来的画刷
pOldBrush=dc.SelectObject (&brush);
//画一个圆圈,圆心是(x,y)
上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页