复制实体时如何更新实体的xdata信息

时间:2019-07-01 17:55:57

标签: lisp autocad autolisp

我有两条文本与一行相关。由于文本代表该行的某些数据,因此它们始终被视为该行的子级,并且在该行旁边可见。通过一些lisp例程,如果行的数据发生更改,则文本实体会通过更改其文本来反映更改。为此,我将每个文本的行句柄存储为xdata,反之亦然,例如文本的句柄。

当我用文本复制行时出现问题,每个文本都有一个新的句柄,但是存储的xdata提供了旧的句柄,这导致了进一步的问题。我以为vlr-copied反应堆可以解决我的问题,但是由于我对反应堆不是很熟练,所以我似乎无法使其工作。

有人可以指出我正确的方向吗?我找到了

http://www.theswamp.org/index.php?topic=42654.0

但是我无法理解选择线集时(包括不相关的其他实体)如何将正确的选择集传递到反应堆并更新手柄。

任何建议表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

首先,您需要假设要复制的对象(文本或行)是独立于另一个对象的,然后才决定对象要表现的行为。由于两个对象已链接,因此您可能需要确定哪个对象是'master',哪个是'slave'

例如,如果将文本对象复制到空白区域,则由于没有可引用的行,因此您可能决定删除结果副本。而如果将行复制到空白区域,则可以决定复制关联的文本对象,并将其相对于新行定位。

这是我开发Associative Textbox应用程序时遵循的方法(本质上解决了将图形中的两个对象(在我的情况下是文本对象和边界框架)相关联的问题。) >

在我的应用程序中,我使用一个单独的对象反应器分别处理文本对象和文本框的修改事件:

(vlr-object-reactor txt "tbox-textreactor"
   '(
        (:vlr-modified . tbox:textcallback)
        (:vlr-copied   . tbox:textcopied)
    )
)
(vlr-object-reactor box "tbox-tboxreactor"
   '(
        (:vlr-modified . tbox:tboxcallback)
        (:vlr-copied   . tbox:tboxcopied)
    )
)

类似于您的设置,它们是在程序加载时使用附加到文本和文本框的扩展实体数据(xData)构建和配置的。

当触发texbox的Copy事件(评估tbox:tboxcopied回调函数)时,我认为如果没有文本框,文本框就无法生存,因此我从图形中删除了孤立的文本框。

但是,使用对象反应器时必须记住的最重要一点是您不能在其自身的回调函数中修改对象反应器的所有者

这样,对于所有需要修改事件所有者的修改事件,我都会生成一个临时Command Reactor,它将在对象被修改后触发 ,以确保该对象未锁定修改。

例如,对于文本框复制事件,我使用以下内容:

(defun tbox:tboxcopied ( owner reactor params )
    (if (/= 0 (car params))
        (progn
            (setq tbox:owner (append tbox:owner (list (car params))))
            (vlr-command-reactor "tbox-tboxcopiedcommreactor"
               '(
                    (:vlr-commandended     . tbox:tboxcopiedcommandended)
                    (:vlr-commandcancelled . tbox:tboxcopiedcommandcancelled)
                    (:vlr-commandfailed    . tbox:tboxcopiedcommandcancelled)
                )
            )            
        )
    )
    (princ)
)

然后我在其自己的任何回调函数中删除此临时Command Reactor,以防止冗余反应堆在图形中传播:

(defun tbox:tboxcopiedcommandended ( reactor params / ent )
    (vlr-remove reactor) ;; <----- Remove temporary Command Reactor
    (if
        (and
            (setq ent (car tbox:owner))
            (member (cdr (assoc 0 (entget ent))) '("CIRCLE" "LWPOLYLINE"))
        )
        (entdel ent) ;; <----- Delete orphan textbox
    )
    (setq tbox:owner (cdr tbox:owner))
    (princ)
)

在复制文本时,我将重新创建周围的文本框并建立新的关联(再次,生成临时Command Reactor以便于修改文本对象本身):

(defun tbox:textcopied ( owner reactor params )
    (if (/= 0 (car params))
        (progn
            (setq tbox:owner (append tbox:owner (list (car params))))
            (vlr-command-reactor "tbox-textcopiedcommreactor"
               '(
                    (:vlr-commandended     . tbox:textcopiedcommandended)
                    (:vlr-commandcancelled . tbox:textcopiedcommandcancelled)
                    (:vlr-commandfailed    . tbox:textcopiedcommandcancelled)
                )
            )
        )
    )
    (princ)
)

...并重新创建适当的文本框,作为临时Command Reactor的回调函数的一部分:

(defun tbox:textcopiedcommandended ( reactor params / box ent enx val )
    (vlr-remove reactor) ;; <----- Remove temporary Command Reactor
    (if
        (and
            (setq ent (car tbox:owner))
            (setq enx (entget ent (list tbox:app)))
            (member (cdr (assoc 0 enx)) '("TEXT" "MTEXT"))
            (setq val (cdadr (assoc -3 enx)))
            (setq box (tbox:createbox enx (cdr (assoc 1000 val)) (cdr (assoc 1040 val))))
        )
        (progn
            (entmod
                (append (vl-remove (assoc 40 enx) (entget ent))
                    (list
                        (list -3
                            (list tbox:app
                               '(1002 . "{")
                                (cons  1005 (cdr (assoc 5 (entget box))))
                                (assoc 1000 val)
                                (assoc 1040 val)
                               '(1002 . "}")
                            )
                        )
                    )
                )
            )
            (if (= 'vlr-object-reactor (type tbox:textreactor))
                (vlr-owner-add tbox:textreactor (vlax-ename->vla-object ent))
            )
            (if (= 'vlr-object-reactor (type tbox:tboxreactor))
                (vlr-owner-add tbox:tboxreactor (vlax-ename->vla-object box))
            )                    
        )            
    )
    (setq tbox:owner (cdr tbox:owner))
    (princ)
)

上面介绍的方法是我为您的情况推荐的方法:

复制文本后,删除生成的孤立文本对象;复制时,创建一个相应的文本对象,并在复制的行和新文本对象之间建立关联

相关问题