DCL Trouble

Discussion in 'AutoCAD' started by Michael Bulatovich, Mar 5, 2005.

  1. I'll admit to only ever having successfully integrated a dialog box with a
    lisp routine once, that I can remember. I find the relationship between the
    DCL and the LSP often confusing, especially WHEN values get assigned.

    I recently decided to pick up where I left off a couple years ago on a DCL
    interface for a lisp I use a lot. The dialog checks out from the point of
    view of layout, but I'm having trouble getting the thing to do what I want.
    The odd thing is that it is based on the one that I got working. The dialog
    doesn't seem to want to 'retire' or close when I hit the button that is
    supposed to return the user to the graphics screen to pick a couple of
    points. If you click the button the dialog persists, as you step through the
    routine, and the computer hangs if you click the cancel button.

    Here's the DCL code for the bottom row in the routine that works:

    : row {
    :spacer { width = 5;}
    : button { // defines the Pick Points button
    label = "Pick Points";
    key = "pickpoints";
    action = "(getpnts)";
    is_default = true;
    fixed_width = true;
    width = 15;
    }
    : retirement_button { // defines the Cancel button
    label = "Cancel";
    width = 15;
    is_cancel = true;
    key = "cancel";
    }
    :spacer { width = 5;}
    } //end of row
    } //end of column
    } //end dialogue

    and here's the code for the same row in the dialog that doesn't:

    : button { // defines the Pick Points button
    label = "Pick Points";
    key = "pickpoints";
    action = "(getpnts)";
    is_default = true;
    fixed_width = true;
    width = 15;
    }
    : retirement_button { // defines the Cancel button
    label = "Cancel";
    width = 15;
    is_cancel = true;
    key = "cancel";
    }
    :spacer { width = 5;}
    } //end of row
    } //end of column
    } //end dialogue

    In their routines the "pick points" buttons are given the same action_tile
    call for a done_dialog with a value. They are both supposed to trigger a
    routine where you pick some points, but in the new one, the routine
    processes all the lisp code in the getpnts routine but the dialog never
    closes and you don't get to pick the points, so the getpoint calls end up
    returning nil.When the routine tries to do math with nil values the whole
    thing goes boom. The dialogue closes before the error message appears.

    In both routines the call to the routine to process the points is located
    between the start_dialog and the unload_dialog calls.

    Anyone had similar troubles?
     
    Michael Bulatovich, Mar 5, 2005
    #1
  2. Michael Bulatovich

    Pete Guest

    Michael, I'm looking at this over and over and getting bleary eyed. The
    only differences between the two that I can see are, 1) the :row and
    :spacer lines are not included in the second listing (irrelevant), and 2)
    there's an extra space between the : and button in the first line of the
    second listing (also harmless, I think).

    Any chance that you can post the lsp code?
     
    Pete, Mar 6, 2005
    #2
  3. Michael Bulatovich

    Pete Guest

    Michael, have you tried something like this? Instead of defining the
    button action in the dcl, do that with action_tile in the lsp code. You'll
    need to add the ans variable to your list of locals.

    In the dcl code:

    : button { // defines the Pick Points button
    label = "Pick Points";
    key = "pickpoints";
    // action = "(getpnts)"; //remove this line
    is_default = true;
    fixed_width = true;
    width = 15;
    }


    In the lsp code:

    (action_tile "pickpoints" "(setq ans 1) (done_dialog)")
    (action_tile "cancel" "(setq ans 0) (done_dialog)")


    (if (= ans 1)
    (getpnts)
    )
    (unload_dialog dcl_id)
    (exit)





    Pete
     
    Pete, Mar 6, 2005
    #3
  4. Thanks Pete. I've plunked them up on the server :

    www.michaelbulatovich.ca/Temp/dddvdr.lsp

    www.michaelbulatovich.ca/Temp/dvdr.DCL

    These are kinda messy with comments all over the place as they are in
    progress, so bear with me. I've even tried breaking up the getpoints
    function, which used to be called "getpnts", but to no avail. The point
    selection doesn't happen, and returns nil. If you check, you'll see that the
    dialog doesn't retire to allow point selection to take place. I'm pretty
    sure the problem is around this issue.



    MichaelB
    www.michaelbulatovich.ca
     
    Michael Bulatovich, Mar 6, 2005
    #4
  5. Michael Bulatovich, Mar 6, 2005
    #5
  6. Michael Bulatovich

    Pete Guest

    Michael, some of that stuff is over my head but I can tell you that by doing
    this:

    ; (new_dialog "dvdr" dcl_id "" '(-1 -1))
    ; (if (not (new_dialog "dvdr" dcl_id)) (exit))
    (if (not (new_dialog "dvdr" dcl_id "" '(-1 -1))) (exit)) ;this line
    combines the 2 preceding lines in your lsp

    You will get the select point prompt. Why? I'm not sure because if this is
    a problem, I don't know why it doesn't crash before you click the get points
    button. What I am sure of is that you are invoking the new_dialog command
    twice for the same dialog in the those two lines.


    As for the cancel button freezing the works, it look like you need to unload
    the dialog within the cond statement, not after it.
    Instead of this:
    (cond
    ((= what_next 4)(getpoints))
    ((= what_next 0)(prompt "\nuser cancelled dialog"))
    )

    (unload_dialog dcl_id)


    do this:
    (cond
    ((= what_next 4)(getpoints))
    ((= what_next 0)
    (progn
    (unload_dialog dcl_id)
    (prompt "\nuser cancelled dialog")
    ) ;progn
    );what_next 0
    );cond


    I have to take a good look at the way you handle the tiles at the start of
    the routine line by line, specifically regarding the arguments in the
    action_tile and mode_tile statements. I never went this deep with dialogs
    and I haven't done much with them in quite some time. Maybe this is the
    kick start that I need. Thanks for posting it.

    Regards,
    Pete

    PS: You could define a second dialog in the same dcl and maybe call it
    preview. It would have 3 buttons; accept, modify, cancel. Define a
    function in the lsp program that opens this dialog. Call the function right
    after you call (getpoints). Have the modify button undo the points and then
    return you to the first dialog and start again if you don't like the first
    results.
     
    Pete, Mar 6, 2005
    #6
  7. Michael Bulatovich

    Pete Guest

    Correction, leave the unload_dialog outside the condition statement but
    change the prompt to princ.

    ((= what_next 0)(princ "\nuser cancelled dialog"))
     
    Pete, Mar 7, 2005
    #7
  8. Michael Bulatovich

    JP Guest

    Like Pete answers, use a certain value to check wether or not the CANCEL
    button is hit.
    Upon hitting the cancel set it to 1 make sure you use that value in the
    declaration of your vars or use a seperate line to set it to nil otherwise
    your routine will run only once every session. :))
    You can than use f.e.:
    (While (/= ans 1)
    --test the dialog values like:---
    (ACTION_TILE "DN" "(SETQ aanz 0) (do_aanz)") :sample
    (ACTION_TILE "BAN" "(SETQ aanz 1) (do_aanz)") ; sample
    (ACTION_TILE "ZAN" "(SETQ aanz 2) (do_aanz)") ; sample
    (ACTION_TILE "accept" "(uitvoer) (DONE_DIALOG)") ;sample OK is hit
    (ACTION_TILE "cancel" "(SETQ ans 1) (DONE_DIALOG)");sample CANCEL is hit
    (START_DIALOG)
    (UNLOAD_DIALOG dcl_id)
    ); end while

    The above sequence is often used in my progs, works like a charm.

    Hope it helps you a little.

    Regards,
    Jan
     
    JP, Mar 7, 2005
    #8
  9. Many thanks Pete. The reopening of the dialog was the first culprit, and you
    fixed the cancel problem too.

    After that was out of the way I could plow through the other mistakes in the
    code, and it now works.

    There's some error prevention to do before it gets distributed...
     
    Michael Bulatovich, Mar 7, 2005
    #9
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.