OpenDCL Forums

OpenDCL => FAQs => Topic started by: Fred Tomke on December 14, 2009, 03:18:09 AM

Title: How to close a modal form to pick a point and re-show the form again
Post by: Fred Tomke on December 14, 2009, 03:18:09 AM
Question:
I want to pick a point in AutoCAD while a modal form is showing.

Answer:
You cannot pick a point or select objects in the drawing as long a modal form is showing. You have to close the form and to show it again after you have picked the point. The returning values for dcl_form_show and dcl_form_close will help you.

Code (autolisp) Select

(defun c:MyProg (/ doCont intResult c:proj_form_OnInitialize c:proj_form_pb_accept c:proj_form_pb_select c:proj_form_pb_cancel)
  (defun c:proj_form_OnInitialize ()
    (princ "Initializing the form...")
  );  c:proj_form_OnInitialize

  (defun c:proj_form_pb_accept ()
    (dcl_form_close proj_form 0)
  ); c:proj_form_pb_accept

  (defun c:proj_form_pb_select ()
    (dcl_form_close proj_form 1)
  ); c:proj_form_pb_select

  (defun c:proj_form_pb_cancel ()
    (dcl_form_close proj_form 2)
  ); c:proj_form_pb_cancel

  (setq doCont T)
  (while doCont
    (setq doCont nil) ;; to avoid neverending loop at ESC
    (setq intResult (dcl_form_show proj_form))
    (cond
      ((= intResult 0) (princ "Something will happen here."))
      ((= intResult 1) (setq ptPoint (getpoint "\nPick point: ")) (setq doCont T)) ;; don't forget to set doCont to T to show the form again
      ((= intResult 2) (princ "This will be executed after ESC and after pressing Cancel button."))
    ); cond
  ); while
  (princ)
); MyProg


Here you will find a sample with placing blocks:
http://www.opendcl.com/forum/index.php?topic=769.0 (http://www.opendcl.com/forum/index.php?topic=769.0)

Here you will find a sample with a nested dialog.
http://www.opendcl.com/forum/index.php?topic=947.0 (http://www.opendcl.com/forum/index.php?topic=947.0)

Also see the "Selections.lsp" sample installed with the Studio under: "C:\Program Files\OpenDCL Studio\<LANGUAGE>\Samples"

Fred
Title: How to close a modal form to pick a point and re-show the form again - Part II
Post by: Fred Tomke on February 26, 2010, 01:31:37 PM
Hello,

in addition to the initial post, this post is going into detail, when a modal form is being called from a modeless form (or palette or dockable form) and you want to have access to the AutoCAD drawing database from the modal form.

Like in the first part you will have to close the modal form, as long as you need access to the drawing database. AutoCAD prevents you from having fully access to the drawing database if you call the modal form within a synchronous called event handler. The following event handler won't give you access to the drawing database if the EventInvoke property state of the clicked button is 0 for KeepFocus (don't mix it with the KeepFocus property of forms!).

Code (autolisp) Select

(defun c:MyProj_MyForm_MyButton1_OnClicked ()
  (dcl_form_Hide MyProj_MyForm T)
  (call_function_with_modal_form)
  (dcl_form_Hide MyProj_MyForm nil)
); c:MyProj_MyForm_MyButton1_OnClicked

(defun c:MyProj_MyForm_MyButton2_OnClicked ()
  (dcl_form_close MyProj_MyForm)
  (call_function_with_modal_form)
  (dcl_form_show MyProj_MyForm)
); c:MyProj_MyForm_MyButton2_OnClicked


This code works very well as long as you don't need access to the drawing database. But if you want to pick points, select objects or attach object data you will have to finish the event handler at first!

There are 2 ways to do that:

1. Call another command using dcl_sendstring from a synchronous called event handler.
This makes only sense if you have to define additional variables at first or you have to finish other tasks at first before calling the other command.

2. The event handler is an own command which is called asynchronous.

The attached sample will show you how to work with modeless forms, modal forms and user inputs from the commandline.
It is based on a topic from andrew (http://www.opendcl.com/forum/index.php?topic=1171.msg6323#msg6323).
All files need to be located into an AutoCAD support path. Compare both buttons of the modeless form with each other.

Note: the latest selected item will be stored into the drawing using vlax-ldata-put. Also outside any event and modal form!!!
Change objects and objectdata outside (!!!) a running modal form and never inside. Make sure that Lisp-reactors are getting never fired when a modal form is active or a synchronous event is running.

Have fun,
Fred