昨天花了点时间以ListView为基础,为各ListItem添加了连接箭头,模拟出一个简单的流程图界面,拖动图标时亦会调整重绘连线。
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
重点在绘箭头连接线用的DrawFlowLine函数上,有需要的朋友可自己扩展一下:
- //CommCtrl, GraphUtil
- procedure DrawFlowLine(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) div 2;
- SrcPt.Y := SrcRect.Top + (SrcRect.Bottom - SrcRect.Top) div 2;
- DestPt.X := DestRect.Left + (DestRect.Right - DestRect.Left) div 2;
- DestPt.Y := DestRect.Top + (DestRect.Bottom - DestRect.Top) div 2;
- //通过中点的比较决定箭头方向
- if Abs(SrcPt.X - DestPt.X) > Abs(SrcPt.Y - DestPt.Y) then begin
- if SrcPt.X <= DestPt.X then ArrowDirect := sdRight
- else ArrowDirect := sdLeft;
- end else begin
- if SrcPt.Y <= DestPt.Y then ArrowDirect := sdDown
- else ArrowDirect := sdUp;
- end;
- //计算线段的起点与终点
- case ArrowDirect of
- sdLeft: begin
- SrcPt := Point(DestRect.Right-16, DestRect.Top + ((DestRect.Bottom-DestRect.Top) div 2));
- DestPt := Point(SrcRect.Left+16, SrcRect.Top + ((SrcRect.Bottom-SrcRect.Top) div 2));
- end;
- sdRight: begin
- SrcPt := Point(SrcRect.Right-16, SrcRect.Top + ((SrcRect.Bottom-SrcRect.Top) div 2));
- DestPt := Point(DestRect.Left+16, DestRect.Top + ((DestRect.Bottom-DestRect.Top) div 2));
- end;
- sdUp: begin
- SrcPt := Point(DestRect.Left + ((DestRect.Right-DestRect.Left) div 2), DestRect.Bottom+2);
- DestPt := Point(SrcRect.Left + ((SrcRect.Right-SrcRect.Left) div 2), SrcRect.Top);
- end;
- sdDown: begin
- SrcPt := Point(SrcRect.Left + ((SrcRect.Right-SrcRect.Left) div 2), SrcRect.Bottom);
- DestPt := Point(DestRect.Left + ((DestRect.Right-DestRect.Left) div 2), DestRect.Top);
- end;
- end;
- //绘制连线
- ACanvas.Pen.Width := 2;
- case ArrowDirect of
- 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;
- //绘制箭头
- case ArrowDirect of
- 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
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>