TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: cjw on May 18, 2009, 01:43:57 AM
-
[How]
Change the number'color to "red",if the number smaller than 500;
Else,change the number'color to "bylayer"
(vl-load-com)
;;By carrot1983 2009-05-18
(defun C:TT (/ DATA_LST E OWN_LST)
(if (setq E (car (entsel "\nSelect the number: ")))
(progn
(setq DATA_LST (list 500))
(setq OWN_LST (list (vlax-ename->vla-object E)))
(vlr-pers
(vlr-object-reactor
OWN_LST
DATA_LST
'((:vlr-modified . REACTOR-CHANGE-COLOR))
)
)
)
)
(princ)
)
(defun REACTOR-CHANGE-COLOR (OWNER DATA PAR / DATA_LST E1 TXT V1)
(setq TXT (vla-get-textstring OWNER))
(setq DATA_LST (vlr-data DATA))
(if (< (read TXT) (car DATA_LST))
(setq A (vl-catch-all-apply
'vla-put-color
(list OWNER 1)
)
)
(setq A (vl-catch-all-apply
'vla-put-color
(list OWNER acbylayer)
)
)
)
(princ)
)
;;After modified
;;(VL-CATCH-ALL-ERROR-MESSAGE A)
;;Error: AutoCAD.Application: ....
-
your code will continue changing the object color after the reactor is originally fired and, that will trigger an non-stopable calling for ur call-back function becoz changing color will also fire vlr:modified.
You need to record the old color of object and to detect if a color change is necessary. So the scenario of changing might be:
1: u change the number
2: callback function is fired as object is changed by content, then object color is changed if necessary
3: callback function is fired again if object color is changed
4: as the color is already be correct, then no change of color is needed any more. And then u can quit reactor callback function normally.
-
your code will continue changing the object color after the reactor is originally fired and, that will trigger an non-stopable calling for ur call-back function becoz changing color will also fire vlr:modified.
You need to record the old color of object and to detect if a color change is necessary. So the scenario of changing might be:
1: u change the number
2: callback function is fired as object is changed by content, then object color is changed if necessary
3: callback function is fired again if object color is changed
4: as the color is already be correct, then no change of color is needed any more. And then u can quit reactor callback function normally.
Have you actually tried this, because I think the problem is actually a little deeper. You actually can't modify the object that issued the notification because it is potentially still open for writing.
What you can do is add the object's id to a list and then grab it from its id and modify it in an editor reactor rather than a database reactor. It means you end up with an extra reactor, but to my knowledge, it is the only safe means of doing what you want.
-
...
You actually can't modify the object that issued the notification because it is potentially still open for writing.
Yes you are right.
-
Have you actually tried this, because I think the problem is actually a little deeper. You actually can't modify the object that issued the notification because it is potentially still open for writing.
I can't believe I actually used the word "actually" that many times in a single paragraph. :D
-
Thank you, kozmos Chuck Gabriel !
My english is not good.so....
I have no idea to fix it.
I don't know how to understand it.
1: u change the number
2: callback function is fired as object is changed by content, then object color is changed if necessary
3: callback function is fired again if object color is changed
4: as the color is already be correct, then no change of color is needed any more. And then u can quit reactor callback function normally.
Could realize it by Lisp code?
-
Fair warning, this is hacky code, but it should get you started.
(vl-load-com)
(setq *TT:NOTIFYING* T)
(defun TT:COMMAND-ENDED (reactor commandName)
(setq *TT:NOTIFYING* nil)
(foreach ent *TT:MODIFIED_LESS*
(vla-put-color ent 1)
)
(foreach ent *TT:MODIFIED_GREATER*
(vla-put-color ent acbylayer)
)
(setq
*TT:NOTIFYING* T
*TT:MODIFIED_LESS* nil
*TT:MODIFIED_GREATER* nil
)
(princ)
)
(defun TT:CLEANUP ()
(mapcar 'vlr-remove-all
'(:vlr-acdb-reactor
:vlr-editor-reactor
:vlr-linker-reactor
:vlr-object-reactor
)
)
)
(defun TT:OBJECT-CHANGED (OWNER DATA PAR / DATA_LST TXT)
(if *TT:NOTIFYING*
(progn
(setq TXT (vla-get-textstring OWNER))
(setq DATA_LST (vlr-data DATA))
(if (< (read TXT) (car DATA_LST))
(setq *TT:MODIFIED_LESS*
(if *TT:MODIFIED_LESS*
(if (member OWNER *TT:MODIFIED_LESS*)
*TT:MEMBER_LESS*
(cons OWNER *TT:MODIFIED_LESS*)
)
(list OWNER)
)
)
(setq *TT:MODIFIED_GREATER*
(if *TT:MODIFIED_GREATER*
(if (member OWNER *TT:MODIFIED_GREATER*)
*TT:MODIFIED_GREATER*
(cons OWNER *TT:MODIFIED_GREATER*)
)
(list OWNER)
)
)
)
)
)
(princ)
)
(or *commandReactor*
(setq *commandReactor*
(vlr-command-reactor
nil
'((:vlr-commandEnded . TT:COMMAND-ENDED))
)
)
)
(or *cleanupReactor*
(setq *cleanupReactor*
(vlr-dwg-reactor
nil
'((:vlr-beginClose . TT:CLEANUP))
)
)
)
(defun C:TT (/ DATA_LST E OWN_LST)
(if (setq E (car (entsel "\nSelect the number: ")))
(progn
(setq
DATA_LST (list 500)
OWN_LST (list (vlax-ename->vla-object E))
)
(vlr-object-reactor
OWN_LST
DATA_LST
'((:vlr-modified . TT:OBJECT-CHANGED))
)
)
)
(princ)
)
-
Chuck Gabriel ,Thanks for your kindness!!
Learning your code...
Thank you very much.
-
After did the test,I found it can't work,so add two code.Like this.
So now it work...I am studying....
Thanks again.
(if (< (read TXT) (car DATA_LST))
(progn
(setq *TT:MODIFIED_LESS*
(if *TT:MODIFIED_LESS*
(if (member OWNER *TT:MODIFIED_LESS*)
*TT:MEMBER_LESS*
(cons OWNER *TT:MODIFIED_LESS*)
)
(list OWNER)
)
)
[color=red] (setq *TT:MODIFIED_GREATER* NIL);_ADD CODE[/color]
)
(progn
(setq *TT:MODIFIED_GREATER*
(if *TT:MODIFIED_GREATER*
(if (member OWNER *TT:MODIFIED_GREATER*)
*TT:MODIFIED_GREATER*
(cons OWNER *TT:MODIFIED_GREATER*)
)
(list OWNER)
)
)
[color=red] (setq *TT:MODIFIED_LESS* NIL);_ADD CODE[/color]
)
)