Search Tools Links Login

Tutorial - Graphics - Shapes - by Simon Price


Visual Basic 6, or VB Classic

This tutorial is third in a series about Win32 API for graphics. In this tutorial, you will learn about functions that help draw various geometric shapes and how to use them in code, with a working example to download.

Original Author: Simon Price

Code






New Page 1





About this tutorial:


This tutorial by Simon Price is part of a series held at http://www.VBgames.co.uk.
It requires a good knowledge of Visual Basic programming. This tutorial come
with an example program with VB6 source code, which can be downloaded from http://www.VBgames.co.uk/tutorials/gdi/pensbrushes.zip
and possibly from other websites hosting this tutorial (such as PSC).


Before you begin:


Have you read the previous tutorial - Device Contexts? If not, please
read that first, because this tutorial builds upon the knowledge and code of the
previous tutorial.


Pixels


A bitmap has dimensions of width and height measured in pixels. A pixel is
the smallest part of a bitmap which can be changed. It's a little dot. Drawing
anything, whether it's a line, a circle, or a 3D model in the latest 3D shoot-em-up,
at the end of the way, it comes down to drawing pixels. So a pixel is the first
"shape" to learn to draw, since everything else relies upon it.


32 Bit Color


All colors in the Windows API graphics functions are given in a 32 bit (4
byte) integer - the Long data type in VB. 1 byte is red, 1 byte green, 1 byte
blue, 1 byte is reserved and currently does nothing ( you can use
the last byte for yourself - maybe store alpha values!?
). VB comes
with the RGB function for creating these 32 bit colors.


API functions for pixels


Here are the API functions used for pixels:




Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long


GetPixel - returns the color of a pixel in a device context, given
it's x and y coordinates




Private Declare Function SetPixelV Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long


SetPixelV - Sets the color of a pixel in a device context




Reading and Writing Pixel Colors


Pixels are read and written with the GetPixel and SetPixelV
functions. Here is the code to read and write pixel colors, it is pretty much
self-explanitory:


' gets an individual pixel color in long format

Public Property Get Pixel(x As Long, y As Long) As Long

On Error Resume Next

?á?á?á Pixel = GetPixel(Me.hDC, x, y)

End Property




' sets an individual pixel color in long format

Public Property Let Pixel(x As Long, y As Long, Color As Long)

On Error Resume Next

?á?á?á SetPixelV Me.hDC, x, y, Color

End Property


Shapes


It would be possible for us to draw other shapes using the pixel drawing
functions we just learnt. If you want, feel free to go do just that! However,
Windows comes with functions to draw several common shapes, which are easy to
use, and faster than what you could make in your own software VB-coded
implementations of the same functions. I suggest you learn the Windows API
rather than doing it yourself. No need to re-invert the wheel yet.


API functions for shapes


Here are the API functions used for shapes:




Private Declare Function MoveToEx Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long


MoveToEx - set the current cursor of the device context




Private Declare Function LineTo Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long


LineTo - draws a line from the current cursor position to the
specified point




Private Declare Function Rectangle Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long


Rectangle - draws a rectangle given two opposing points




Private Declare Function Ellipse Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long


Ellipse - draws an ellipse, given the opposing points of an imaginary
rectangle what would fit around the ellipse




Private Declare Function Polygon Lib "gdi32" (ByVal hDC As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long


Polygon - draws a polygon of any number of sides, given a pointer to
and array of 2D points, and the number or points




Private Declare Function Arc Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As Long


Arc - Draws and arc




Private Declare Function ArcTo Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As Long


ArcTo - draws an arc




Private Declare Function Pie Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As Long


Pie - draws sector of a circle




Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long


ExtFloodFill - floods an area with a color




Private Declare Function FloodFill Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long


FloodFill - floods an area with color until a border color is found




Private Declare Function FillRect Lib "user32" (ByVal hDC As Long, lpRect As RECT, ByVal hBrush As Long) As Long


FillRect - fills a rectangle with a pattern from a brush




Private Declare Function PatBlt Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal dwRop As Long) As Long


PatBlt - fills a rectangle with a pattern




Private Declare Function GetPolyFillMode Lib "gdi32" (ByVal hDC As Long) As Long


GetPolyFillMode - returns the current polygon filling mode




Private Declare Function SetPolyFillMode Lib "gdi32" (ByVal hDC As Long, ByVal nPolyFillMode As Long) As Long


SetPolyFillMode - sets the current polygon filling mode




Private Declare Function GetTextColor Lib "gdi32" (ByVal hDC As Long) As Long


GetTextColor - returns the current text color




Private Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long


SetTextColor - sets the current text color




Private Declare Function GetTextAlign Lib "gdi32" (ByVal hDC As Long) As Long


GetTextAlign - returns the current text alignment mode




Private Declare Function SetTextAlign Lib "gdi32" (ByVal hDC As Long, ByVal wFlags As Long) As Long


SetTextAlign - sets the current text alignment mode




Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long


TextOut - draws a specified string of text on a device context using
the current text color and alignment




Lines


Lines are drawn with the MoveToEx and LineTo functions. A
device context has a current drawing position - a 2D coordinate, like a cursor.
To draw a line, we must put the "cursor" to one end of the line, then
draw a line between the cursor and the other end of the line. That was a lame
explanation, just look at the code and it's easily understood:


' draws a line

Public Sub DrawLine(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long)

Dim Point As POINTAPI

On Error Resume Next

?á?á?á MoveToEx hDC, X1, Y1, Point

?á?á?á LineTo hDC, X2, Y2

End Sub


Rectangles (and squares)


A rectangle is drawn with the Rectangle function. A rectangle is
specified by the coordinates of 2 opposing corners. There is no need to specify
the other 2 corners since they can be worked out from the given points. Here is
the code to draw a rectangle:


' draws a rectangle

Public Sub DrawRectangle(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long)

On Error Resume Next

?á?á?á Rectangle hDC, X1, Y1, X2, Y2

End Sub


Note that squares are drawn in the same way, because a square is just a
special type of rectangle where X2 - X1 = Y2 - Y1.


Ellipses (and circles)


An ellipse is drawn with the Ellipse function. An ellipse is specified
by an imaginary rectangle what would fit around the ellipse. Here is the code to
draw an ellipse:


' draws an ellipse

Public Sub DrawEllipse(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long)

On Error Resume Next

?á?á?á Ellipse hDC, X1, Y1, X2, Y2

End Sub


Note that circles are drawn in the same way, because a circle is just a
special type of ellipse where X2 - X1 = Y2 - Y1.


Drawing Polygons


Polygons are drawn with the Polygon function. Polygons are made from
many points joined up. Examples of polygons include triangles, quadrilaterals,
pentagons, hexagons, heptagons, octagons, nonagons, decagons, dodecagons etc.


Here is the function to draw any polygon:


' draws a polygon

Public Sub DrawPolygon(x() As Long, y() As Long)

Dim Point() As POINTAPI

Dim i As Long

On Error Resume Next

?á?á?á ReDim Point(LBound(x) To UBound(x))

?á?á?á For i = LBound(x) To UBound(x)

?á?á?á?á?á?á?á Point(i).x = x(i)

?á?á?á?á?á?á?á Point(i).y = y(i)

?á?á?á Next

?á?á?á Polygon hDC, Point(LBound(Point)), UBound(Point) - LBound(Point) + 1

End Sub


The most commonly drawn polygon is a triangle, so here is an optimised
version of the function, just for triangles:


' draws a triangle

Public Sub DrawTriangle(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long, X3 As Long, Y3 As Long)

Dim Point(1 To 3) As POINTAPI

On Error Resume Next

?á?á?á Point(1).x = X1

?á?á?á Point(1).y = Y1

?á?á?á Point(2).x = X2

?á?á?á Point(2).y = Y2

?á?á?á Point(3).x = X3

?á?á?á Point(3).y = Y3

?á?á?á Polygon hDC, Point(1), 3

End Sub


Drawing Patterns


A rectangular region can be filled with a common hatched pattern with the PatBlt
function. Here is the code to do that:


' fills a rectangle with a pattern

Public Sub DrawPattern(Optional x As Long = 0, Optional y As Long = 0, Optional lWidth As Long = 0, Optional lHeight As Long = 0, Optional RasterOp As PATBLT_RASTEROP = PR_PATCOPY)

On Error Resume Next

?á?á?á If lWidth = 0 Then lWidth = Width

?á?á?á If lHeight = 0 Then lHeight = Height

?á?á?á PatBlt hDC, x, y, lWidth, lHeight, RasterOp

End Sub


Drawing Text


A string of text can be draw with the TextOut function. Here is the
code to draw text at a specified position on the device context:


' draws a text string

Public Sub DrawText(str As String, Optional x As Long = 0, Optional y As Long = 0)

On Error Resume Next

?á?á?á TextOut hDC, x, y, str, Len(str)

End Sub


Example Program



The example program demonstrates most of what has been learnt in this
tutorial. Download and run the code, you should see several shapes and a text
string naming the coolest site for VB games programming on earth! Have a go at
drawing some more, learn them well, these basic shapes are the basis for all
other shapes.


Coming soon...


Watch out for the next tutorial in this series! Next we will learn how to
load from and save to bitmap files for persistent graphics!

About this post

Posted: 2002-06-01
By: ArchiveBot
Viewed: 116 times

Categories

Visual Basic 6

Attachments

Tutorial_-4187512132001.zip
Posted: 9/3/2020 3:45:00 PM
Size: 8,387 bytes


Loading Comments ...

Comments

No comments have been added for this post.

You must be logged in to make a comment.