Search code examples
vbamicrostation

How to ask user to snap on a vertex of a line element (in the ILocateCommandEvents_Accept handler) of Microstation VBA


I know how to write a VBA macro in Microstation that will ask the user to select an element:

Sub Create2DCrossLines()
    ' Set error handler
    On Error GoTo ErrorHandler

    ' Let the user select the bank elements himself
    Call CommandState.StartLocate(New clsSelectBanksLCE)

    Exit Sub

ErrorHandler:
    Call ReportError("Create2dCrossLines")
End Sub

clsSelectBanksLCE uses ILocateCommandEvents for managing that part of the logic. So the user can select a LineElement for example and when the Accept event is fired it runs an action:

Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, _
                                        Point As Point3d, _
                                        ByVal View As View)

In my particular case we track selecting element 1 and then element 2 and once both elements are selected it proceeds. This is all fine.

My problem is this: after I accept the first element, and before proceeding to select the next (ie: in the Accept handler) I want to get the user to snap on to two vertices of the line element.

I need to know which part of the line element they want to process. I can't work out how to do this. In AutoCAD you can use GetPoint.

So I want to ask them to snap on to the first vertex on this line element, then snap onto the end vertex. After this can we move on to select the second element.

Update

I have just stumbled over this article. I notice it says:

Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.

It seems what I want but I just am not clear on the right order. At the moment I have:

ILocateCommandEvents_Start This begins the location process.

ILocateCommandEvents_LocateFilter. If the element is a LineElement, then it assigns m_Element1 and the second event fired assigns m_Element2.

ILocateCommandEvents_Accept If both the variables are not nothing it runs the main process.

See my dilemma? It sounds like I need to:

  • Run one instance of ILocateCommandEvents to select one element only.
  • Then run one instance of IPrimitiveCommandEvents to get the first snap point.
  • Then run another instance of IPrimitiveCommandEvents to get the second snap point.
  • Then run another instance of ILocateCommandEvents to get the second element.
  • Finally, once the second element is accepted, perform my processing.

That is how I understand I need to do it. Or, can I use my one ILocateCommandEvents class that currently gets the user to choose two elements?

Guidance appreciated.

Update

I got it to work by following the above logic. That article really helped. The only issue I have now is that I need to draw a rubber band. But that is a separate question.


Solution

  • As mentioned in this article:

    Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.

    The link also provides example code on how to use the IPrimitiveCommandEvents event class.