昨天花了点时间以ListView为基础,为各ListItem添加了连接箭头,模拟出一个简单的流程图界面,拖动图标时亦会调整重绘连线。
<!-- google_ad_client = "pub-5395599807454886"; /* 468x15文字连接广告, 创建于 08-11-21 */ google_ad_slot = "5196248270"; google_ad_width = 468; google_ad_height = 15; //-->
重点在绘箭头连接线用的DrawFlowLine函数上,有需要的朋友可自己扩展一下:
- //CommCtrl,GraphUtil
- procedureDrawFlowLine(ACanvas:TCanvas;SrcItem,DestItem:TListItem);
- var
- SrcPt,DestPt:TPoint;
- SrcRect,DestRect:TRect;
- ArrowDirect:TScrollDirection;
- begin
- //取对象的中点供比较之用
- ListView_GetItemRect(SrcItem.ListView.Handle,SrcItem.Index,SrcRect,0);
- ListView_GetItemRect(DestItem.ListView.Handle,DestItem.Index,DestRect,0);
- SrcPt.X:=SrcRect.Left+(SrcRect.Right-SrcRect.Left)div2;
- SrcPt.Y:=SrcRect.Top+(SrcRect.Bottom-SrcRect.Top)div2;
- DestPt.X:=DestRect.Left+(DestRect.Right-DestRect.Left)div2;
- DestPt.Y:=DestRect.Top+(DestRect.Bottom-DestRect.Top)div2;
- //通过中点的比较决定箭头方向
- ifAbs(SrcPt.X-DestPt.X)>Abs(SrcPt.Y-DestPt.Y)thenbegin
- ifSrcPt.X<=DestPt.XthenArrowDirect:=sdRight
- elseArrowDirect:=sdLeft;
- endelsebegin
- ifSrcPt.Y<=DestPt.YthenArrowDirect:=sdDown
- elseArrowDirect:=sdUp;
- end;
- //计算线段的起点与终点
- caseArrowDirectof
- sdLeft:begin
- SrcPt:=Point(DestRect.Right-16,DestRect.Top+((DestRect.Bottom-DestRect.Top)div2));
- DestPt:=Point(SrcRect.Left+16,SrcRect.Top+((SrcRect.Bottom-SrcRect.Top)div2));
- end;
- sdRight:begin
- SrcPt:=Point(SrcRect.Right-16,SrcRect.Top+((SrcRect.Bottom-SrcRect.Top)div2));
- DestPt:=Point(DestRect.Left+16,DestRect.Top+((DestRect.Bottom-DestRect.Top)div2));
- end;
- sdUp:begin
- SrcPt:=Point(DestRect.Left+((DestRect.Right-DestRect.Left)div2),DestRect.Bottom+2);
- DestPt:=Point(SrcRect.Left+((SrcRect.Right-SrcRect.Left)div2),SrcRect.Top);
- end;
- sdDown:begin
- SrcPt:=Point(SrcRect.Left+((SrcRect.Right-SrcRect.Left)div2),SrcRect.Bottom);
- DestPt:=Point(DestRect.Left+((DestRect.Right-DestRect.Left)div2),DestRect.Top);
- end;
- end;
- //绘制连线
- ACanvas.Pen.Width:=2;
- caseArrowDirectof
- sdLeft,sdRight:begin
- ACanvas.MoveTo(SrcPt.X,SrcPt.Y);
- ACanvas.LineTo(SrcPt.X+8,SrcPt.Y);
- ACanvas.LineTo(DestPt.X-8,DestPt.Y);
- ACanvas.LineTo(DestPt.X,DestPt.Y);
- end;
- sdUp,sdDown:begin
- ACanvas.MoveTo(SrcPt.X,SrcPt.Y);
- ACanvas.LineTo(SrcPt.X,SrcPt.Y+8);
- ACanvas.LineTo(DestPt.X,DestPt.Y-8);
- ACanvas.LineTo(DestPt.X,DestPt.Y-2);
- end;
- end;
- //绘制箭头
- caseArrowDirectof
- sdLeft:DrawArrow(ACanvas,sdLeft,Point(SrcPt.X-2,SrcPt.Y-5),4);
- sdRight:DrawArrow(ACanvas,sdRight,Point(DestPt.X-2,DestPt.Y-5),4);
- sdUp:DrawArrow(ACanvas,sdUp,Point(SrcPt.X-5,SrcPt.Y-2),4);
- sdDown:DrawArrow(ACanvas,sdDown,Point(DestPt.X-5,DestPt.Y-4),4);
- end;
- end;
完整的程序已上传到我的资源中:
http://download.csdn.net/source/758098
<!-- google_ad_client = "pub-5395599807454886"; /* 468x15文字连接广告, 创建于 08-11-21 */ google_ad_slot = "5196248270"; google_ad_width = 468; google_ad_height = 15; //-->