You can use a hit test. Here a cut and paste I made from another post which
is related to this concept.
----------------------------------------------
Since this is a mathematical concept, there is no need to have a display
context (hDC) to use the methods (as long as you don't have to render
graphically the region).
The function to use is: PtInRegion( region, x, y)
which tells you if the point (x,y) is, or not, in the region.
What is left to you is to create a 'region'. You do it with CreatePolygonRgn
(there are other way to create regions, but this one is versatile). You send
it an array of points (vertex of the polygon), by giving the start of the
sequence and the number of points to be read. A third argument is used in
case you are grapically inclined to render the region (need an hDC too to do
that).
So, here all the code required to test if one point is, or not, inside a
triangle (in Access, again, since no real graphic rendering is performed):
========================
Option Compare Database
Option Explicit
Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal x
As Long, ByVal y As Long) As Long
Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As Any, ByVal
nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As
Long
Private Type POINT
x As Long
y As Long
End Type
Public Sub HitTestSample()
Dim points(1 To 3) As POINT
' define the vertex of a triangle
points(1).x = 0
points(1).y = 0
points(2).x = 100
points(2).y = 0
points(3).x = 0
points(3).y = 100
Dim regionOne As Long
' make a region of or vertexes
regionOne = CreatePolygonRgn(points(1), 3, 2)
' the filling mode has only interest if you use graphical
' display of the region.
If PtInRegion(regionOne, 60, 60) Then Debug.Print "(60,60) in the
triangle"
If PtInRegion(regionOne, 40, 40) Then Debug.Print "(40,40) in the
triangle"
' release memory associated to our variable of type LONG
' since VBA only sees it as a standard LONG variable
DeleteObject regionOne
End Sub
=========================
So, I assume you are likely to end with many regions that you will keep in
an array, or in a collection, and test the point "for each" region in your
collecton (array) of regions.
Final note: since VBA sees only a long, when you speak of a region, the
automatic stack cleaning may not release the memory WIN32 has associated and
made available through this "handle", so it is required to use DeleteObject.
----------------------------
NOTE: Since your regions are defined in a table, your corner number
sequence is important when you define the regions, Indeed, for a square, if
you enter the sequence like:
{ top, left}, {bot, left}, {top, right}, {bot, right}
you don't get a rectangle, but a butterfly as "region" .
As for when using DeleteObject, it is BEFORE loosing the VBA variable of
type long which 'handles' the region (before it goes out of scope, in
general). Be careful with the other case:
Dim x AS region
x= CreatePolygonRegion(.... )
x= CreatePolygonRegion(... )
It is wrong (memory leak) since you lose the first handle when you assign
the variable by something else (here, by assigning a second region to it).
Maybe better to define a CLASS with a TERMINATE event :
Dim x As ClassRegion
x.CreatePolygonRegion( ... )
x.CreatePolygonRegion( ... )
and the class is like:
=========================
Option Compare Database
Option Explicit
Private handle As Long ' your will be handle to a region
Private Sub Class_Terminate()
DeleteObject handle ' delete object automatically called for you
End Sub
Public Sub CreatePolygonRegion( ... )
handle = ...
End Sub
Public Function PointInRegion( ... ) As Boolean
...
End Function
==========================
so the Terminate event being called, AUTOMATICALLY for you, at each
opportune time, such class GREATLY improves the tolerance against memory
leak.
Even more, your class CreatePolygonRegion can accept a single number, and
make the whole job to read the data in the table, etc, which will then ALSO
greatly improve the user-friendly-ness for the developper using such system!
Vanderghast, Access MVP