Handling data entry that is more than 256 characters long with DCL

Discussion in 'AutoCAD' started by Bob, Feb 24, 2005.

  1. Bob

    Bob Guest

    I'm trying to write a utility that will allow a user to enter a string of
    text into an edit field in a Lisp driven dialog box. Basically I need a
    memo field of up to 500 characters. However, I'm running into the DCL field
    length limit. Does anybody have a trick or know of another way to handle
    this?
     
    Bob, Feb 24, 2005
    #1
  2. Bob - although Help states that the maximum edit limit allowed is 256 - you can set higher - up to 2048 it seems (in R15 at least):

    edit_limit = 2048;

    If you have express tools - i.e.-access to acetutil.arx, then see acet-ui-txted for a multi-line text editing dialog.

    Another alternative is to create your own activex dll and invoke it from lisp - I use something like this with a RichTextBox component.

    Peter
     
    petersciganek, Feb 24, 2005
    #2
  3. Bob

    Bob Guest

    Peter - thank you for your help.

    Where can I get the express tools?

    Create my own activex dll is not something I've done before. How can I do
    this? Can you point me in the right direction?

    Thanks again!
     
    Bob, Feb 24, 2005
    #3
  4. Bob,

    I'm not really sure where or even if Express Tools are still available - maybe search the autodesk website for purchase options. Also, run a search on your hard drive for "acetutil.arx" - maybe you have it installed but are not loading the functions (worth a shot, anyway). The acetutil.arx has a number of useful functions that you can call from lisp. Quite possibly, some of these have been integrated into post R15 AutoCAD - I'm currently running 2002 so I can't tell you whether or not this is the case. You could also look into ObjectDCL - though I have no experience with that application.

    As for creating a dialog with activeX -I'll do my best to explain my working method.

    I use Visual Basic (6) (not VBA - Visual Basic for Applications that ships with Acad) -

    Start a new activeX.dll project

    Add a class (in my example "ui_functions" then add some code to the class:

    e.g.

    Public Function get_text(vdata As Variant) As Variant
    Dim frm As frmTextEdit

    varData = vdata

    Set frm = New frmTextEdit

    frm.Show vbModal

    get_text = varReturn

    Unload frm

    Set frm = Nothing

    End Function

    Next, add a module and declare varData and varReturn as public variants:

    Public varSet, varData, varReturn As Variant

    These hold the values passed back and forth between the class and the form (there probably is a more elegant way to do this...)



    Next - add your form (here frmTextEdit) RichTextBox that will place varData as e.g. the default text - add the code necessary to display the dialog as you desire, set varReturn on accept. Here is part of my code (it has some additional options but you should get the point):

    Private Sub cmdCancel_Click()
    Me.Hide
    Unload Me
    End Sub

    Private Sub cmdOK_Click()
    varReturn = RichTextBox1.Text & vbVerticalTab & CStr(chkLayer.Value) & vbVerticalTab & CStr(chkSize.Value)
    Me.Hide
    Unload Me
    End Sub

    Private Sub Form_Load()
    Dim lst As Variant

    form_position Me, True

    lst = Split(varData, vbVerticalTab)

    RichTextBox1.Text = lst(0)
    If lst(1) = -1 Then
    chkLayer.Enabled = False
    Else
    chkLayer.Value = lst(1)
    End If
    If lst(2) = -1 Then
    chkSize.Enabled = False
    Else
    chkSize.Value = lst(2)
    End If

    'match_controls

    End Sub

    Now save all of these (class module, module and form) and compile this as a dll - in my case to "SPPX.dll"

    Back in AutoCAD/Lisp -

    ;;invoke sppx dll ui functions

    (defun fx:sppx_ui ()
    (f:vlerr 'vla-GetInterfaceObject (list (fx:acad) "sppx.ui_functions") nil)
    )

    sppx is the dll, and ui_functions is the class module (see the VB code above)

    - here f:vlerr is a catch-error function (added at the end of this description) and (fx:acad) is the autocad application object (set with (vlax-get-acad-object)...


    Once you have the activex object you can invoke methods from it's classes, e.g.:

    (setq ret (f:vlerr 'vlax-invoke (list (fx:sppx_ui) 'get_text "Test Text") T)

    Note that the method is called get_text (see the VB code in the class modul above).

    Assuming that you have set up your dll correctly (and that I have explained this well enough) this will return the text from the RichTextBox in your form (frmTextEdit).

    You can pass multiple arguments and 1-D lists (I seem to recall having problems for multi-dimensional lists). In the code that I posted here - I parse a string to get the list.( Rather than revise the code I am posting as is for speed's sake).

    As you can imagine - this greatly expands the UI possibilities for lisp - and makes it much simpler to interact with other applications through VB. It is well worth learning - and there are better descriptions than this one (I think I learned this from a tutorial on the acadx.com website - though I don't know anymore where that tutorial is). I hope, though, that this is enough to get you both interested and started.

    Peter

    (defun fx:acad ()
    (setq *AutoCAD-application-object*
    (cond
    (*AutoCAD-application-object*)
    ((vlax-get-acad-object))
    (T nil)
    )
    )
    )



    ;;f:vlerr simplified error catching routine for vl-catch*
    ;;f:vlerr usage (setq en (f:vlerr 'vla-get-Area (list en) nil))
    ;;f:vlerr tag = true for debugging: princes error message


    (defun f:vlerr (fun lst tag / ret *error*)

    (if (or (null lst) (not (listp lst)))
    (progn
    (f:prm (list "\n***f:vlerr error: lst variable must be passed as a list (" lst ").***"))
    (exit)
    )
    )


    (if (vl-catch-all-error-p (setq ret (vl-catch-all-apply fun lst)))
    (if tag
    (progn (f:prm (list "\n" (vl-catch-all-error-message ret) "\n" fun lst)) nil)
    nil
    )
    (if (not ret) (setq ret T) ret)
    )
    (if (= (type ret) 'VL-CATCH-ALL-APPLY-ERROR) (setq ret nil))


    ret)

    (defun f:prm (x) (f:notice x nil))

    (defun f:notice (x tag / tx ret)
    (if (= (type x) 'STR)
    (setq tx (strcat "\n" (vl-princ-to-string x)))
    (if (and x (listp x))
    (progn
    (if (= (last x) nil)
    (setq ret nil x (reverse (cdr (reverse x))))
    )
    (setq tx (strcat "\n" (f:join (mapcar 'vl-princ-to-string x) "")))
    )
    )
    )
    (cond
    ((not tx))
    ((= tag 0)
    tx
    )
    (tag (alert tx)
    (if ret nil T)
    )
    (T (prompt tx)
    (if ret nil T)
    )
    )
    tx)
     
    petersciganek, Feb 24, 2005
    #4
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.