Content Supported by Sourcelens Consulting
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Polygon"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
' >> Best viewed in Full Module view. <<
'
' Storage for debug ID number.
Private mlngDebugID As Long
Implements IDebug
' Polygon is a VERY rudimentary class of
' ------- polygon objects. It only
' allows polygons to be created (with
' the SetPoints method); there's no way
' to modify the points once they're set.
' (Of course, you can call SetPoints
' again, to reset the entire polygon.)
Private Type POLYPOINT ' prefix pyp
X As Single
Y As Single
Angle As Single
End Type
' Polygon defaults to one point, at (0,0).
Private mapyp() As POLYPOINT
' Storage for read-only Normalized property.
Private mblnNormalized As Boolean
' Storage for Color property.
Private mrgbColor As Long
' IShape is the interface that's used to
' ------ display the polygon. It also
' has a TimeTest method that's used to
' compare early and late binding call
' overhead.
Implements IShape
' -------------------------------------
' This marks the beginning of the
' implementation of the IShape
' interface.
' IShape.DrawToPictureBox is called to
' ====== ---------------- draw a shape,
' so each class of shape must supply
' its own implementation.
'
Private Sub IShape_DrawToPictureBox(ByVal pb As PictureBox)
Dim sngXLast As Single
Dim sngYLast As Single
Dim sngX As Single
Dim sngY As Single
Dim intMax As Integer
Dim intCt As Integer
intMax = UBound(mapyp)
sngX = mapyp(intMax).X
sngY = mapyp(intMax).Y
If intMax = 0 Then
pb.PSet (sngX, sngY), mrgbColor
Else
For intCt = 0 To intMax
sngXLast = sngX
sngYLast = sngY
sngX = mapyp(intCt).X
sngY = mapyp(intCt).Y
pb.Line (sngXLast, sngYLast)-(sngX, sngY), mrgbColor
Next
End If
End Sub
' IShape.TimeTest method is used to show
' ====== -------- the reduced call
' overhead of a method called on an
' interface that several classes
' implement -- as opposed to calling
' a similar method on the classes'
' default interfaces.
'
Private Sub IShape_TimeTest()
End Sub
' --------------------------------------
' This is the beginning of the Polygon
' class's default interface (Public
' properties and methods). This is
' the Polygon interface that Triangle
' and Rectangle implement.
' Color property.
' -----
'
Public Property Get Color() As Long
Color = mrgbColor
End Property
'
Public Property Let Color(ByVal rgb As Long)
If 0 <> (rgb And &HFF000000) Then
Err.Raise vbObjectError + 2080, , _
"Invalid color value for Polygon."
Exit Property
End If
mrgbColor = rgb
End Property
' TimeTest method takes no arguments,
' -------- does nothing, and
' immediately returns. It's used to
' illustrate the call overhead for
' late binding, as opposed to the
' early binding provided by calling
' TimeTest on the IShape interface.
'
' You might think we would make TimeTest
' a Friend property, like DebugID, to
' save Triangle and Rectangle -- which
' implement Polygon's interface -- from
' having to implement Polygon_TimeTest.
' (Friend properties and methods are
' NOT part of a class's interface.)
' The reason we can't do this is that
' TimeTest must be called LATE bound
' for the demo -- but Friend properties
' and methods must always be called
' EARLY bound.
Public Sub TimeTest()
End Sub
' GetPoint sets two ByRef Singles to
' -------- the X and Y values for
' the requested point. (If Polygon's
' interface wasn't being implemented
' by Triangle and Rectangle, GetPoint
' could be declared Friend, and could
' return a POLYPOINT -- which would
' have to be declared Public in a
' standard module in that case;
' however, Friend members are not part
' of a class's interface, so making
' GetPoint a Friend would prevent
' Triangle and Rectangle from
' implementing an early-bound
' Polygon_GetPoint.)
'
Public Sub GetPoint(ByVal intPoint As Integer, _
ByRef X As Single, ByRef Y As Single)
X = mapyp(intPoint).X
Y = mapyp(intPoint).Y
End Sub
' GetPointCount returns the number of
' ------------- points in the Polygon.
'
Public Property Get GetPointCount() As Integer
GetPointCount = UBound(mapyp) + 1
End Property
' SetPoints accepts a zero-based array
' --------- of Singles, the even-numbered
' elements (0, 2, etc.) being the X
' values, and the odd-numbered elements
' being the Y values of the points.
'
Public Sub SetPoints(asngPoints() As Single)
Dim blnBadArray As Boolean
Dim intMax As Integer
Dim intPoint As Integer
On Error Resume Next
If LBound(asngPoints) <> 0 Then blnBadArray = True
intMax = UBound(asngPoints)
' The upper bound of a zero-based
' array must be an odd number --
' validate this.
If (intMax / 2#) = (intMax \ 2) Then blnBadArray = True
' If an error occurs in the UBound
' function, declare array invalid.
If Err.Number <> 0 Then blnBadArray = True
If blnBadArray Then
Err.Raise vbObjectError + 2081, , _
"SetPoints must receive a zero-based, one-dimensional array with an even number of elements, the odd entries being X values and the even entries Y values."
Exit Sub
End If
' Convert the maximum index of the input
' array to the maximum index of the
' internal array of the Polygon.
intMax = intMax \ 2
ReDim mapyp(0 To intMax)
' Read in the point values.
For intPoint = 0 To intMax
mapyp(intPoint).X = asngPoints(intPoint * 2)
mapyp(intPoint).Y = asngPoints(intPoint * 2 + 1)
Next
End Sub
' --------------------------------------
' This is the beginning of the Polygon's
' private procedures (helper procedures
' and event procedures).
Private Sub Class_Initialize()
' Debug code.
mlngDebugID = DebugInit(Me)
'
' Polygon defaults to a point.
ReDim mapyp(0 To 0)
End Sub
Private Sub Class_Terminate()
DebugTerm Me
End Sub
' -------- IDebug Implementation --------
'
' IDebug.DebugID gives you a way to tell
' ====== ------- objects apart. It's
' required by the DebugInit, DebugTerm,
' and DebugShow debugging procedures
' declared in modFriend.
'
Private Property Get IDebug_DebugID() As Long
IDebug_DebugID = mlngDebugID
End Property