ILocateCommandEvents_LocateFilter is not working for second datapoint

Hi folks,

I am missing something here. I want to prompt the user to click on a line in 2 different places and collect both datapoints.

If I click on text for the first datapoint it correctly says its not a line, however for the second datapoint I can click on anything and it accepts it... help! 

 

sub main()

CommandState.StartLocate New clsLocatePts

end sub

 

 

' ---------------------------class code ---------------------------------------

Option Explicit
Implements ILocateCommandEvents

Dim Mypoint(1) As Point3d ' holds the data point user provides
Dim numPointsPlaced As Long ' number of datapoints placed

Private Sub ILocateCommandEvents_Start()
    Application.ShowCommand ""
    Application.ShowPrompt "Select first point on line, RESET to exit"
    numPointsPlaced = 0
End Sub

Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, Point As Point3d, ByVal view As view)
On Error GoTo err
    If numPointsPlaced = 0 Then
        CommandState.StartDynamics
        Mypoint(0) = Point ' capture first point
        MsgBox "Point 1 captured"
        Application.ShowPrompt "Select Second Point on line, RESET to restart"
    Else
 CommandState.SetLocateCursor
        MsgBox "Point 2 captured"
        Mypoint(1) = Point ' capture second point

        ' have 2 points time for H/W calc
       MsgBox "time to calc"

        CommandState.StartDefaultCommand
        numPointsPlaced = 0
        Exit Sub
    End If

    numPointsPlaced = numPointsPlaced + 1
    Exit Sub
err:
    MsgBox "Datapoint module error " & err.Number & vbCrLf & err.Description
End Sub

Private Sub ILocateCommandEvents_LocateFilter(ByVal Element As Element, Point As Point3d, Accepted As Boolean)

' add in line string later

    If Element.Type = msdElementTypeLine Then
        Accepted = True
    Else
        Accepted = False
    End If

End Sub

Private Sub ILocateCommandEvents_LocateFailed()
'    ShowStatus "Not a line element"
MsgBox "Not a line element"
End Sub

Private Sub ILocateCommandEvents_Dynamics(Point As Point3d, ByVal view As view, ByVal DrawMode As MsdDrawingMode)

End Sub

Private Sub ILocateCommandEvents_LocateReset()
    '????
End Sub

Private Sub ILocateCommandEvents_Cleanup()

End Sub

  • Hi,

    I see more possible problems in your code, but the answer to your question is probably that you test element type for msdElementTypeLine but not for msdElementTypeLineString, which is more often used element type.

    The test in LocateFilter can looks like:

      If ((Element.Type = msdElementTypeLine) Or (Element.Type = msdElementTypeLineString)) Then ...

    What I see as another problem is after a user choose an element, it has to accept it using another data point, which looks useless extra step (but of ocourse it can be an intention ;-).

    Regards,

      Jan

  • Thanks Jan,

    Not sure how to properly handle the extra data point.. can you point me to an example of using ILocateCommandEvents

    and selecting 2 data pojnts?

  • Hi,

    I think the problem is not in the code, which only follows tool design. At first, you have to define exactly what your tool workflow will be, in other words what will happen when a user click data or reset mouse button. Simplified version of what you described can be:

    1. Start the tool.
    2. Data point at element: First point is identified.
      Reset: No action.
    3. Data point at element: Second point is identified.
      Reset: Reject the first point (the tool returns to beginning).
    4. Data point anywhere: Acceptance of second point, the tool can finish what should be done.
      Reset: Reject the second point.

    Such kind of workflow (usually is more complex for real tools) gives you clear picture what event (Locate, Accept etc.) to use to track what user action. In your case I think the solution can be:

    • One "state variable" ... you have it already, it's number of placed points.
    • If Locate test is passed (element type = line or line string), increase number of placed points.
    • Test when reset button is clicked and if a point(s) is identified already, decreast number of placed points.
    • If Accept method is called and two points are entered, the tool can do its job.

    It means you will have to move the most of your code from Accept method to Locate method. What is helpful is to set break points to all ILocateCommandEvents methods and to track what is called when.

    With regards,

      Jan

    Answer Verified By: rpsmith 

  • Unknown said:
    What is helpful is to set break points to all ILocateCommandEvents methods and to track what is called when

    And use Debug.Print.

    Sub ILocateCommandEvents_Accept (...)
      Debug.Print "Accept event"
    End Sub

    Sub ILocateCommandEvents_LocateFilter (...)
      Debug.Print "LocateFilter event"
    End Sub

     
    Regards, Jon Summers
    LA Solutions

  • Hi,

    In your case, you can use IPrimitiveCommandEvents.

    Set cursor to Locate in the start event of IPrimitiveCommandEvents.

    Private Sub IPrimitiveCommandEvents_Start()

    CommandState.SetLocateCursor

    End Sub

    In the Data Point event, locate the element by using the data point and validate it.

    If it is a valid element, store the data point.

    Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d, ByVal View As View)

    Dim elm As Element

    Set elm = CommandState.LocateElement(Point, View, True)

    If elm Is Nothing Then

    MsgBox "Pick on Line", vbInformation

    Exit Sub

    End If

    If elm.IsLineElement = False Then

       MsgBox "Invalid Element", vbInformation

    Else

       If ptcount = 1 Then

           dataPoint1 = Point

           ptcount = 2

       Else

           dataPoint2 = Point

           '...........

           '...........

       End If

    End If

    End Sub

    HTH,

    Siva

    Answer Verified By: rpsmith