Place Text through VBA

Hi all,

Trying to work out how to place a predefined text string onto the drawing, without bring up any menus or options.

Have tried

    CadInputQueue.SendKeyin "place text"
CadInputQueue.SendKeyin sText

But the keyin window appears and i cant work out how to close it.

Also have tried
    CadInputQueue.SendKeyin "place dialogtext icon"
CadInputQueue.SendMessageToApplication "WORDPROC", sText

Which brings up the word processor but doesn't input the text.

Ideally i'd like to simple click a button on a form and the text appears on the drawing at the cursor ready for the user to select the location.

Cheers,

Rob

  • dim text as string                  ' text string

    dim rotmatrix as matrix3d     ' text rotation

    dim p1 as point3d                  ' textt origin

    RotMatrix = Matrix3dFromAxisAndRotationAngle(2, 0)

    Set Text = CreateTextElement1(Nothing, "text to be written, P1, RotMatrix)

    ActiveModelReference.AddElement Testo

    Thanks, blumax, this helped me out a lot, but I'd like to submit a correction and expansion to this like so:

    dim text as TextElement
    dim RotMatrix as Matrix3d
    dim p1 as Point3d
    
    ' insert your own code to specify location of p1 based on your needs
    RotMatrix = Matrix3dFromAxisAndRotationAngle(2, 0)
    
    Set text = CreateTextElement1(Nothing, "your text, or a variable string", p1, RotMatrix)
    ' now you can set graphic group or any other properties you like, for example:
    text.graphicGroup = 15
    
    ActiveModelReference.AddElement text

  • Perfect Stefan!

    Only 1 small problem though, when the reset button is clicked nothing happens.

    Is it ok to simply add in "    CommandState.StartDefaultCommand"

    or when working with classes is it best to do it another way?

  • Got you wrong Rob.

    I thought you wanted to place a line and a text.

    Please find a example attached.

    Answer Verified By: Rob Golding 

    CreateText.mvba

  • Hi Rob,

    few notes (not sitting at my computer, so sorry, no code):

    • Because only the first data point is important for you, you don't have to count points and you can start dynamics immediately when tool is started.
    • The first data point is the place where the text should be added to a model and as Stefan recommends, the tools should be restarted there.
    • I prefer (but it's just personal style) in such case to create text immediately when the tool is started (because you know the text already) at 0,0 coordinates and make it available for the rest of the code. Both in dynamic and datapoint you can use Transform3dFromPoint3d to create Transform3d and use it to shift the text to the dynamic or data point using textElm.Transform method.

    Regards,

      Jan

  • Some small corrections:

    Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)

       If m_nPoints = 1 Then

           m_atPoints(1) = Point

           Dim otext As TextElement

           Set otext = CreateTextElement1(Nothing, m_strText, Point, Matrix3dIdentity)

           otext.Redraw msdDrawingModeTemporary

       End If

    End Sub

    Private Sub IPrimitiveCommandEvents_Reset()

       'Better to do a clear reinitialization

       CommandState.StartPrimitive New MyClass()

       m_nPoints = 0

    End Sub

  • Hi Jan,

    The Steps listed above are correct apart from number 1.

    1. Text is assigned from somewhere else in the VBA. Will be passed a string
    2. Until datapoint is pressed, text is dynamically displayed at cursor. (this is so the user can see that the program is wanting the user to place text, plus being able to fit it in the design without accidently overlapping other elements)
    3. If reset button is pressed, text is erased.
    4. If datapoint is pressed, text is added into model and the tool is restarted.
    Probably should have started a new thread, but since its still explaining how to place text in VBA i thought i would leave it. Plus i really didn't think it would be this involved!
    Essentially all i want to do was do exactly what the Word Processor / text dialog box does, but instead of having the word processor display and input text, i assign the text through VBA or keyin.
  • Unknown said:
    If i add another "ActiveModelReference.AddElement otext" into the Dynamics section

    You never can do that. _Dynamics method is called when a cursor is moved, which means it can happen tens times every second. _DataPoint is the best place to add element into a model.

    Unknown said:
    Is there anything from below that could be changed to get the result the client wants?

    This thread has become pretty long and it's hard to find out what your client wants. Can you describe step by step how the tool should work ? Something like (just an example):

    1. Tool is started, the user is asked to enter text into a dialog.
    2. Until datapoint is pressed, text is dynamically displayed at cursor.
    3. If reset button is pressed, text is erased.
    4. If datapoint is pressed, text is added into model and the tool is restarted.

    What I miss in the information available is a definition how mouse buttons should work.

    With regards,

      Jan

  • Thanks Jan. I have had a look at the example and it was helpful but still couldn't give the result the client wants.

    Below is the code that i have pieced together from the example and also from what the guys helped me with above. The exact code below, essentially work the same as before

    If i add another "ActiveModelReference.AddElement otext" into the Dynamics section, then its achieves sort of what i'm after, where the text is placed at the cursor, however everytime the mouse is moved it will place the text... ending up with hundreds of text elements on the design.

    Is there anything from below that could be changed to get the result the client wants?

    I have seen a few programs (i think it was part of an MDL) that could do exactly as im after so i assume this is possible?


    Implements IPrimitiveCommandEvents

    Private m_strText As String
    Private m_atPoints(0 To 1) As Point3d
    Private m_nPoints As Integer

    Public Property Let Text(s As String)
    m_strText = s
    End Property

    Sub IPrimitiveCommandEvents_Datapoint(Point As Point3d, ByVal oView As View)

    If m_nPoints = 0 Then
    CommandState.StartDynamics
    m_atPoints(0) = Point
    m_nPoints = 1
    ShowPrompt "Place end point"
    ElseIf m_nPoints = 1 Then
    m_atPoints(1) = Point
    Dim otext As TextElement
    Set otext = CreateTextElement1(Nothing, m_strText, Point, Matrix3dIdentity)
    ActiveModelReference.AddElement otext
    otext.Redraw msdDrawingModeNormal
    m_atPoints(0) = m_atPoints(1)
    End If

    End Sub


    Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)

    If m_nPoints = 1 Then
    m_atPoints(1) = Point
    Dim otext As TextElement
    Set otext = CreateTextElement1(Nothing, m_strText, Point, Matrix3dIdentity)
    otext.Redraw msdDrawingModeNormal
    End If
    End Sub

    Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String)
    End Sub

    Private Sub IPrimitiveCommandEvents_Reset()
    CommandState.StartPrimitive Me
    m_nPoints = 0
    End Sub

    Private Sub IPrimitiveCommandEvents_Start()
    ShowPrompt "Select insertion point for text"
    End Sub
  • Hi Rob,

    you can display dynamic elements when Primitive Command is active. The right place to do it is Dynamics methods in IPrimitiveCommandEvents, because this method is called everytime the cursor is moved.

    You can check for example Line Element Creation Command example in MicroStation VBA help to see how to do it.

    If there is no dynamic, Transient Elements can be used to display elements that don't exist in design file.

    With regards,

     Jan

  • Just a bit further to this... the client has asked if its possible to show a preview of the text on the screen (i personally think its not needed but hey they pay the bills so least i can do is ask)

    In the above, I know that VBA doesn't actually create the text element until the datapoint is clicked, so i'm not sure if this is possible.

    They basically want to be able to see where the text is going to be placed, so much like the text already predefined at the cursor just waiting for a insertion point.

    Any ideas?

    Thanks again!