实现网络拓扑的自动绘制的自定义控件

运行界面如下所示:

topo2.JPG

//================================code begin=============================//
using
System;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Data;

using System.Windows.Forms;

 

namespace datalink.userCtrl

{

     /// <summary>

     /// 实现网络拓扑的自动绘制的自定义控件。

     /// </summary>

     public class Canvas : System.Windows.Forms.PictureBox

     {

         /// <summary>

         /// Required designer variable.

         /// </summary>

//       private int netID = -1;

//       private int outID = -1;

         private int items=0;

         private int active_item = 0;

         private int hover_item = -1;

         public string clickedText = "";

         public int clickedIndex = -1;

         private const int MAX_ELEMENTS = 255;

         private string[] menuitems = new string[MAX_ELEMENTS];

         private string[] tags = new string[MAX_ELEMENTS];

         private System.Drawing.Point[] item_start = new System.Drawing.Point[MAX_ELEMENTS];

         private System.Drawing.Point[] item_end = new System.Drawing.Point[MAX_ELEMENTS];

         private ImageList imageList = null;

         private Bitmap swImage = new Bitmap("sw.jpg");

         private Bitmap hostImage = new Bitmap("host.jpg");

         private Bitmap hostHoverImage = new Bitmap("hostHover.jpg");

         private Bitmap cloudImage = new Bitmap("cloud.jpg");

         private Bitmap hostSelectedImage = new Bitmap("hostSelted.jpg");

         private Bitmap hostTitle = new Bitmap("host.ico");

         private DataTable dataTab=null;

         private FrmFuseResult fuseFrm = new FrmFuseResult();

 

         private string sessionID="";

         private Graphics thisG;

         Brush bgBrush = Brushes.Chocolate;

         Brush fgBrush = Brushes.DarkBlue;

         Brush titleBrush = Brushes.White;

        

 

         //交换机水平间距switch vertical space

         private const int svSpace = 150;

         //主机(交换机)垂直间距 host vertical space

         private const int hvSpace = 120;

         //主机与交换机的水平间距

         private const int hshSpace = 60;

         //主机水平间距

         private const int hhSpace = 60;

         //主机与交换机连线水平间距

         private const int lhSpace = 5;

         //主机与交换机连线垂直间距

         private const int lvSpace = 10;

         //交换机长度

         private const int sWidth = 51;

         //交换机宽度

         private const int sHeight = 26;

         //主机长度

         private const int hWidth = 36;

         //主机宽度

         private const int hHeight = 39;

         //一个交换机挂接的主机数

         private const int hostsInSwitcher = 3;

 

         private int xMoved = 0,yMoved = 0;

         bool moved = false;

 

         int itemIndex = 0;

         int currentIndex = 0;//已经读到第几个主机。

         Pen bchPen = new Pen(Color.Black,2);

         Pen bchErasePen = new Pen(Color.White,2);

         Pen bonePen = new Pen(Color.Black,2);

 

         Point[] leftPoints = new Point[3];

         Point[] rightPoints = new Point[3];

//       Point[] hLeftPoints = new Point[3];

//       Point[] hRightPoints = new Point[3];

        

         private System.ComponentModel.Container components = null;

 

 

         public ImageList TabImageList

         {

              get { return imageList; }

              set { imageList = value;}

         }

        

         public DataTable DataTab

         {

              set { dataTab = value;}

         }

 

 

 

         public Canvas(System.ComponentModel.IContainer container)

         {

              ///

              /// Required for Windows.Forms Class Composition Designer support

              ///

              container.Add(this);

              InitializeComponent();

 

              //

              // TODO: Add any constructor code after InitializeComponent call

              //

         }

 

         public Canvas()

         {

              ///

              /// Required for Windows.Forms Class Composition Designer support

              ///

              InitializeComponent();

 

              //

              // TODO: Add any constructor code after InitializeComponent call

              //

         }

        

         /// <summary>

         /// Clean up any resources being used.

         /// </summary>

         protected override void Dispose( bool disposing )

         {

              if( disposing )

              {

                   if(components != null)

                   {

                       components.Dispose();

                  }

              }

              base.Dispose( disposing );

         }

 

         public void add_item()

         {

             

              if( items >= MAX_ELEMENTS )

              {

                   MessageBox.Show("超过最多允许显示的按钮数量,请与系统管理员联系", "系统信息",MessageBoxButtons.OKCancel,MessageBoxIcon.Error);

                   return;

              }

 

              item_start[items] = new System.Drawing.Point(0);

              item_end[items] = new System.Drawing.Point(0);

              items++;

              this.Refresh();

         }

 

         #region Component Designer generated code

         /// <summary>

         /// Required method for Designer support - do not modify

         /// the contents of this method with the code editor.

         /// </summary>

         private void InitializeComponent()

         {

              components = new System.ComponentModel.Container();

              this.Paint += new System.Windows.Forms.PaintEventHandler(this.Canvas_Paint);

              this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Canvas_MouseMove);

              this.MouseLeave += new System.EventHandler(this.Canvas_MouseLeave);

              this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Canvas_MouseDown);

              this.MouseUp +=new MouseEventHandler(Canvas_MouseUp);

             

         }

         #endregion

 

         private void Canvas_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

         {

             

//            if(dataTab != null)

                   DrawTree(new Point(this.Width/2,this.Height/2),e);

              itemIndex = 0;

         }

 

         public void DrawTree(Point centerP, System.Windows.Forms.PaintEventArgs e)

         {

              if(dataTab == null ) return;

              items = this.dataTab.Rows.Count;

              if(items == 0 ) return;         

              int switches = items/hostsInSwitcher + 1;//交换机的个数。每个交换机最多挂接hostsInSwitcher个终端

              if(items % hostsInSwitcher == 0 ) switches--;

             

             

              this.Navigate(xMoved,yMoved,e);

 

              Pen outPen = new Pen(Color.Purple,4);

              outPen.SetLineCap(LineCap.DiamondAnchor,LineCap.ArrowAnchor,DashCap.Triangle);

              e.Graphics.DrawImage(cloudImage,centerP.X-50,centerP.Y -200,150,82);

              e.Graphics.DrawLine(outPen,centerP.X +10,centerP.Y,centerP.X+10,centerP.Y -118);

              outPen.Dispose();

 

              Point sLeftEndPoint = new Point(centerP.X - 2*svSpace/3,centerP.Y);//中心交换机与边缘交换机间左边第一个转接点

              Point sRightEndPoint = new Point(centerP.X + 2*svSpace/3,centerP.Y);//中心交换机与边缘交换机间右边第一个转接点

              this.DrawBone(centerP,sLeftEndPoint,e);

 

             

 

        

              // Create array of points that define lines to draw.

              Point[] leftPoints =

                            {

                                 new Point( sLeftEndPoint.X,  sLeftEndPoint.Y),//xy都不变

                                 new Point( sLeftEndPoint.X,  sLeftEndPoint.Y),//x不变,y与下面点y坐标相同

                                 new Point( centerP.X - svSpace,  sLeftEndPoint.Y),//x不变,y与上面点y坐标相同

                            };

              Point[] rightPoints =

                            {

                                 new Point( sRightEndPoint.X,  sRightEndPoint.Y),//xy都不变

                                 new Point( sRightEndPoint.X,  sRightEndPoint.Y),//x不变,y与下面点y坐标相同

                                 new Point( centerP.X + svSpace,  sRightEndPoint.Y),//x不变,y与上面点y坐标相同

              };

 

              int leftSwitches =1;//已经在右边画了多少个交换机数

              int rightSwitches = 1;

              if(switches > 0)

              {

                   e.Graphics.DrawLines(bonePen, leftPoints);

 

                   this.DrawLeftHosts(leftPoints,e);

                   this.DrawSwitcher(leftPoints[2].X-sWidth,leftPoints[2].Y - sHeight/2,e);

 

                   if(switches > 1)

                   {

                       this.DrawBone(centerP,sRightEndPoint,e);

 

                       e.Graphics.DrawLines(bonePen,rightPoints);

                       this.DrawRightHosts(rightPoints,e);

                       this.DrawSwitcher(rightPoints[2].X,rightPoints[2].Y - sHeight/2,e);

 

                   }

              }

              this.DrawSwitcher(centerP.X-sWidth/2,centerP.Y-sHeight/2,e);

 

              //Draw lines to screen.

              for(int i=2;i<switches;i++)

              {

                   if(i%2==0)//draw the left part

                   {

                       if(leftSwitches % 2 == 0)

                            leftPoints[1].Y -= hvSpace * leftSwitches;

                       else

                            leftPoints[1].Y += hvSpace * leftSwitches;

 

                       leftPoints[2].Y = leftPoints[1].Y;

                       e.Graphics.DrawLines(bonePen, leftPoints);

 

                       this.DrawLeftHosts(leftPoints,e);

                       this.DrawSwitcher(leftPoints[2].X-sWidth,leftPoints[2].Y - sHeight/2,e);

 

                       leftSwitches++;

                   }

                   else//draw the right part

                   {

                       if(rightSwitches % 2 == 0)

                            rightPoints[1].Y -= hvSpace * rightSwitches;

                       else

                            rightPoints[1].Y += hvSpace * rightSwitches;

 

                       rightPoints[2].Y = rightPoints[1].Y;

                       e.Graphics.DrawLines(bonePen,rightPoints);

                       this.DrawRightHosts(rightPoints,e);

                       this.DrawSwitcher(rightPoints[2].X,rightPoints[2].Y - sHeight/2,e);

 

                      

 

                       rightSwitches++;

                   }

              }

              currentIndex = 0;

             

 

         }

         public void DrawBch(Point fromP,Point toP,int width,System.Windows.Forms.PaintEventArgs e)

         {

              bchPen.Width = width;

              e.Graphics.DrawLine(bchPen,fromP,toP);

         }

 

         public void DrawBone(Point fromP,Point toP,System.Windows.Forms.PaintEventArgs e)

         {

              bonePen.DashStyle = DashStyle.DashDot;

              e.Graphics.DrawLine(bonePen,fromP,toP);

             

         }

         public void DrawSwitcher(int x,int y,System.Windows.Forms.PaintEventArgs e)

         {

             

              e.Graphics.DrawImageUnscaled(swImage,x,y,sWidth,sHeight);

         }

         public void DrawBaseHost(int x,int y,System.Windows.Forms.PaintEventArgs e,Image i)

         {

              string hostName = dataTab.Rows[itemIndex]["ip_address"].ToString();

              e.Graphics.DrawImageUnscaled(i,x,y,sWidth,sHeight);

              // Set world transform of graphics object to translate.

              e.Graphics.TranslateTransform(x-30, y-35);

              // Then to rotate, appending rotation matrix.

              e.Graphics.RotateTransform(<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />20.0F, MatrixOrder.Prepend);

              e.Graphics.DrawString(hostName,new Font("Arial", 9),Brushes.Purple,0,0);

              e.Graphics.ResetTransform();

 

              this.Navigate(xMoved,yMoved,e);

              this.menuitems[itemIndex] = hostName;

              this.tags[itemIndex] = dataTab.Rows[itemIndex]["session_id"].ToString();

              itemIndex++;

         }

         public void DrawHost(int x,int y,System.Windows.Forms.PaintEventArgs e)

         {

             

              this.DrawBaseHost(x,y,e,this.hostImage);

         }

         public void DrawHostHover(int x,int y,System.Windows.Forms.PaintEventArgs e)

         {

             

              this.DrawBaseHost(x,y,e,this.hostHoverImage);

         }

         public void DrawHostAtcive(int x,int y,System.Windows.Forms.PaintEventArgs e)

         {

             

              this.DrawBaseHost(x,y,e,this.hostSelectedImage);

         }

 

         public void DrawRightHosts(Point[] p,System.Windows.Forms.PaintEventArgs e)

         {

              int hostNum = 0;

              for(int j=currentIndex;j<items;j++)

              {

                   hostNum = j-currentIndex;

                   int spaceToOrgn = (hostsInSwitcher - hostNum ) * hhSpace;

 

                   item_start[itemIndex].X = p[2].X + spaceToOrgn +hshSpace-hWidth;

                   item_start[itemIndex].Y = p[2].Y - sHeight/2;

                   item_end[itemIndex].X = item_start[itemIndex].X + hWidth;

                   item_end[itemIndex].Y = item_start[itemIndex].Y + hHeight;

                   //绘出连接线

                   e.Graphics.DrawRectangle(bchPen,p[2].X + sWidth - lhSpace * (hostsInSwitcher - hostNum),p[2].Y + sHeight/2,

                       hshSpace + (lhSpace + hhSpace) * (hostsInSwitcher - hostNum-1),

                       20 + lvSpace*(hostsInSwitcher - hostNum));

                   e.Graphics.DrawLine(bchErasePen,p[2].X + sWidth - lhSpace * (hostsInSwitcher - hostNum),p[2].Y + sHeight/2,

                       p[2].X + sWidth - lhSpace * (hostsInSwitcher - hostNum) + hshSpace + (lhSpace + hhSpace) * (hostsInSwitcher - hostNum-1),

                       p[2].Y + sHeight/2);

                           

                   if(active_item == itemIndex)

                       this.DrawHostAtcive(item_start[itemIndex].X,item_start[itemIndex].Y,e);

                   else if(hover_item == itemIndex)

                       this.DrawHostHover(item_start[itemIndex].X,item_start[itemIndex].Y,e);

                   else

                       this.DrawHost(item_start[itemIndex].X,item_start[itemIndex].Y,e);

 

                   if(hostNum == (hostsInSwitcher-1))

                   {

                       currentIndex +=hostsInSwitcher;

                       break;

                   }

              }

         }

         public void DrawLeftHosts(Point[] p,System.Windows.Forms.PaintEventArgs e)

         {

              int hostNum = 0;

              for(int j=currentIndex;j<items;j++)

              {

                   hostNum = j-currentIndex;

                   int spaceToOrgn = (hostsInSwitcher - hostNum ) * hhSpace;

 

                   item_start[itemIndex].X = p[2].X - spaceToOrgn - hshSpace;

                   item_start[itemIndex].Y = p[2].Y - sHeight/2;

                   item_end[itemIndex].X = item_start[itemIndex].X + hWidth;

                   item_end[itemIndex].Y = item_start[itemIndex].Y + hHeight;

                   e.Graphics.DrawRectangle(bchPen,item_start[itemIndex].X + hWidth/2,item_start[itemIndex].Y + hHeight/2,

                       hshSpace + (lhSpace + hhSpace) * (hostsInSwitcher - hostNum -1 ),

                       20+lvSpace*(hostsInSwitcher - hostNum ));

                   e.Graphics.DrawLine(bchErasePen,item_start[itemIndex].X + hWidth/2,item_start[itemIndex].Y + hHeight/2,

                       item_start[itemIndex].X + hWidth/2 + hshSpace + (lhSpace + hhSpace) * (hostsInSwitcher - hostNum ),

                       item_start[itemIndex].Y + hHeight/2);

 

                   int xPos = item_start[itemIndex].X;

                   if(active_item == itemIndex)

                       this.DrawHostAtcive(xPos,item_start[itemIndex].Y,e);

                   else if(hover_item == itemIndex)

                       this.DrawHostHover(xPos,item_start[itemIndex].Y,e);

                   else

                       this.DrawHost(xPos,item_start[itemIndex].Y,e);

 

                   if(hostNum == (hostsInSwitcher-1))

                   {

                       currentIndex +=hostsInSwitcher;

                       break;

                   }

              }

         }

        

         private void Navigate(int x,int  y,System.Windows.Forms.PaintEventArgs e)

         {

              if(moved)

                   e.Graphics.TranslateTransform(x,y);

         }

         private void Canvas_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)

         {

              bool need_activation;

              for(int i=0;i<items;i++)

              {

                   if(  (e.X > item_start[i].X && e.Y > item_start[i].Y) &&

                       (e.X < item_end[i].X  &&  e.Y < item_end[i].Y)

                       )

                   {

                       this.Cursor = System.Windows.Forms.Cursors.Hand;

                       need_activation = (hover_item!=i);

                       hover_item = i;

                       if(need_activation) this.Refresh();

                       return;

                   }

              }

              this.Cursor = System.Windows.Forms.Cursors.Default;

         }

 

         private void Canvas_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)

         {

//            this.Cursor = System.Windows.Forms.Cursors.Cross;

              xMoved = e.X;

              yMoved = e.Y;

              this.clickedText = "";

              active_item = hover_item;           

              for(int i=0;i<items;i++)

              {

                   if( (e.X > item_start[i].X && e.Y > item_start[i].Y) &&

                       (e.X < item_end[i].X  &&  e.Y < item_end[i].Y)

                       )

                   {

                       //                     childs[i].Activate();

                       clickedText = menuitems[i];

                       clickedIndex = i;

                       active_item = i;

                       this.sessionID = tags[i];

                       this.Refresh();

                       ShowTips(e.X,e.Y);

                                    

                       return;

                   }

              }

         }

 

         private void ShowTips(float xPos, float yPos)

         {

              thisG = this.CreateGraphics();

              float tipWidth = 250,tipHeight = 150;//信息提示窗口的大小。

             

              int m = 0;

              float x = xPos,y=yPos;

             

              string[] values = new string[3];

              fuseFrm.FillBaseInfo(sessionID,ref values);

              Font tipF = new Font("Arial", 9);

              values[0] = "计算机名:" + values[0];

              values[1] = "地理位置:" + values[1];

              values[2] = "机构名称:" + values[2];

              string[] values2 =  new string[3]{"","",""};

              fuseFrm.FillOS(sessionID,ref values2);

              values2[0] = "操作系统:" + values2[0];

              SizeF size = thisG.MeasureString(values[0],tipF);

              //计算出提示框的大小

              for(int i=0;i<3;i++)

              {

                   size = thisG.MeasureString(values2[i],tipF);

                   if(size.Width > tipWidth) tipWidth = size.Width;

                   size = thisG.MeasureString(values[i],tipF);

                   if(size.Width > tipWidth ) tipWidth = size.Width;

 

              }

              if(values2[1] != "") tipHeight += size.Height;

              if(values2[2] != "") tipHeight += size.Height;

              //根据鼠标点位置确定提示框显示的位置

              if(this.Width - xPos < tipWidth)

              {

                   xPos -= tipWidth;

              }

              if(this.Height - yPos < tipHeight)

              {

                   yPos =yPos - tipHeight -25 ;

              }

              yPos += 25;

 

              Bitmap map = new Bitmap(Convert.ToInt32(tipWidth),Convert.ToInt32(tipHeight));

              Graphics g = Graphics.FromImage(map);

              x = xPos ;

              y = yPos ;

              xPos=yPos=0;

//            map.MakeTransparent(Color.DarkRed);

              //绘出背景框

              g.DrawRectangle(Pens.Black,xPos -2,yPos-2,tipWidth+4,tipHeight+4);

              g.FillRectangle(bgBrush,xPos,yPos,tipWidth,tipHeight);

 

              //文字缩进设置

              xPos +=3;

              yPos +=3;

 

              //绘出标题

              g.FillRectangle(Brushes.DarkRed,xPos-2,yPos - 2,tipWidth -2,size.Height +4 );

              g.DrawLine(Pens.Black,xPos,yPos + size.Height + 2,xPos + tipWidth -4,yPos + size.Height + 2);

              g.DrawRectangle(new Pen(Color.DarkRed,2),xPos-2,yPos - 2,tipWidth -2,tipHeight-2);

              Font titleFont = new Font("Arial",10,FontStyle.Bold);

              g.DrawImage(hostTitle,xPos,yPos,size.Height,size.Height);

              g.DrawString(this.clickedText,titleFont,titleBrush,xPos + size.Height,yPos); m += 4;

              titleFont.Dispose();

              yPos +=4;

 

                  

              g.DrawString(values[0],tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;             

              g.DrawString(values[1],tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;             

              g.DrawString(values[2],tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;

             

              g.DrawString(values2[0],tipF,fgBrush,xPos,yPos + m * size.Height/3);m += 4;

              if(values2[1] != "")

              {

                   values2[1] = ">>> " + values2[1];

                   g.DrawString(values2[1],tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;

                   if(values2[2] != "")

                   {

                       values2[2] = ">>> " + values2[2];

                       g.DrawString(values2[2],tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;

                   }

              }

             

              string vuls = "漏洞数目:" + fuseFrm.GetVulCount(sessionID).ToString();

              g.DrawString(vuls,tipF,fgBrush,xPos,yPos + m * size.Height/3); m += 4;

 

              string ports = "开放端口:" + fuseFrm.GetPortCount(sessionID).ToString();

              g.DrawString(ports,tipF,fgBrush,xPos,yPos + m * size.Height/3);

 

              map.MakeTransparent(Color.Cornsilk);

              thisG.DrawImage(map,x-2,y-2);

             

              thisG.Dispose();

              tipF.Dispose();

              g.Dispose();

 

         }

         private void Canvas_MouseLeave(object sender, System.EventArgs e)

         {

              hover_item = -1;

              this.Refresh();

         }

 

 

        

         private void Canvas_MouseUp(object sender, MouseEventArgs e)

         {

         }

     }

}

 

调用方法如下:

private datalink.userCtrl.Canvas myCanvas;

this.myCanvas.BackColor = System.Drawing.SystemColors.ActiveCaptionText;

              this.myCanvas.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;

              this.myCanvas.Dock = System.Windows.Forms.DockStyle.Fill;

              this.myCanvas.Location = new System.Drawing.Point(211, 44);

              this.myCanvas.Name = "myCanvas";

              this.myCanvas.Size = new System.Drawing.Size(581, 380);

              this.myCanvas.TabIndex = 5;

              this.myCanvas.TabStop = false;

              this.myCanvas.DoubleClick +=new EventHandler(myCanvas_DoubleClick);

              for(int i=0;i<45;i++)

              {

                   this.myCanvas.add_item();

              }

this.myCanvas.DataTab =  ds.Tables[0];

转载于:https://www.cnblogs.com/keynuo/archive/2004/05/06/8420.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值