调用的API: [DllImport("gdi32.dll", EntryPoint="LineDDA")] public static extern int LineDDA ( int nXStart, // 线条起点的X坐标 int nYStart, // 线条起点的Y坐标 int nXEnd, // 线条终点的X坐标 int nYEnd, // 线条终点的Y坐标 LineDDAProcHandle lpLineDDAProc, IntPtr lParam ); public delegate void LineDDAProcHandle( int X, // 被求值点的X坐标 int Y, // 被求值点的Y坐标 ref DrawStruct lpData ); private void LineDDAProc( int X, // 被求值点的X坐标 int Y, // 被求值点的Y坐标 ref DrawStruct mDrawStruct )// 应用程序定义数据的指针 { int modvalue = mDrawStruct.nWidth; if((X % modvalue) == 0) { for(int i=X-modvalue;i<X;i++) { int YY = (int)(modvalue * Math.Sin(1 * 3.1415926 * i / modvalue - modvalue)); LineTo(mDrawStruct.hdc,i,YY/2 + Y); //SetPixel(mDrawStruct.hdc,i,YY,mDrawStruct.mColor); } } //SetPixel(mDrawStruct.hdc,X,YY,mDrawStruct.mColor); } public enum dwPenStyle { PS_GEOMETRIC =0x10000, PS_COSMETIC = 0 } //publc public enum Hatch { HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS, HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL } public enum Style { BS_DIBPATTERN, BS_DIBPATTERN8X8, BS_DIBPATTERNPT, BS_HATCHED, BS_HOLLOW, BS_NULL, BS_PATTERN, BS_PATTERN8X8, BS_SOLID } [StructLayout(LayoutKind.Sequential)] public struct LOGBRUSH { public Style lbStyle; public int crColor; public Hatch lbHatch; } public enum PenStyles { PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT } [DllImport("gdi32.dll", EntryPoint="MoveToEx")] public static extern int MoveToEx ( IntPtr hdc, int x, int y, IntPtr lpPoint ); [DllImport("gdi32.dll")] private static extern IntPtr CreatePen(PenStyles enPenStyle, int nWidth, int crColor); [DllImport("gdi32.dll")] private static extern IntPtr ExtCreatePen( int dwPenStyle, // pen style int dwWidth, // pen width ref LOGBRUSH lplb, // brush attributes int dwStyleCount, // length of custom style array IntPtr lpStyle // custom style array ); [DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); [DllImport("gdi32.dll")] protected static extern bool DeleteObject(IntPtr hObject); public struct PenStylesStu { public PenStyles style; public override string ToString() { return style.ToString (); } } // [DllImport("gdi32.dll", EntryPoint="MoveToEx")] // public static extern int MoveToEx ( // IntPtr hdc, // int x, // int y, // ref POINTAPI lpPoint // ); [StructLayout(LayoutKind.Sequential)] public struct POINTAPI { public int X; public int Y; } [DllImport("gdi32.dll", EntryPoint="LineTo")] public static extern int LineTo ( IntPtr hdc, int x, int y ); [DllImport("gdi32.dll", EntryPoint="EndPath")] public static extern int EndPath ( IntPtr hdc ); [DllImport("gdi32.dll", EntryPoint="StrokePath")] public static extern int StrokePath ( IntPtr hdc ); [DllImport("gdi32.dll", EntryPoint="BeginPath")] public static extern int BeginPath ( IntPtr hdc ); public struct StyleStu { public Style style; public override string ToString() { return style.ToString (); } } public const int PS_GEOMETRIC = 0x10000; public const int PS_COSMETIC = 0x0; public const int PS_ENDCAP_ROUND = 0x0; public const int PS_ENDCAP_SQUARE = 0x100; public const int PS_ENDCAP_FLAT = 0x200; public const int PS_JOIN_BEVEL = 0x1000; public const int PS_JOIN_MITER = 0x2000; public const int PS_JOIN_ROUND = 0x0; public const int PS_SOLID = 0; public const int BS_SOLID = 0; public const int PS_USERSTYLE = 7; 绘制铁路线的代码: //绘制铁路线 Graphics g = Graphics.FromHwnd(this.panel1.Handle);//在panle1上绘制 g.Clear(Color.White); IntPtr hdc = g.GetHdc(); ///先绘制直线,比指定宽度大2 Color c = this.label3.BackColor; //获取颜色 int nWidth = (int)this.numericUpDown1.Value;//获取线宽 LOGBRUSH lb; lb.crColor= GetGDIRGB(c); lb.lbHatch = Hatch.HS_BDIAGONAL; lb.lbStyle = Style.BS_DIBPATTERN; IntPtr hPen, hOldPen; nWidth = nWidth + 2; hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID | PS_GEOMETRIC/* | iEnd [i] | iJoin [i]*/, nWidth , ref lb,0,IntPtr.Zero); hOldPen = SelectObject(hdc,hPen); MoveToEx(hdc,30,50,IntPtr.Zero); LineTo(hdc,this.panel1.Width - 60,200); SelectObject(hdc,hOldPen); DeleteObject(hPen); //再绘制白色虚线,用指定的宽度 c = Color.White; lb.crColor= GetGDIRGB(c); lb.lbHatch = Hatch.HS_BDIAGONAL; lb.lbStyle = Style.BS_DIBPATTERN; int[] kkk = new int[]{nWidth * 2,nWidth * 2}; int newWidth = nWidth - (nWidth/2)+1; if(newWidth > nWidth - 2) newWidth = nWidth - 2; hPen = ExtCreatePen(PS_ENDCAP_FLAT| PS_USERSTYLE | PS_GEOMETRIC/* | iEnd [i] | iJoin [i]*/, newWidth , ref lb, kkk.Length, Marshal.UnsafeAddrOfPinnedArrayElement(kkk,0)); hOldPen = SelectObject(hdc,hPen); MoveToEx(hdc,30,50,IntPtr.Zero); LineTo(hdc,this.panel1.Width - 60,200); SelectObject(hdc,hOldPen); DeleteObject(hPen); g.ReleaseHdc(hdc); g.Dispose(); //绘制国界线 private void button8_Click(object sender, System.EventArgs e) { Graphics g = Graphics.FromHwnd(this.panel1.Handle); g.Clear(Color.White); IntPtr hdc = g.GetHdc(); DrawStruct str = new DrawStruct(); int nWidth = (int)this.numericUpDown1.Value; str.hdc = hdc; Color c = this.label3.BackColor; str.mColor = GetGDIRGB(c); str.nWidth = nWidth; LOGBRUSH lb; lb.crColor= GetGDIRGB(c); lb.lbHatch = Hatch.HS_BDIAGONAL; lb.lbStyle = Style.BS_DIBPATTERN; IntPtr hPen, hOldPen; hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID | PS_GEOMETRIC/* | iEnd [i] | iJoin [i]*/, 1 , ref lb,0,IntPtr.Zero); hOldPen = SelectObject(hdc,hPen); //MoveToEx(hdc,10,50,IntPtr.Zero); str.oldX = this.panel1.Width -30; str.oldY = 50; str.nWidth = nWidth; IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str)); Marshal.StructureToPtr(str,ptr,true); MoveToEx(hdc,str.oldX,str.oldY,IntPtr.Zero); LineDDA(str.oldX,str.oldY,50,250, new LineDDAProcHandle(LineDDAProc_Guojie),ptr); SelectObject(hdc,hOldPen); DeleteObject(hPen); g.ReleaseHdc(hdc); Marshal.DestroyStructure(ptr,typeof(DrawStruct)); g.Dispose(); } /// <summary> /// 绘制国界线回调函数 /// </summary> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="mDrawStruct"></param> private void LineDDAProc_Guojie( int X, // 被求值点的X坐标 int Y, // 被求值点的Y坐标 ref DrawStruct mDrawStruct )// 应用程序定义数据的指针 { int modvalue = mDrawStruct.nWidth; double hg = mDrawStruct.nWidth;//方波高度 //计算2点间距离,粗略计算 double distance = 0.0; double angle = Math.Atan((double)(Y - mDrawStruct.oldY) / (double)(X - mDrawStruct.oldX));//线夹角 distance = (double)(X - mDrawStruct.oldX)*(X - mDrawStruct.oldX) + (double)(Y - mDrawStruct.oldY)*(Y - mDrawStruct.oldY); distance = Math.Abs( Math.Sqrt(distance)); if(distance > hg *4) { Point P0 = Point.Empty; Point P1 = Point.Empty; Point P2 = Point.Empty; Point P3 = Point.Empty; Point P4 = Point.Empty; P0.X = mDrawStruct.oldX; P0.Y = mDrawStruct.oldY; P2.X = (X + mDrawStruct.oldX) /2; P2.Y = (Y + mDrawStruct.oldY) /2; P1.X = (P2.X + mDrawStruct.oldX) /2; P1.Y = (P2.Y + mDrawStruct.oldY) /2; P4.X = X; P4.Y = Y; P3.X =(P4.X + P2.X)/2; P3.Y =(P4.Y + P2.Y)/2; //在P1点绘制一个点 SetPixel(mDrawStruct.hdc,P1.X,P1.Y,mDrawStruct.mColor); //在P2处绘制一条垂直的长度为hg的线段 Point P21 = Point.Empty; Point P22 =Point.Empty; //P2和P21的X差 = P1和P2的Y差 , P2和P21的Y差 = P2和P1的X差 P21.X = P2.X - (P1.Y - P2.Y) /2; P21.Y = P2.Y - (P2.X - P1.X) /2; //P2和P22的X差 P22.X = P2.X + (P1.Y - P2.Y) /2; P22.Y = P2.Y + (P2.X - P1.X) /2; Point P41 = Point.Empty; Point P42 = Point.Empty; P41.X = P4.X - (P3.Y - P4.Y) /2; P41.Y = P4.Y - (P4.X - P3.X) /2; //P2和P22的X差 P42.X = P4.X + (P3.Y - P4.Y) /2; P42.Y = P4.Y + (P4.X - P3.X) /2; MoveToEx(mDrawStruct.hdc,P21.X,P21.Y,IntPtr.Zero); LineTo(mDrawStruct.hdc,P22.X,P22.Y); MoveToEx(mDrawStruct.hdc,P2.X,P2.Y,IntPtr.Zero); LineTo(mDrawStruct.hdc,P4.X,P4.Y); MoveToEx(mDrawStruct.hdc,P41.X,P41.Y,IntPtr.Zero); LineTo(mDrawStruct.hdc,P42.X,P42.Y); mDrawStruct.oldX = P4.X; mDrawStruct.oldY = P4.Y; } } ///绘制城墙线 /// <summary> /// 绘制城墙线 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button7_Click(object sender, System.EventArgs e) { Graphics g = Graphics.FromHwnd(this.panel1.Handle); g.Clear(Color.White); IntPtr hdc = g.GetHdc(); DrawStruct str = new DrawStruct(); int nWidth = (int)this.numericUpDown1.Value; str.hdc = hdc; Color c = this.label3.BackColor; str.mColor = GetGDIRGB(c); str.nWidth = nWidth; LOGBRUSH lb; lb.crColor= GetGDIRGB(c); lb.lbHatch = Hatch.HS_BDIAGONAL; lb.lbStyle = Style.BS_DIBPATTERN; IntPtr hPen, hOldPen; hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID | PS_GEOMETRIC/* | iEnd [i] | iJoin [i]*/, 1 , ref lb,0,IntPtr.Zero); hOldPen = SelectObject(hdc,hPen); //MoveToEx(hdc,10,50,IntPtr.Zero); str.oldX = this.panel1.Width -30; str.oldY = 50; str.nWidth = nWidth; IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str)); Marshal.StructureToPtr(str,ptr,true); MoveToEx(hdc,str.oldX,str.oldY,IntPtr.Zero); LineDDA(str.oldX,str.oldY,50,50, new LineDDAProcHandle(LineDDAProc_CityWalline),ptr); SelectObject(hdc,hOldPen); DeleteObject(hPen); g.ReleaseHdc(hdc); Marshal.DestroyStructure(ptr,typeof(DrawStruct)); g.Dispose(); } /// <summary> /// 绘制城墙线(方波线)回调函数 /// </summary> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="mDrawStruct"></param> private void LineDDAProc_CityWalline( int X, // 被求值点的X坐标 int Y, // 被求值点的Y坐标 ref DrawStruct mDrawStruct )// 应用程序定义数据的指针 { { double hg = mDrawStruct.nWidth;//方波高度 //计算2点间距离,粗略计算 double distance = 0.0; double angle = Math.Atan((double)(Y - mDrawStruct.oldY) / (double)(X - mDrawStruct.oldX));//线夹角 distance = (double)(X - mDrawStruct.oldX)*(X - mDrawStruct.oldX) + (double)(Y - mDrawStruct.oldY)*(Y - mDrawStruct.oldY); distance = Math.Abs( Math.Sqrt(distance)); #region 第二种算法 if(distance >=hg* 2 )//距离大于2象素 { Point P1 = Point.Empty; Point P2 = Point.Empty; Point P3 = Point.Empty; Point P4 = Point.Empty; Point P5 = Point.Empty; //p1 P1.X = mDrawStruct.oldX; P1.Y = mDrawStruct.oldY; //p5 P5.X = X; P5.Y = Y; //p2 P2是起始2个端点的重心 P2.X =(X + mDrawStruct.oldX) /2; P2.Y =(Y + mDrawStruct.oldY) /2; //p3 P3和P2的X差 == P2和P5的Y差,P3和P2的Y差 = P2和P5的X差 P3.X = P2.Y - P5.Y + P2.X; P3.Y = P5.X - P2.X + P2.Y; //P4 P4和P3的X差 = P5和P2的X差 P4和P3的Y差 = P2和P5的Y差 P4.X = P5.X - P2.X + P3.X; P4.Y = P5.Y - P2.Y + P3.Y; //绘制方波线 // MoveToEx(mDrawStruct.hdc,P1.X,P1.Y,IntPtr.Zero); LineTo(mDrawStruct.hdc,P2.X,P2.Y); LineTo(mDrawStruct.hdc,P3.X,P3.Y); LineTo(mDrawStruct.hdc,P4.X,P4.Y); LineTo(mDrawStruct.hdc,P5.X,P5.Y); mDrawStruct.oldX = P5.X; mDrawStruct.oldY = P5.Y; } #endregion // } } ////绘波浪线 /// <summary> /// 绘波浪线 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button6_Click(object sender, System.EventArgs e) { Graphics g = Graphics.FromHwnd(this.panel1.Handle); g.Clear(Color.White); IntPtr hdc = g.GetHdc(); DrawStruct str = new DrawStruct(); str.hdc = hdc; int nWidth = (int)this.numericUpDown1.Value; str.nWidth = nWidth; Color c = this.label3.BackColor; str.mColor = GetGDIRGB(c); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str)); Marshal.StructureToPtr(str,ptr,true); //// LOGBRUSH lb;// lb.crColor= GetGDIRGB(c);// lb.lbHatch = Hatch.HS_BDIAGONAL;// lb.lbStyle = Style.BS_DIBPATTERN;//// // IntPtr hPen, hOldPen; // hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID |// PS_GEOMETRIC/* |// iEnd [i] |// iJoin [i]*/,// nWidth , ref lb,0,IntPtr.Zero);// hOldPen = SelectObject(hdc,hPen); MoveToEx(hdc,10,50,IntPtr.Zero); LineDDA(10,50,this.panel1.Width - 20,100,new LineDDAProcHandle(LineDDAProc),ptr); // SelectObject(hdc,hOldPen);// DeleteObject(hPen); g.ReleaseHdc(hdc); Marshal.DestroyStructure(ptr,typeof(DrawStruct)); g.Dispose(); }

评论