[MVBA] Best way to retrieve Point3d Object from Tentative Snap like "Rotate View by 2 points"

Disclaimer: First Foray into using MVBA with the native Microstation Objects.  Well versed in VB.NET though.

I am trying to create a simple little MVBA application to return the 2D slope between 2 points.  This is what I have so far thanks to a previous post by Jan called MeasureLine.mvba.

Main entry point for the program

Option Explicit
' ---------------------------------------------------------------------
Private Const strMODULE_NAME                As String = "modMain"
'   AnnotateSlope is a MicroStation VBA project.  It enables a user to
'   identify (locate) a 2 points in a DGN file and get/annotate the slope,
'   and post the measurement in a UserForm.

' ---------------------------------------------------------------------
'   To start this macro, use the following MicroStation keyin:
'   vba run [AnnotateSlope]modMain.Main
' ---------------------------------------------------------------------
'   Main entry point
' ---------------------------------------------------------------------
Public Sub Main()
    On Error GoTo err_Main
    Debug.Print "VBA project location: " & Application.VBE.activevbproject.FileName
    frmLocator.Show vbModeless
    Exit Sub

err_Main:
    ReportError strMODULE_NAME, "Main"
End Sub
' ---------------------------------------------------------------------
'   ReportError
'   Generic way to report an error
' ---------------------------------------------------------------------
Public Sub ReportError(ByVal modName As String, ByVal procName As String)
    Const strColon As String = ":"
    MsgBox "Error " & CStr(err.Number) & strColon & " " & err.Description & vbNewLine & _
        "Caused by " & err.Source, vbOKOnly Or vbCritical, "Error in " & modName & strColon & procName
End Sub
' ---------------------------------------------------------------------

Temporary code for userform (Everything is commented out except the call CommandState.SetLocate)

Option Explicit
' ---------------------------------------------------------------------
Private Const strMODULE_NAME                As String = "frmLocator"
' ---------------------------------------------------------------------
Public Property Let ElementID(ByRef id As DLong)
    'txtID.Text = DLongToString(id)
End Property
' ---------------------------------------------------------------------
Public Property Let Length(ByVal l As Double)
    'txtLength.Text = Format(l, "#0.00")
End Property
' ---------------------------------------------------------------------
Private Sub commandButton_Click()
    '   Start a new locate command by invoking our class clsLocator
    Dim oLocator As New clsLocator
    Set oLocator.Originator = Me
    CommandState.SetLocate oLocator
End Sub
' ---------------------------------------------------------------------

Private Sub UserForm_Initialize()
    '   Initialise units
    Dim master As MeasurementUnit
    master = ActiveModelReference.MasterUnit
    'lblLength.Caption = "Length " & master.Label & ":"
    '   Initialise ID
    ElementID = DLongFromLong(0)
    '   Initialise length
    Length = 0#
End Sub

 

Class Module implementing ILocateCommandEvents

Option Explicit
' ---------------------------------------------------------------------
Private Const strMODULE_NAME                As String = "clsLocator"
' ---------------------------------------------------------------------
Implements ILocateCommandEvents
' ---------------------------------------------------------------------
'   Member variable stores a reference to the UserForm that called this
'   locate class
' ---------------------------------------------------------------------
Private m_oOriginator                       As frmLocator
' ---------------------------------------------------------------------
'   Property lets us assign our form to this variable
'   e.g. Set oLocator.Originator = Me
' ---------------------------------------------------------------------
Public Property Set Originator(ByRef oForm As frmLocator)
    Set m_oOriginator = oForm
End Property
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_Accept(ByVal oElement As Element, point As Point3d, ByVal View As View)
    '   Use originator variable to use properties of frmLocator
    m_oOriginator.ElementID = oElement.id
    m_oOriginator.Length = oElement.AsLineElement.Length
End Sub
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_Cleanup()

End Sub
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_Dynamics(point As Point3d, ByVal View As View, ByVal drawMode As MsdDrawingMode)
    '   Intentionally empty
End Sub
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_LocateFailed()
    ShowStatus "Not a line element"
End Sub
' ---------------------------------------------------------------------
'   Reject elements that are not LineElements because we can't measure them
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_LocateFilter(ByVal oElement As Element, point As Point3d, accepted As Boolean)
    '   Intentionally empty
End Sub
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_LocateReset()
    '   Intentionally empty
End Sub
' ---------------------------------------------------------------------
Private Sub ILocateCommandEvents_Start()
    Dim ele As Element
    Dim eleComponent As Element
    Dim hitPoint As Point3d
    
    ShowCommand "Select 1st Data Point"
    ShowPrompt "Snap on your 1st point"
    hitPoint = CommandState.GetHitPoint
    Debug.Print "    Point on Element " & Point3dToString(hitPoint)
End Sub
' ---------------------------------------------------------------------
Function Point3dToString(pnt As Point3d) As String
    Point3dToString = "(" & pnt.X & ", " & pnt.Y & ", " & pnt.Z & ")"
End Function

 

I am having difficulty finding a CommandState Object Method for prompting the user to send a snapped Point3d rather than an element of some sort.  Do I need to be using IPrimitiveCommandEvents instead? It looks like the IPrimitiveCommandEvents_DataPoint Method does what I want, but I am having trouble calling it from a dialog box button.

Thanks!
Matt

P.S. How do you do code blocks <code></code> on these forums?

 

Parents
  • Unknown said:
    It looks like the IPrimitiveCommandEvents_DataPoint Method does what I want, but I am having trouble calling it from a dialog box button

    A locator class does what you expect — it locates things.  If the points you want are always part of an element (e.g. a line end point) then ILocateCommandEvents is what you need.

    If you want to gather a point placed anywhere, then you don't want to be locating something, and a class that Implements IPrimitiveCommandEvents should do you.  You can start that command class from a UserForm command button much the same as your locator class...

    Sub MyButton_click ()
      Dim   oPointPicker As New clsPointPicker ' this is your class that Implements IPrimitiveCommandEvents
      CommandState.StartPrimitive oPointPicker
    End Sub

    Unknown said:
    CommandState.SetLocate oLocator

    That should be...

    CommandState.StartLocate oLocator

     
    Regards, Jon Summers
    LA Solutions

Reply
  • Unknown said:
    It looks like the IPrimitiveCommandEvents_DataPoint Method does what I want, but I am having trouble calling it from a dialog box button

    A locator class does what you expect — it locates things.  If the points you want are always part of an element (e.g. a line end point) then ILocateCommandEvents is what you need.

    If you want to gather a point placed anywhere, then you don't want to be locating something, and a class that Implements IPrimitiveCommandEvents should do you.  You can start that command class from a UserForm command button much the same as your locator class...

    Sub MyButton_click ()
      Dim   oPointPicker As New clsPointPicker ' this is your class that Implements IPrimitiveCommandEvents
      CommandState.StartPrimitive oPointPicker
    End Sub

    Unknown said:
    CommandState.SetLocate oLocator

    That should be...

    CommandState.StartLocate oLocator

     
    Regards, Jon Summers
    LA Solutions

Children
No Data