SolidEdge是Siemens PLM Software公司旗下的三维CAD软件,采用Siemens PLM Software公司自己拥有专利的Parasolid作为软件核心,将普及型CAD系统与世界上最具领先地位的实体造型引擎结合在一起,是基于Windows平台、功能强大且易用的三维CAD软件。扩展阅读:SolidEdge:一款被低估的CAD软件,助你开启高效机械设计解决方案(附学习教程)
SolidEdge二次开发有COM和Addin两种方式,其中COM(组件对象模型)具有不依赖平台和编程语言等优点,是最常用的一种Solid二次开发方式。
一、处理应用程序正忙的错误
当通过外部方式进行访问SolidEdge应用程序时,有可能会报以下异常:
应用程序正在运行时或未响应(RPC_E_CALL_REJECTED 0x80010001)
拒绝被调用(RPC_E_SERVERCALL_RETRYLATER 0x8001010A)
发生这些错误是因为二次开发程序和SolidEdge之间的线程争用问题,可以通过实现IOleMessageFilter接口处理这些异常。
首先创建OleMessageFilter,实现IOleMessageFilter接口,代码如下:
namespace UGITCApp
{
class OleMessageFilter : IOleMessageFilter
{
public static void Register()
{
IOleMessageFilter newFilter = new OleMessageFilter();
IOleMessageFilter oldFilter = null;
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
{
CoRegisterMessageFilter(newFilter, out oldFilter);
}
else
{
throw new COMException("Unable to register message filter because the current thread apartment state is not STA.");
}
}
public static void Revoke()
{
IOleMessageFilter oldFilter = null;
CoRegisterMessageFilter(null, out oldFilter);
}
int IOleMessageFilter.HandleInComingCall(
int dwCallType,
System.IntPtr hTaskCaller,
int dwTickCount,
System.IntPtr lpInterfaceInfo)
{
return (int)SERVERCALL.SERVERCALL_ISHANDLED;
}
int IOleMessageFilter.RetryRejectedCall(
System.IntPtr hTaskCallee,
int dwTickCount,
int dwRejectType)
{
if (dwRejectType == (int)SERVERCALL.SERVERCALL_RETRYLATER)
{
return 99;
}
return -1;
}
int IOleMessageFilter.MessagePing(
System.IntPtr hTaskCallee,
int dwTickCount,
int dwPingType)
{
return (int)PINGMSG.PINGMSG_WAITDEFPROCESS;
}
[DllImport("Ole32.dll")]
private static extern int CoRegisterMessageFilter(
IOleMessageFilter newFilter,
out IOleMessageFilter oldFilter);
}
[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IOleMessageFilter
{
[PreserveSig]
int HandleInComingCall(
int dwCallType,
IntPtr hTaskCaller,
int dwTickCount,
IntPtr lpInterfaceInfo);
[PreserveSig]
int RetryRejectedCall(
IntPtr hTaskCallee,
int dwTickCount,
int dwRejectType);
[PreserveSig]
int MessagePing(
IntPtr hTaskCallee,
int dwTickCount,
int dwPingType);
}
}
使用方法如下:
static void Main(string[] args)
{
OleMessageFilter.Register();
// Make COM calls.
OleMessageFilter.Revoke();
}
二、获取所有的Application实例对象
二次开发时,我们通常使用GetActiveObject获取当前激活的SolidEdge的COM接口对象。
如果打开多个SolidEdge窗口时,如何获取所有的接口对象,通过程序筛选需要的接口对象?这个时候就需要获取当前所有的运行对象表。
首先引用CreateBindCtx函数,创建绑定上下文对象操作的指针,代码如下:
通过绑定上下文对象获取运行时对象表,并筛选出指定的接口对象,代码如下:
调用方法如下,即可获取所有的已经运行的SolidEdge应用接口对象:
三、如何获取材料信息?
在开发过程中,SolidEdge的材料表也是很重要的一部分功能,SolidEdge自身有材料库界面,但同样可以通过二次开发获取,我们以2022为例介绍如何获取。
关键代码如下:
1、获取材料表对象
MatTable matTable = SolidEdgeFramework.Application.GetMaterialTable();
无输入参数,返回SolidEdge的材料表对象MatTable。
2、获取材料表中材料库
matTable.GetMaterialLibraryList(out object listOfMaterialLibs, out int numOfMaterialList);
通过上述的matTable,获取到材料表配置中所有的材料库及数量,每个材料列表包含多种材料。
3、根据材料列表名称获取材料
matTable.GetMaterialListFromLibrary(libName, out int materialNums, out object listOfMaterials);
根据matTable对象,输入libName(材料库名称),输出材料库当中包含的所有材料名称和数量。
4、获取材料属性
matTable.GetMaterialPropValueFromLibrary(matName,libName, MatTablePropIndex, out object value);
根据matTable对象,输入matName(材料名称)、libName(材料库名称)、MatTable Prop Index(材料属性索引),即可获取对应材料属性的值。
实现效果如下:
图1 读取材料表
SolidEdge当中获取材料的关键代码如上所述,效果图中可以看到,在名为Materials的材料库中,名为铝 1350的材料,它的密度属性值为2.712。熟练应用以上4组代码,即可实现对所有材料信息的获取。
以上三则实用经验你学会了吗?更多关于SE二次开发的问题可以扫码添加小造微信好友(添加时备注:SE),进群交流