Using the Scripting Interface with C++: Examples

Examples are provided below of using the Scripting Interface with C++ in eCADSTAR Library Editor,eCADSTAR Schematic Editor and eCADSTAR PCB Editor. The procedures are also provided for using Iterator-based and Range-based loops. To download scripting examples, click: Scripting Examples. For a specified design, these provide a list of components and their associated parts. Browse to the C++ folder in the downloaded data.

To Display All Part Properties in a Library

 

           #include <iostream>
              #import "C:\Program Files\eCADSTAR\eCADSTAR 2021.0\bin\eCS_le.exe"

 

              class COMInitializer
              {
              public:
                   COMInitializer()
                   {
                           CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
                   }
                   ~COMInitializer()
                   {
                           CoUninitialize();
                   }
              };

 

              int main(int argc, char* argv[])
              {
                   using  namespace eCSLECOM;

 

                   std::wcout.imbue(std::locale(""));

 

                   if(argc < 2)
                   {
                       return  1;
                   }
                   COMInitializer co;

 

                   // Launch eCADSTAR Library Editor.
                   ILEApplicationPtr app;
                   app.CreateInstance(__uuidof(LEApplication));

 

                   app->OpenDesign(argv[1]);

 

                   ILEPartsPtr parts= app->Library->Parts;

 

                   for(long ic = 1; ic <= parts->Count; ic++)
                   {
                       ILEPartPtr part= part->Item[ic];

 

                       IPropertiesPtr properties = part->Properties;

 

                       for(long ip = 1; ip <= properties->Count; ip++)
                       {
                           IPropertyPtr property = properties->Item[ip];;
                           std::wcout << property->Name << " : " << property->Value << std::endl;
                       }
                   }

 

                   app->Quit();

 

                   return  0;
              }

 

To Display All Sheet Properties in a Schematic Design

 

              #include <iostream>
              #import "C:\Program Files\eCADSTAR\eCADSTAR 2019.0\bin\eCS_scm.exe"

 

              class COMInitializer
              {
              public:
                   COMInitializer()
                   {
                           CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
                   }
                   ~COMInitializer()
                   {
                           CoUninitialize();
                   }
              };

 

              int main(int argc, char* argv[])
              {
                   using  namespace eCSSCHCOM;
                   std::wcout.imbue(std::locale(""));
                   if(argc < 2)
                   {
                       return  1;
                   }
                   COMInitializer co;

 

                   // Launch eCADSTAR Schematic Editor.
                   ISchApplicationPtr app;
                   app.CreateInstance(__uuidof(SchApplication));

 

                   app->OpenDesign(argv[1]);

 

                   ISchSheetsPtr sheets = app->Design->Sheets;
                   for(long is = 1, ns = sheets->Count; is <= ns; ++is)
                   {
                       ISchSheetPtr sheet = sheets->Item[is];
                       sheet->Open();
                       std::wcout << sheet->Number << std::endl;

 

                       IPropertiesPtr properties = sheet->Properties;
                       for(long ip = 1, np = properties->Count; ip <= np; ++ip)
                       {
                           IPropertyPtr property = properties->Item[ip];
                           std::wcout << property->Name << " : " << property->Value << std::endl;
                       }
                       sheet->Close();
                   }

 

                   app->Quit();

 

                   return  0;
              }

 

To Display All Component Properties in a PCB Design

 

              #include <iostream>
              #import "C:\Program Files\eCADSTAR\eCADSTAR 2019.0\bin\eCS_pcb.exe"

 

              class COMInitializer
              {
              public:
                   COMInitializer()
                   {
                           CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
                   }
                   ~COMInitializer()
                   {
                           CoUninitialize();
                   }
              };

 

              int main(int argc, char* argv[])
              {
                   using  namespace eCSPCBCOM;

 

                   std::wcout.imbue(std::locale(""));

 

                   if(argc < 2)
                   {
                       return  1;
                   }
                   COMInitializer co;

 

                   // Launch eCADSTAR PCB Editor.
                   IPCBApplicationPtr app;
                   app.CreateInstance(__uuidof(PCBApplication));

 

                   app->OpenDesign(argv[1]);

 

                   IPCBComponentsPtr components = app->CurrentDesign->Components;

 

                   for(long ic = 1; ic <= components->Count; ic++)
                   {
                       IPCBComponentPtr component = components->Item[ic];

 

                       IPropertiesPtr properties = component->Properties;

 

                       for(long ip = 1; ip <= properties->Count; ip++)
                       {
                           IPropertyPtr property = properties->Item[ip];;
                           std::wcout << property->Name << " : " << property->Value << std::endl;
                       }
                   }

 

                   app->Quit();

 

                   return  0;
              }

 

Using Iterator-based Loops

By default, COM collections are not available in  C++. However, you can define an iterator that wraps IEnumVARIANT, and provides begin and end functions. This enables COM collections to handle the range concept. This is shown in the following example.

 

              template<class IItemPtr>
              class IEnumVARIANT_iterator
              {
              public:
                   using iterator_category = std::forward_iterator_tag;
                   using  value_type = IItemPtr;
                   using  difference_type = std::ptrdiff_t;
                   using pointer = value_type*;
                   using reference = value_type&;

 

                   IEnumVARIANT_iterator() = default;
                   IEnumVARIANT_iterator(IEnumVARIANTPtr p):enumVariant_(p)
                   {
                           operator++();
                   }

 

                   IEnumVARIANT_iterator& operator++()
                   {
                           _variant_t v;
                           ULONG c = 0;
                           if(enumVariant_ && enumVariant_->Next(1, &v, &c) == S_OK)
                           {
                               v.pdispVal->QueryInterface<typename IItemPtr::Interface>(&item_);
                           }
                           else
                           {
                               enumVariant_ = nullptr;
                               item_ =  nullptr;
                           }
                           return *this;
                   }

 

                   operator  bool(){ return  static_cast<bool>(item_); }

 

                   bool  operator==(const IEnumVARIANT_iterator& rhs) const  noexcept { return  item_ == rhs.item_; }
                   bool  operator!=(const IEnumVARIANT_iterator& rhs) const  noexcept { return  item_ != rhs.item_; }

 

                   reference operator*() noexcept { return  item_; }
                   value_type  operator*() const  noexcept { return  item_; }
                   pointer operator->() noexcept { return &item_; }
                   const pointer operator->() const  noexcept { return &item_; }

 

              private:
                   IEnumVARIANTPtr enumVariant_;
                   IItemPtr item_;
              };

 

              template<typename _IIID>
              auto begin(const _com_ptr_t<_IIID>& p)
              {
                   return IEnumVARIANT_iterator<decltype(p->Item[0])>{ p->_NewEnum };
              }

 

              template<typename _IIID>
              auto end(const _com_ptr_t<_IIID>& p)
              {
                   return IEnumVARIANT_iterator<decltype(p->Item[0])>{ nullptr };
              }

 

Using Range-based loops over COM Collections

The following iterator definition allows you to use range-based loops over COM collections.

 

              int main(int argc, char* argv[])
              {
                   using  namespace eCSSCHCOM;

 

                   std::wcout.imbue(std::locale(""));

 

                   if(argc < 2)
                   {
                           return  1;
                   }

 

                   COMInitializer co;

 

                   ISchApplicationPtr app;

 

                   app.CreateInstance(__uuidof(SchApplication));

 

                   app->OpenDesign(argv[1]);

 

                   for(ISchSheetPtr sheet : app->Design->Sheets)
                   {
                           sheet->Open();
                           std::wcout << sheet->Number << std::endl;
                           for(IPropertyPtr property : sheet->Properties)
                           {
                                   std::wcout << property->Name << " : " << property->Value << std::endl;
                           }
                           sheet->Close();
                   }

 

                   app->Quit();

 

                   return  0;
              }