...which I should have posted. For the purposes of the example you will need a form with an array of Line controls on it (the routine for checking if we're clicking on a line actually takes a RECT structure defining the start and end points of the line, but for the example it was just easier to plonk the line controls down). The example also assumes that you are drawing on the form, but it should be fairly easy to see how to extend the core function to deal with any object that has an hDC. And that's it. Just paste the following code into the form:
[tt]
Option Explicit
' Essential declares to do the trick...
Private Declare Function BeginPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function GetPath Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTAPI, lpTypes As Byte, ByVal nSize As Long) As Long
Private Declare Function WidenPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function PathToRegion Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim lp As Long
Dim LineRect As RECT
' Check out each line in the relevant control array
For lp = Line1.lbound To Line1.ubound
' We're moving to a RECT because the linecheck routine is written to b more generic
' than just handling VB's line controls
SetRect LineRect, Line1(lp).X1, Line1(lp).Y1, Line1(lp).X2, Line1(lp).Y2
If IsLine(LineRect, x, y, 5) Then
Line1(lp).Visible = False
End If
Next
End Sub
' This is the essential function
Private Function IsLine(myLine As RECT, x As Single, y As Single, Optional PixelFuzz As Long = 5) As Boolean
Dim myPoint As POINTAPI
Dim OldWidth As Long
Dim OldScale As Long
Dim hRgn As Long
OldWidth = Form1.DrawWidth
OldScale = Form1.ScaleMode
Form1.DrawWidth = Form1.DrawWidth + PixelFuzz * 2 ' Allow width on either side
Form1.ScaleMode = vbPixels
' Ok create a path that matches the line
BeginPath Form1.hdc
MoveToEx Form1.hdc, myLine.Left, myLine.Top, myPoint
LineTo Form1.hdc, myLine.Right, myLine.Bottom
EndPath Form1.hdc
' Do the magic...
WidenPath Form1.hdc ' Add the Pixel Fuzz Factor, so we can click 'near' the line
hRgn = PathToRegion(Form1.hdc) ' Turn our widened path into a Windows region
IsLine = PtInRegion(hRgn, x, y) ' Are we clicking in the region that we have created?
'Clean up our GDI object and the form settings
DeleteObject hRgn
Form1.DrawWidth = OldWidth
Form1.ScaleMode = OldScale
End Function