GDI Topics: Polylines

 Introduction
 A polyline is a series of connected lines. The lines are stored in an array of TPoint values. To draw a polyline, you use the TCanvas::Polyline() method. Its syntax is: ```void __fastcall Polyline(const Types::TPoint* Points, const int Points_Size);``` The Points argument is an array of TPoint values. The Points_Size argument specifies the number of members of the array. When executing, the compiler moves the starting point to Points[0]. The first line is drawn from Points[0] to Points[1] as in:
```//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
TPoint Pt[] = { Point(60, 20), Point(60, 122) };

Canvas->MoveTo(Pt[0].x, Pt[0].y);
Canvas->LineTo(Pt[1].x, Pt[1].y);
}
//---------------------------------------------------------------------------```

To draw a polyline, you must have at least two points. If you define more than two points, each line after the first would be drawn from the previous point to the next point until all points have been included. Here is an example:

 ```//--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { TPoint Pt[7]; Pt[0] = Point(20, 50); Pt[1] = Point(180, 50); Pt[2] = Point(180, 20); Pt[3] = Point(230, 70); Pt[4] = Point(180, 120); Pt[5] = Point(180, 90); Pt[6] = Point(20, 90); Canvas->Polyline(Pt, 7); } //---------------------------------------------------------------------------```

Besides the Polyline() method, the Win32 API provides the PolylineTo() function. Its syntax is:

`BOOL PolylineTo(HDC hdc, CONST POINT *lppt, DWORD cCount);`

The hdc argument is a handle to the canvas on which you are drawing.

The lppt argument is the name of an array of POINT or TPoint objects.

The cCount argument specifies the number of points that would be included in the figure. Here is an example:

 ```//--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { TPoint Pt[7]; Pt[0] = Point(20, 50); Pt[1] = Point(180, 50); Pt[2] = Point(180, 20); Pt[3] = Point(230, 70); Pt[4] = Point(180, 120); Pt[5] = Point(180, 90); Pt[6] = Point(20, 90); HDC hDC = Canvas->Handle; PolylineTo(hDC, Pt, 7); } //---------------------------------------------------------------------------```

While the Polyline() method starts the first line at lppt[0], the PolylineTo() function does not control the beginning of the first line. Like the LineTo() method, it simply starts drawing, which would mean it could starts at the origin (0, 0). For this reason, if you want to control the starting point of the PolylineTo() drawing, you can use the MoveTo() method:

 ```//--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { TPoint Pt[7]; Pt[0] = Point(20, 50); Pt[1] = Point(180, 50); Pt[2] = Point(180, 20); Pt[3] = Point(230, 70); Pt[4] = Point(180, 120); Pt[5] = Point(180, 90); Pt[6] = Point(20, 90); HDC hDC = Canvas->Handle; Canvas->MoveTo(20, 30); PolylineTo(hDC, Pt, 7); Canvas->LineTo(20, 110); } //---------------------------------------------------------------------------```

 Multiple Polylines
 The above polylines were used each as a single entity. That is, a polyline is a combination of lines. If you want to draw various polylines in one step, you can use the Win32 API's PolyPolyline() function. By definition, PolyPolyline() is used to draw a series of polylines. Its syntax is: `BOOL PolyPolyline(HDC hdc, CONST POINT *lppt, CONST DWORD *lpdwPolyPoints, DWORD cCount);` The hdc argument is a handle to the canvas on which you want to draw. Like the Polyline() method, the lppt argument is an array of POINT or TPoint values. The PolyPolyline() function needs to know how many polylines you want to draw. Each polyline will use the points of the lppt value but when creating the array of points, the values must be incremental. This means that PolyPolyline() will not access their values at random. It will retrieve the first point, followed by the second, followed by the third, etc. Therefore, your first responsibility is to decide where one polyline starts and where it ends. The good news (of course depending on how you see it) is that a polyline does not start where the previous line ended. Each polyline has its own beginning and its own ending point. The lpdwPolyPoints argument is an array or positive integers (unsigned long). Each member of this array specifies the number of vertices (lines) that its corresponding polyline will have. For example, imagine you want to draw M, followed by L, followed by Z. The letter M has 4 lines but you need 5 points to draw it. The letter L has 2 lines and you need 3 points to draw it. The letter Z has 3 lines so 4 points are necessary to draw it. You can store this combination of lines in an array defined as { 5, 3, 4 }. Unlike Polyline(), here, the cCount argument is actually the number of shapes you want to draw and not the number of points (remember that each polyline "knows" or controls its beginning and end). Here is an example:
 ```//--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { TPoint Pt[15]; DWORD lpPts[] = { 4, 4, 7 }; // Left Triangle Pt[0] = Pt[3] = Point(50, 20); Pt[1] = Point(20, 60); Pt[2] = Point(80, 60); // Second Triangle Pt[4] = Pt[7] = Point(70, 20); Pt[5] = Point(100, 60); Pt[6] = Point(130, 20); // Hexagon Pt[8] = Pt[14] = Point(145, 20); Pt[9] = Point(130, 40); Pt[10] = Point(145, 60); Pt[11] = Point(165, 60); Pt[12] = Point(180, 40); Pt[13] = Point(165, 20); HDC hDC = Canvas->Handle; PolyPolyline(hDC, Pt, lpPts, 3); } //---------------------------------------------------------------------------```