iCAx开思网

标题: [CAA] 关于CATIA消息响应(CATAttrNotification) [打印本页]

作者: hick    时间: 2007-2-4 11:54
标题: [CAA] 关于CATIA消息响应(CATAttrNotification)
在CATIA装配模块中, 当前打开的是product. 如果用户删除了其某一个组件. 通过消息响应获得其删除组件的名字(partNumber, instanceName) .
这里用的 CATAttrNotification 消息.

现在的问题是, 无法获得删除组件的名字?  
CATAttrNotification  方法: GetAttribute()  .  能否从 CATISpecAttribute 获得到 CATIProduct(被删除的组件) ?

代码如下:
......
CATIProduct_var spRootProduct = spSpec;
CATISpecEvents_var spEvents = spRootProduct ;   
MyEventSubscriber* pMyEventSubscriber = new MyEventSubscriber;
hr = ::AddCallback(pMyEventSubscriber ,
                               spEvents->GetCallbackManager(),
                               spEvents->GetAttrStructNotification(),
                               (CATSubscriberMethod)&MyEventSubscriber::OnDelete,
                  NULL);
......

void MyEventSubscriber::OnDelete    (  CATCallbackEvent  iPublishedEvent,
                                                   void             *ipPublishingObject,
                                            CATNotification  *ipPublishNotification,
                                    CATSubscriberData iUsefulData,
                                    CATCallback       iCallbackId )
{
   //这里的notification 为 CATAttrNotification
CATAttrNotification *pNot = (CATAttrNotification *)ipPublishNotification;
CATBaseUnknown_var pAttr = pNot->GetAttribute( );
CATISpecAttribute_var spSpecAttr = pAttr;
....
}
作者: horizan    时间: 2007-2-4 16:04
为何不用
spEvents->GetDeleteNotification(),
CATDeleteNotification *pNot = CATDeleteNotification *)ipPublishNotification;
CATBaseUnknown_var pAttr = pNot->GetObject();
这样应该更直接
另外:
hr = ::AddCallback(pMyEventSubscriber ,
                               spEvents->GetCallbackManager(),
                               spEvents->GetAttrStructNotification(),
                               (CATSubscriberMethod)&MyEventSubscriber::OnDelete,
                  NULL);
spEvents->GetCallbackManager()替换为spEvents行不行,我没有用过所以想请教。
作者: hick    时间: 2007-2-4 20:30
原帖由 horizan 于 2007-2-4 16:04 发表
为何不用
spEvents->GetDeleteNotification(),
CATDeleteNotification *pNot = CATDeleteNotification *)ipPublishNotification;
CATBaseUnknown_var pAttr = pNot->GetObject();
这样应该更直接


这样不可以. 因为我现在是删除product下的组件, 而不是删除该product.  
作者: horizan    时间: 2007-2-5 12:38
哦,我的错,期待你的Demo共享。
作者: xyzhu    时间: 2007-2-5 16:31
CATAttrNotification  是继承CATSpecNotification的, CATSpecNotification有个方法GetObject,按照CAA文档的解释:
Returns the impacted object (created, modified or deleted according to the notification type).
也许是你要的,但我没试过.
作者: hick    时间: 2007-2-6 11:19
原帖由 xyzhu 于 2007-2-5 16:31 发表
CATAttrNotification  是继承CATSpecNotification的, CATSpecNotification有个方法GetObject,按照CAA文档的解释:
Returns the impacted object (created, modified or deleted according to the notification ty ...


can't get object!   我都试过了.  这里是源代码 demo

to xyzhu:  CATCommandHeaderCommandStartedEvt 有什么方法,属性, 头文件? 我这里查不到

[ 本帖最后由 hick 于 2007-2-6 12:31 编辑 ]
作者: horizan    时间: 2007-2-6 12:11
得到的消息是操作以后的消息,删除以后就不是specobject了,也许这是原因。
作者: acoka    时间: 2007-2-6 12:46
试了你的test wprkspace了

或许你也已经发现当你添加一个组件的时候,可以取到instanace name.
而当你del掉它的时候,你的OnDel是在它被删除后被呼叫的,所以自然得不到它的point,

以前做ds的mold的replace的时候,遇到过类似问题,
我们想replace前后的组件里,如果有同名同类型的parameter,就保持它们的值不变
但ds的replace是 del then create, 后来我们就做了自己的replace, create then del, 在先做个新的组件,然后从旧组件里把值取过来后在del掉它
后来ds在R17之后,开始把一部分mold的replace改成create then del了。
作者: hick    时间: 2007-2-6 13:37
确实如此, 添加组件可以获得,删除就无法获得.  并且只能是direct children. 孙节点就不可以.
难道只能在属性改变(添加或者删除了组件)后, 必须遍历获得root product下所有组件all children. 然后对每个组件 addcallback它的GetDeleteNotification() ?   进行跌代?  或者不断比较all children list, 找出前后不同之处, 以此来判断用户删除的对象?

o GetAttribute()
Returns the concerned attribute.   这个方法有什么用?  从attribute 是无法获得到删除的对象吗?

[ 本帖最后由 hick 于 2007-2-6 13:49 编辑 ]
作者: acoka    时间: 2007-2-6 19:40
有个笨方法

在addin里给每个asmproduct添加feature extension, 把他们的children的alias name以unicodestring形式保存

添加了children或删除后,你的ondel()会被呼叫,里头检测是否多了还是少了孩子,多了就登记,少了就注销对应的extension,并且显示warning dialog

但restriction太多,漏洞也太多。
作者: horizan    时间: 2007-2-6 19:50
原帖由 acoka 于 2007-2-6 19:40 发表
有个笨方法

在addin里给每个asmproduct添加feature extension, 把他们的children的alias name以unicodestring形式保存

添加了children或删除后,你的ondel()会被呼叫,里头检测是否多了还是少了孩子,多了就 ...

呵呵,看来只能是硬生生把一个艺术家逼成小报记者了。
作者: hick    时间: 2007-2-6 21:01
原帖由 horizan 于 2007-2-6 19:50 发表

呵呵,看来只能是硬生生把一个艺术家逼成小报记者了。


. 看来这也是个办法, 能解决问题的一个办法
作者: xyzhu    时间: 2007-2-7 16:34
Use the highlighting:

void MySubscriber::OnDelete(CATCallbackEvent iEvent,
                void *iFrom,
                CATNotification *iNotification, //CATCommandHeaderCommandStartedEvt
                CATSubscriberData iData,
                CATCallback iCallBack)
{
        CATFrmEditor* pEditor = CATFrmEditor::GetCurrentEditor();
        if(pEditor)
        {
                CATHSO* pHso = pEditor->GetHSO();
                if(pHso)
                {
                        int size = pHso->GetSize();
                        if(size)
                        {
                                CATBaseUnknown* pBase = (*pHso)[0];
                                CATPathElement* pPath = (CATPathElement*)pBase;
                                if(pPath)               
                                {
                                        size = pPath->GetSize();
                                        for(int i=0; i<size; i++)
                                        {
                                                CATIProduct_var spPrd ((*pPath));
                                                if(!!spPrd)
                                                {
                                                        CATUnicodeString instName;
                                                        spPrd->GetPrdInstanceName(instName);
                                                        std::cout << "Delete: " << instName.ConvertToChar() << std::endl;
                                                }
                                        }
                                }
                        }
                }
        }
}
作者: acoka    时间: 2007-2-7 17:23
这个ondel是在del完成后被呼叫的
object已经没了,取它的属性是不可能的吧

最好的解决方法就是可以找到一个catia在delete之前会先呼叫的断点
(CATIMechnicalCPP里的CanBeDel()会在被删除前呼叫,但MechnicalPart或ASMProduct好像没有这个I/F)
但即使有,这个东西也只是被呼叫来确认这个obj是不是被禁止删除,而不保证呼叫后它会被删除
作者: xyzhu    时间: 2007-2-7 17:48
这个OnDelete响应的是CATCommandHeaderCommandStartedEvt,这时Delete应该还未被执行,因为事件CATCommandHeaderActivateEvt在CATCommandHeaderCommandStartedEvt之后产生.
作者: horizan    时间: 2007-2-7 19:21
CommandStarted必须对应的是CommandHeader,而一个SpecObject根本没有这个Event。
作者: horizan    时间: 2007-2-7 19:28
要我说干脆Entention接口lifeCyCleObject.
作者: acoka    时间: 2007-2-7 20:42
可以用呀,只要你不坚持用attribute变化的notify

稍微修改一下就可以用
作者: hick    时间: 2007-2-7 21:24
非常感谢xyzhu, acoka ,horizan(排名不分先后, )

确实是用, CATCommandHeaderCommandStartedEvt + CATHSO. 可以满足我的要求,解决问题!

先前放弃了CATCommandHeaderCommandStartedEvt ,是因为对这个事件不了解,手头查不到这个事件任何方法说明. 既然start是在active之前,
HSO是应该可以捕获到用户选择的对象

现在用这个方法已经可以解决问题了,也许还有别的方法....

再次感谢各位的大力热心帮助
作者: horizan    时间: 2007-2-8 10:18
"CATCommandHeaderCommandStartedEvt"是CATCommandHeader宏CATDeclareCb(CommandStarted)的展开。
惭愧呀,偶压根没有想到去callback到delete这个command,还是太嫩了。
向xyzhu, acoka学习!
作者: netroamer    时间: 2007-4-29 11:53
我想响应文档保存消息,请问AddCallback参数应该怎么给呢?以下是我的代码,请高手指教。
CATCommandHeader * pAfrSaveHeader = NULL;
HRESULT hr = ::CATAfrGetCommandHeader("CATAfrFileSaveHdr", pAfrSaveHeader);
MyEventSubscriber* pMyEventSubscriber = new MyEventSubscriber;
hr = ::AddCallback(pMyEventSubscriber ,pAfrSaveHeader,
                "CATCommandHeaderCommandStartedEvt",
                (CATSubscriberMethod)&MyEventSubscriber::OnSave,
                NULL);




欢迎光临 iCAx开思网 (https://www.icax.org/) Powered by Discuz! X3.3