Table of Contents

Introduction
Solid Edge ST is a 3D CAD parametric feature solid modeling software that now features Synchronous Technology. It runs on Microsoft Windows platforms and provides solid modeling, assembly modelling and drafting functionality for mechanical engineers.
Throughout its history, Solid Edge has supported 3rd party COM addins similar to Microsoft Office products. Whether you're an engineer with C++ experience or a full-time programmer, this article will layout the details that you'll need to create your own custom Solid Edge addins.
In order to reference the SDK information discussed in this article, you must have Solid Edge ST installed. If you want to purchase your own copy of Solid Edge ST, you will need to find a reseller. One that I know of off hand is Swoosh Technologies. The actual cost of a seat of Solid Edge ST will vary on a number of factors. I believe though the range is around $5000 - $6000, give or take a few thousand.
Overview
This article is the 1st of a series that I plan to create in order to bring people up to speed on creating Solid Edge addins. I will only demonstrate the bare minimum requirements to create an addin in this article. There are many things you can do with an addin and I will cover those in future articles.
While it is certainly possible to create an addin using any COM enabled programming language, I chose to keep it simple and focus on VC++ and ATL technologies. If you need MFC, WTL, etc. in your project, you can certainly add it yourself and expand on what I'm presenting here. I'll also note that it is also possible to use .NET to create COM Addins, but that's an entirely different article in itself with its own set of problems.
I also want to mention that while this article is written specifically for Solid Edge ST, the majority of the article is still valid for older releases of Solid Edge. The path to the Solid Edge installation directory will vary from release to release. New interfaces\method\properties may be referenced in this article that are not available in older releases.
The Solid Edge API
The Solid Edge API is a very large and robust COM based API. Solid Edge can be automated using any modern COM enabled programming\scripting language.
SDK
When you install Solid Edge, you will have access to the SDK which can be found in "%PROGRAMFILES%\Solid Edge ST\SDK". You will want to reference the following items in the SDK.
- \include\*.h
- \Samples\Addins\Doc\addin.doc
- Sesdk.chm
Type Libraries
In the following table, I have outlined the most significant portions of the Solid Edge API. Solid Edge offers other API's for various things but these are the most commonly used for addin development. All of the Solid Edge type libraries can be found in the "%PROGRAMFILES%\Solid Edge ST\Program" folder.
The SolidEdgeFramework type library is the base library. It contains everything you will need to create a Solid Edge addin. Specifically, we will implement the ISolidEdgeAddIn interface. This interface is analogous to Microsoft's IDTExtensibility2 interface for creating Office addins.
| Solid Edge Type Libraries |
| File |
Namespace |
Description |
LIBID |
| assembly.tlb |
SolidEdgeAssembly |
Solid Edge Assembly Type Library |
A2259BE4-7E1B-4893-AFF1-96C721E58FDD |
| assemblysync.tlb |
SolidEdgeAssemblySync |
Solid Edge Assembly Sync Type Library |
3E2B3BD4-F0B9-11D1-BDFD-080036B4D502 |
| constant.tlb |
SolidEdgeConstants |
Solid Edge Constants Type Library |
C467A6F5-27ED-11D2-BE30-080036B4D502 |
| draft.tlb |
SolidEdgeDraft |
Solid Edge Draft Type Library |
3E2B3BDC-F0B9-11D1-BDFD-080036B4D502 |
| framewrk.tlb |
SolidEdgeFramework |
Solid Edge Framework Type Library |
8A7EFA3A-F000-11D1-BDFC-080036B4D502 |
| fwksupp.tlb |
SolidEdgeFrameworkSupport |
Solid Edge FrameworkSupport Type Library |
943AC5C6-F4DB-11D1-BE00-080036B4D502 |
| geometry.tlb |
SolidEdgeGeometry |
Solid Edge Geometry Type Library |
3E2B3BE1-F0B9-11D1-BDFD-080036B4D502 |
| InstallData.tlb |
SEInstallDataLib |
Solid Edge Install Data Library |
42E04299-18A0-11D5-BBB2-00C04F79BEA5 |
| Part.tlb |
SolidEdgePart |
Solid Edge Part Type Library |
8A7EFA42-F000-11D1-BDFC-080036B4D502 |
| PartSync.tlb |
SolidEdgePartSync |
Solid Edge Part Sync Type Library |
EAB2DA59-5457-41D9-AEEA-9EC9D424A208 |
Environment Categories
Solid Edge has many possible environments that addin developers need to account for. These CATID's are documented in the "%PROGRAMFILES%\Solid Edge ST\SDK\include\secatids.h" include. This information is important later in the article when I discuss the ExampleAddIn.rgs registry script.
You can use CATID_SEApplication when you want your addin to work outside of a specific environment. For example, when you first start Solid Edge and no documents are open. You can also use CATID_SEAllDocumentEnvrionments when you want your addin to work in all document environments, even future document environments that do not currently exist. Similarly, you can use CATID_SEAll to support all environments, even future environments that do not currently exist.
The following table describes the possible Environment Categories.
| CATIDs for Solid Edge Environment categories |
| Category ID |
GUID |
Notes |
| CATID_SEApplication |
{26618394-09D6-11d1-BA07-080036230602} |
Application Environment |
| CATID_SEAssembly |
{26618395-09D6-11d1-BA07-080036230602} |
Traditional Assembly Document Environment |
| CATID_SEMotion |
{67ED3F40-A351-11d3-A40B-0004AC969602} |
|
| CATID_SEPart |
{26618396-09D6-11d1-BA07-080036230602} |
Traditional Part Document Environment |
| CATID_SEProfile |
{26618397-09D6-11d1-BA07-080036230602} |
|
| CATID_SEFeatureRecognition |
{E6F9C8DC-B256-11d3-A41E-0004AC969602} |
|
| CATID_SESheetMetal |
{26618398-09D6-11d1-BA07-080036230602} |
Traditional SheetMetal Document Environment |
| CATID_SEDraft |
{08244193-B78D-11d2-9216-00C04F79BE98} |
Draft Document Environment |
| CATID_SEWeldment |
{7313526A-276F-11d4-B64E-00C04F79B2BF} |
|
| CATID_SEXpresRoute |
{1661432A-489C-4714-B1B2-61E85CFD0B71} |
XpresRoute is also know as "Tubing" which is what the env returns as its name. |
| CATID_SEExplode |
{23BE4212-5810-478b-94FF-B4D682C1B538} |
|
| CATID_SESimplify |
{CE3DCEBF-E36E-4851-930A-ED892FE0772A} |
|
| CATID_SEStudio |
{D35550BF-0810-4f67-97D5-789EDBC23F4D} |
|
| CATID_SELayout |
{27B34941-FFCD-4768-9102-0B6698656CEA} |
|
| CATID_SESketch |
{0DDABC90-125E-4cfe-9CB7-DC97FB74CCF4} |
Sketch is also know as "LayoutInPart" which is what the env returns as its name. |
| CATID_SEProfileHole |
{0D5CC5F7-5BA3-4d2f-B6A9-31D9B401FE30} |
|
| CATID_SEProfilePattern |
{7BD57D4B-BA47-4a79-A4E2-DFFD43B97ADF} |
|
| CATID_SEProfileRevolved |
{FB73C683-1536-4073-B792-E28B8D31146E} |
|
| CATID_SEDrawingViewEdit |
{8DBC3B5F-02D6-4241-BE96-B12EAF83FAE6} |
|
| CATID_SERefAxis |
{B21CCFF8-1FDD-4f44-9417-F1EAE06888FA} |
|
| CATID_SECuttingPlaneLine |
{7C6F65F1-A02D-4c3c-8063-8F54B59B34E3} |
|
| CATID_SEBrokenOutSectionProfile |
{534CAB66-8089-4e18-8FC4-6FA5A957E445} |
|
| CATID_SEFrame |
{D84119E8-F844-4823-B3A0-D4F31793028A} |
|
| CATID_2dModel |
{F6031120-7D99-48a7-95FC-EEE8038D7996} |
|
| CATID_EditBlockView |
{892A1CDA-12AE-4619-BB69-C5156C929832} |
|
| CATID_SEComponentSketchInPart |
{FAB8DC23-00F4-4872-8662-18DD013F2095} |
|
| CATID_SEComponentSketchInAsm |
{86D925FB-66ED-40d2-AA3D-D04E74838141} |
|
| CATID_SEHarness |
{5337A0AB-23ED-4261-A238-00E2070406FC} |
|
| CATID_SEAll |
{C484ED57-DBB6-4a83-BEDB-C08600AF07BF} |
All Environments |
| CATID_SEAllDocumentEnvrionments |
{BAD41B8D-18FF-42c9-9611-8A00E6921AE8} |
All Document Environments |
| CATID_SEDMPart |
{D9B0BB85-3A6C-4086-A0BB-88A1AAD57A58} |
Synchronous Part Document Environment |
| CATID_SEDMSheetMetal |
{9CBF2809-FF80-4dbc-98F2-B82DABF3530F} |
Synchronous SheetMetal Document Environment |
| CATID_SEDMAssembly |
{2C3C2A72-3A4A-471d-98B5-E3A8CFA4A2BF} |
Synchronous Assembly Document Environment |
ISolidEdgeAddIn Interface
The ISolidEdgeAddIn interface is the interface that all Solid Edge addins must implement to be recognized by Solid Edge. It has 3 methods that get called by Solid Edge back into your addin. You can also reject the loading of your addin by returning any HRESULT other than S_OK in OnConnection.
HRESULT OnConnection( IDispatch *pApplication, seConnectMode ConnectMode, AddIn *pAddIn )
pApplicationSolidEdgeFramework::Application pointer to the dispatch interface of the Solid Edge application that is attempting to connect to the addin. The addin uses this pointer to make any necessary calls to the application to connect to Solid Edge event sinks, or to otherwise communicate with Solid Edge to perform whatever tasks the add-in needs when first starting up.ConnectMode- Connect mode that indicates what caused Solid Edge to connect to the addin. The possible values are:
seConnectAtStartUp - Loading the addin at startup.
seConnectByUser - Loading the addin at user's request.
seConnectExternally - Loading the addin due to an external (programmatic) request.
pAddInSolidEdgeFramework::AddIn pointer to the dispatch interface of a Solid Edge addin object that provides another channel of communication between the addin and Solid Edge.
HRESULT OnConnectToEnvironment( BSTR EnvCatID, LPDISPATCH pEnvironment, VARIANT_BOOL* bFirstTime )
EnvCatID- The category identifier of the environment as a string. If the addin is registered as supporting multiple environments, the addin can use the string to determine which environment to which it is being asked to connect.
pEnvironmentSolidEdgeFramework::Environment pointer to the dispatch interface of the environment. bFirstTime- The bFirstTime parameter specifies that a Solid Edge environment is connecting to the addin for the first time. When connecting for the first time, the addin, if necessary, should add any needed user interface elements (for example, buttons). On exiting, Solid Edge will save any such buttons so they can be restored during the next session.
HRESULT OnDisconnection( SeDisconnectMode DisconnectMode )
DisconnectMode- Disconnect mode that indicates what caused Solid Edge to disconnect from the addin. The possible values are:
seDisconnectAtShutdown - Unloading at shutdown.
seDisconnectByUser - Unloading the addin due to a user request.
seDisconnectExternally - Unloading the addin due to an external (programmatic) request.
Getting started
To get started, you will need to create a Visual C++ ATL Project as shown below.

You can check the "Allow merging of proxy/stub code" for convenience.

Now that your project is created, you will want to modify the project properties. By setting the debugging command to Edge.exe, you will be able to debug you addin real-time in Solid Edge.

You will also want to add the "%PROGRAMFILES%\Solid Edge ST\SDK\include" path to your additional include directories setting. This will allow us to bring in the secatids.h include.

Add Class - ATL Simple Object
The next step is to execute the Add Class wizard on the project. You'll need to add an ATL Simple Object to your project. This class will ultimately implement the ISolidEdgeAddIn interface.



stdafx.h
Next, you'll need to modify your stdafx.h to include the SolidEdgeFramework type library. You can add the #import statement at the bottom of stdafx.h as shown below. Note the way that I use #import, the type library information is obtained via the registry. This keeps us from having to define project paths to the type libraries manually. The libid can be extracted using oleview.exe which is found in %VS80COMNTOOLS% for Visual Studio .NET 2005.
#pragma once
#ifndef STRICT
#define STRICT
#endif
#ifndef WINVER #define WINVER 0x0501 #endif
#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif
#ifndef _WIN32_WINDOWS #define _WIN32_WINDOWS 0x0410 #endif
#ifndef _WIN32_IE #define _WIN32_IE 0x0600 #endif
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#include "resource.h"
#include <atlbase.h>
#include <atlcom.h>
#include <initguid.h>
using namespace ATL;
#pragma warning( disable : 4278 )
#pragma warning( disable : 4146 )
#include "secatids.h"
#import "libid:8A7EFA3A-F000-11D1-BDFC-080036B4D502" exclude ("UINT_PTR", "LONG_PTR")
using namespace SolidEdgeFramework;
#pragma warning( default : 4146 )
#pragma warning( default : 4278 )
ExampleAddIn.h
You will need to modify your ExampleAddIn.h to look like the following. Specifically, note the addition of the ISolidEdgeAddIn interface implementation. I've also added a couple of private smart pointers for later use.
#pragma once
#include "resource.h"
#include "CodeProjectExample.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform..."
#endif
class ATL_NO_VTABLE CExampleAddIn :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CExampleAddIn, &CLSID_ExampleAddIn>,
public IExampleAddIn,
public ISolidEdgeAddIn
{
public:
CExampleAddIn()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_EXAMPLEADDIN)
DECLARE_NOT_AGGREGATABLE(CExampleAddIn)
BEGIN_COM_MAP(CExampleAddIn)
COM_INTERFACE_ENTRY(IExampleAddIn)
COM_INTERFACE_ENTRY(ISolidEdgeAddIn)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
private:
SolidEdgeFramework::ApplicationPtr m_pApplication;
SolidEdgeFramework::ISEAddInPtr m_pAddIn;
SolidEdgeFramework::ISEAddInExPtr m_pAddinEx;
public:
STDMETHOD(raw_OnConnection)( THIS_ IDispatch* pAppDispatch, SeConnectMode ConnectMode, SolidEdgeFramework::AddIn* pUnkAddIn );
STDMETHOD(raw_OnConnectToEnvironment)( BSTR EnvironmentCatid, LPDISPATCH pEnvironment, VARIANT_BOOL bFirstTime );
STDMETHOD(raw_OnDisconnection)( THIS_ SeDisconnectMode DisconnectMode );
};
OBJECT_ENTRY_AUTO(__uuidof(ExampleAddIn), CExampleAddIn)
ExampleAddIn.cpp
You will need to modify your ExampleAddIn.cpp to look like the following. I added a bit of skeleton code to demonstrate the usage.
// ExampleAddIn.cpp : Implementation of CExampleAddIn
#include "stdafx.h"
#include "ExampleAddIn.h"
// CExampleAddIn
STDMETHODIMP CExampleAddIn::raw_OnConnection( IDispatch *pAppDispatch, SeConnectMode ConnectMode, AddIn* pAddIn )
{
HRESULT hr = S_OK;
/* Assign smart pointers */
m_pApplication = pAppDispatch;
m_pAddIn = pAddIn;
m_pAddinEx = pAddIn; /* This QueryInterface() will fail on pre ST builds */
// Set the gui version. If the version changed since the last time
// addin was connected, SE will purge any gui related to
// this it and force bFirstTime to VARIANT_TRUE when calling
// OnConnectToEnvironment.
m_pAddIn->GuiVersion = 1;
/* Unremark if you want to hide the addin from addin manager. */
// m_pAddIn->Visible = VARIANT_FALSE;
/* Handle connect mode if required */
switch (ConnectMode)
{
case SolidEdgeFramework::seConnectAtStartup:
break;
case SolidEdgeFramework::seConnectByUser:
break;
case SolidEdgeFramework::seConnectExternally:
break;
}
return hr;
}
STDMETHODIMP CExampleAddIn::raw_OnConnectToEnvironment( BSTR EnvironmentCatid, LPDISPATCH pEnvironment, VARIANT_BOOL bFirstTime )
{
HRESULT hr = S_OK;
CLSID clsidEnv;
CLSIDFromString(EnvironmentCatid, &clsidEnv);
/* If you need to handle a specific environment, do the following. */
if (IsEqualCLSID(clsidEnv, CATID_SEApplication))
{
/* Do something specific for this environment. */
}
return hr;
}
STDMETHODIMP CExampleAddIn::raw_OnDisconnection( SeDisconnectMode DisconnectMode )
{
HRESULT hr = S_OK;
/* Handle disconnect mode if required */
switch (DisconnectMode)
{
case SolidEdgeFramework::seDisconnectAtShutdown:
break;
case SolidEdgeFramework::seDisconnectByUser:
break;
case SolidEdgeFramework::seDisconnectExternally:
break;
}
/* Free smart pointers */
m_pAddIn = NULL;
m_pApplication = NULL;
return hr;
}
ExampleAddIn.rgs
The .rgs registry script gets executed when regsvr32.exe is executed for the .dll. It adds all of the required registry entries that enable Solid Edge to see the addin. Specifically, the Implemented Categories entry is what allows Solid Edge to recognize our .dll as a Solid Edge addin.
For the possible Environment Categories, you can refer to the secatids.h include or the Environment Categories table in this article.
HKCR
{
CodeProjectExample.ExampleAddIn.1 = s 'ExampleAddIn Class'
{
CLSID = s '{B66BA526-53E5-41B1-9620-AB7945F57155}'
}
CodeProjectExample.ExampleAddIn = s 'ExampleAddIn Class'
{
CLSID = s '{B66BA526-53E5-41B1-9620-AB7945F57155}'
CurVer = s 'CodeProjectExample.ExampleAddIn.1'
}
NoRemove CLSID
{
ForceRemove {B66BA526-53E5-41B1-9620-AB7945F57155} = s 'ExampleAddIn Class'
{
val 409 = s 'Code Project Example AddIn'
val AutoConnect = d 1
ProgID = s 'CodeProjectExample.ExampleAddIn.1'
VersionIndependentProgID = s 'CodeProjectExample.ExampleAddIn'
ForceRemove 'Environment Categories'
{
ForceRemove '{26618394-09D6-11d1-BA07-080036230602}' = s 'CATID_SEApplication'
ForceRemove '{BAD41B8D-18FF-42c9-9611-8A00E6921AE8}' = s 'CATID_SEAllDocumentEnvrionments'
}
ForceRemove 'Implemented Categories'
{
ForceRemove '{26B1D2D1-2B03-11D2-B589-080036E8B802}' = s 'CATID_SolidEdgeAddIn'
}
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
Summary
{
val 409 = s 'Code Project Example AddIn Description'
}
val AppID = s '%APPID%'
'TypeLib' = s '{7AA65125-937A-40F5-9F85-44FA48617F46}'
}
}
}
Debugging
Assuming that you're able to compile the code successfully, you can now begin debugging the project and see how the addin works. What I typically do is set a breakpoint on the first line of code in the OnConnection, OnConnectToEnvironment and OnDisconnection methods.
Since we've configured our addin to connect to the CATID_SEApplication environment category, you should hit the OnConnection almost immediately.


Once you're in Solid Edge, you can verify that your addin is correctly registered by opening the Add-In Manager. The Add-In Manager will only display registered Environments that are explicitly set. Since we used the generic CATID_SEAllDocumentEnvrionments in the .rgs registry script, those environments are not displayed. In this example, only the CATID_SEApplication is displayed.

Conclusion
This article was written to target the bare minimum requirements for writing Solid Edge addins. It does not cover other very important topics as those will be discussed in later articles. My goal is to create step-by-step articles that are easy to understand and that build upon each other in the series.
If you've followed the step-by-step instructions in this article, you should not have any trouble getting up to speed quickly. You can also download the attached example which should compile without much effort.
Credits
Siemens PLM Software - Portions of this article are reused from existing Solid Edge SDK documentation.
R.D. Holland - R.D. is a Software Engineer at Siemens PLM Software. He is THE MAN when it comes to Solid Edge addins. I would not have had as good of an understanding of this topic if it were not for R.D.'s help.
John Hilton - John is the owner of Spatial Freedom and is the inventor of the Astroid 3D motion controller. John basically taught me C++ programming so he also deserves credit for the article.
History
2/21/2009 - Initial Release