首先,您需要确定您希望对象表现出的行为,假设其中一个对象(文本或行)是独立于另一个对象复制的。由于这两个对象是链接的,您可能需要确定哪个对象是 '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 回调函数)时,我决定文本框没有它所包含的文本就无法生存,因此我从绘图中删除了孤立文本框。
但是,在使用对象反应器时,您必须记住的最重要一点是您不能在其自己的回调函数中修改对象反应器的所有者。
因此,对于我需要修改事件所有者的所有修改事件,我会生成一个临时命令反应器,它将在对象被修改后触发,以确保对象未锁定以进行修改。
例如,对于文本框复制事件,我使用以下内容:
(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)
)
然后我在它自己的任何回调函数中删除这个临时命令反应器,以防止图形中冗余反应器的传播:
(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)
)
然而,当 text 被复制时,我会重新创建周围的文本框并建立新的关联(同样,生成一个临时命令反应器以方便修改文本对象本身):
(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)
)
...并重新创建适当的文本框作为临时命令反应器的回调函数的一部分:
(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)
)
我上面描述的方法是我为您的场景推荐的方法:
文本被复制后,删除生成的孤立文本对象;当行被复制时,创建一个对应的文本对象,并在复制的行和新的文本对象之间建立关联。