Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. 3rd Party Software
  4. Windows COM automation Qt and AutoCAD
Forum Updated to NodeBB v4.3 + New Features

Windows COM automation Qt and AutoCAD

Scheduled Pinned Locked Moved Unsolved 3rd Party Software
comqaxbaseqaxobjectdumpcpptlb
14 Posts 5 Posters 3.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • hskoglundH Offline
    hskoglundH Offline
    hskoglund
    wrote on last edited by hskoglund
    #3

    Hi, I think if you're using the dynamicCall function, you should be able to do something simpler, perhaps like:

    myLayer->dynamicCall("AddPoint(double,double,double)",1.0,2.0,3.0);
    

    Note: I don't know anything about AutoCad, this is just a guess :-)

    Edit: googled a bit, maybe this works better:

    QList<QVariant> v3;
    v3.append(1.0);
    v3.append(2.0);
    v3.append(3.0);
    
    myLayer->dynamicCall("AddPoint(QList<QVariant>&)",v3);
    
    1 Reply Last reply
    0
    • N Offline
      N Offline
      nadamus
      wrote on last edited by nadamus
      #4

      @hskoglund said in Windows COM automation Qt and AutoCAd:

      myLayer->dynamicCall

      Thanks for your replay.
      AddPoint requires only one argument to pass. Second approach is similar to what I tried to do.
      Orginal AutoCAD documentation:

      Signature

      VBA:

      RetVal = object.AddPoint(Point)

      object

      Type: Block, ModelSpace, PaperSpace

      The objects this method applies to.

      Point

      Access: Input-only

      Type: Variant (three-element array of doubles)

      The coordinates of the point to be created.
      Return Value (RetVal)

      Type: Point

      The newly created Point object.

      and this is what was generated in header file from tlb file with dumpcpp

      inline AutoCAD::IAcadPoint* IAcadPaperSpace::AddPoint(const QVariant& Point)

      {

      AutoCAD::IAcadPoint* qax_result = 0;
      
      qRegisterMetaType<AutoCAD::IAcadPoint*>("IAcadPoint*", &qax_result);
      
      qRegisterMetaType<AutoCAD::IAcadPoint>("IAcadPoint", qax_result);
      
      void *_a[] = {(void*)&qax_result, (void*)&Point};
      
      qt_metacall(QMetaObject::InvokeMetaMethod, 43, _a);
      
      return qax_result;
      

      }

      Regards
      Adam

      1 Reply Last reply
      0
      • hskoglundH Offline
        hskoglundH Offline
        hskoglund
        wrote on last edited by
        #5

        I see, should be good using the dumpcpp tool, so perhaps try something like:

        QList<QVariant> v3;
        v3.append(1.0);
        v3.append(2.0);
        v3.append(3.0);
        
        QVariant point = QVariant::fromValue(v3);
        myPaperSpaceClass->AddPoint(point);
        

        Or is this what you've tried already?

        1 Reply Last reply
        0
        • N Offline
          N Offline
          nadamus
          wrote on last edited by
          #6

          This approach is not working neither. Same exception is thrown.
          Regards
          Adam

          hskoglundH 1 Reply Last reply
          0
          • N nadamus

            This approach is not working neither. Same exception is thrown.
            Regards
            Adam

            hskoglundH Offline
            hskoglundH Offline
            hskoglund
            wrote on last edited by
            #7

            Ok time to bring out the big guns, i.e. go native and try with the old style SAFEARRAY, say like this:

            SAFEARRAYBOUND rgsabound[1];
            rgsabound[0].lLbound = 0;
            rgsabound[0].cElements = 3;
            
            SAFEARRAY* psa = SafeArrayCreate(VT_R8, 1, rgsabound);
            
            LONG  rgIndex = 0;
            double x = 1.0;
            double y = 2.0;
            double z = 3.0;
            
            SafeArrayPutElement(psa, &rgIndex, &x);
            rgIndex++;
            SafeArrayPutElement(psa, &rgIndex, &y);
            rgIndex++;
            SafeArrayPutElement(psa, &rgIndex, &z);
            
            QVariant point = QVariant::fromValue(psa);
            myPaperSpaceClass->AddPoint(point);
            

            Note: if the QVariant::fromValue fails to compile, consider brute-forcing by changing the void *_a[] declaration inside that function AddPoint() that dumpcpp generated for you, to:

            void *_a[] = {(void*)&qax_result, (void*)&psa};
            

            Also need a way to make psa variable visible in there, perhaps declare it as a global (quick and dirty :-)

            1 Reply Last reply
            2
            • N Offline
              N Offline
              nadamus
              wrote on last edited by nadamus
              #8

              What I did:
              I changed my compiler from MinGW to MSVC and prepared tlh and tli files from the same tlb libraries.
              Then I used SAFEARRAY* wrapped with variant_t
              Now it works, but sill I wonder why it is not working with QList and QVariant. According to documentation it should, as far as I understand it. Maybe I'm missing something? Hard to say.
              Anyway. Thanks for your support. I appreciate it :)
              Code looks like this:
              variant_t AcadCom::SetVariant(SAFEARRAY** wektor, double* koordynaty,unsigned long wymiar)

              {

              if(wymiar>0)
              
              {
              
                  SAFEARRAYBOUND granice;
              
                  granice.lLbound=0;
              
                  granice.cElements=wymiar;
              
                  *wektor=SafeArrayCreate(VT_R8,1,&granice);
              
                  double HUGEP* pdFreq;
              
                  SafeArrayAccessData(*wektor,(void HUGEP* FAR*)&pdFreq);
              
                  for(DWORD i=0;i<wymiar;i++)
              
                  {
              
                      *pdFreq++=koordynaty[i]*skala;
              
                  }
              
                  SafeArrayUnaccessData(*wektor);
              
                  variant_t vKoordynaty;
              
                  vKoordynaty.vt=VT_ARRAY|VT_R8;
              
                  vKoordynaty.parray=*wektor;
              
                  return vKoordynaty;
              
                }
              
              else
              
              {
              
                  return 0;
              
              }
              

              }

              bool AcadCom::SetPunkt(double *koordynaty, QString identyfikator)

              {

              bool sukces=false;
              
              SAFEARRAY *wektor;
              
              IAcadPointPtr pktPtr;
              
              IAcadTextPtr idText;
              
              if(czyPolaczony)
              
              {
              
              
              
                 variant_t vKoordynaty=SetVariant(&wektor,koordynaty);
              
              
              
                 pktPtr=autoCadAppPtr->ActiveDocument->ModelSpace->AddPoint(vKoordynaty);
              
                  if(pktPtr->GetApplication())
              
                  {
              
                     idText=autoCadAppPtr->ActiveDocument->ModelSpace->AddText(identyfikator.toStdString().c_str(),vKoordynaty,0.005*skala);
              
                      if(idText->GetApplication())
              
                          sukces=true;
              
                      DopasujWidok();
              
                  }
              
                  SafeArrayUnlock(wektor);
              
                  SafeArrayDestroy(wektor);
              
                  vKoordynaty.Clear();
              
                  wektor=NULL;
              
              }
              
              return sukces;
              

              Regards
              Adam

              hskoglundH 1 Reply Last reply
              0
              • N nadamus

                What I did:
                I changed my compiler from MinGW to MSVC and prepared tlh and tli files from the same tlb libraries.
                Then I used SAFEARRAY* wrapped with variant_t
                Now it works, but sill I wonder why it is not working with QList and QVariant. According to documentation it should, as far as I understand it. Maybe I'm missing something? Hard to say.
                Anyway. Thanks for your support. I appreciate it :)
                Code looks like this:
                variant_t AcadCom::SetVariant(SAFEARRAY** wektor, double* koordynaty,unsigned long wymiar)

                {

                if(wymiar>0)
                
                {
                
                    SAFEARRAYBOUND granice;
                
                    granice.lLbound=0;
                
                    granice.cElements=wymiar;
                
                    *wektor=SafeArrayCreate(VT_R8,1,&granice);
                
                    double HUGEP* pdFreq;
                
                    SafeArrayAccessData(*wektor,(void HUGEP* FAR*)&pdFreq);
                
                    for(DWORD i=0;i<wymiar;i++)
                
                    {
                
                        *pdFreq++=koordynaty[i]*skala;
                
                    }
                
                    SafeArrayUnaccessData(*wektor);
                
                    variant_t vKoordynaty;
                
                    vKoordynaty.vt=VT_ARRAY|VT_R8;
                
                    vKoordynaty.parray=*wektor;
                
                    return vKoordynaty;
                
                  }
                
                else
                
                {
                
                    return 0;
                
                }
                

                }

                bool AcadCom::SetPunkt(double *koordynaty, QString identyfikator)

                {

                bool sukces=false;
                
                SAFEARRAY *wektor;
                
                IAcadPointPtr pktPtr;
                
                IAcadTextPtr idText;
                
                if(czyPolaczony)
                
                {
                
                
                
                   variant_t vKoordynaty=SetVariant(&wektor,koordynaty);
                
                
                
                   pktPtr=autoCadAppPtr->ActiveDocument->ModelSpace->AddPoint(vKoordynaty);
                
                    if(pktPtr->GetApplication())
                
                    {
                
                       idText=autoCadAppPtr->ActiveDocument->ModelSpace->AddText(identyfikator.toStdString().c_str(),vKoordynaty,0.005*skala);
                
                        if(idText->GetApplication())
                
                            sukces=true;
                
                        DopasujWidok();
                
                    }
                
                    SafeArrayUnlock(wektor);
                
                    SafeArrayDestroy(wektor);
                
                    vKoordynaty.Clear();
                
                    wektor=NULL;
                
                }
                
                return sukces;
                

                Regards
                Adam

                hskoglundH Offline
                hskoglundH Offline
                hskoglund
                wrote on last edited by
                #9

                @nadamus said in Windows COM automation Qt and AutoCAD:
                ..
                Now it works, but sill I wonder why it is not working with QList and QVariant.

                I think the culprit is this line:

                *wektor=SafeArrayCreate(VT_R8,1,&granice);
                

                had it instead been *wektor=SafeArrayCreate(VT_VARIANT,1,&granice); then a QList<QVariant> should've worked.

                Qt's COM support is kind of stuck between a rock (everything is a VARIANT, the Visual Basic COM flavor, functions are called 100% through the IDispatch interface) and a hard place (you can pass native data types like int, doubles etc through COM, the C/C++ COM flavor, functions are called through specialized interfaces based on IUnknown). I remember doing a lot COM coding around the turn of the century, it was really hot then. Nowadays not so much :-)

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  china-Qter
                  wrote on last edited by china-Qter
                  #10

                  This is the modified part,

                  variant_t Form::SetVariant(SAFEARRAY **wektor, double *koordynaty, unsigned long wymiar)
                  {
                  if(wymiar>0)
                  {
                  SAFEARRAYBOUND granice;
                  granice.lLbound=0;
                  granice.cElements=wymiar;
                  *wektor=SafeArrayCreate(VT_R8,1,&granice);

                      double HUGEP* pdFreq;
                      SafeArrayAccessData(*wektor,(void HUGEP* FAR*)&pdFreq);
                      for(DWORD i=0;i<wymiar;i++)
                      {
                          *pdFreq++=koordynaty[i]*skala;
                      }
                      SafeArrayUnaccessData(*wektor);
                      variant_t vKoordynaty;
                      vKoordynaty.vt=VT_ARRAY|VT_R8;
                      vKoordynaty.parray=*wektor;
                      return vKoordynaty;
                  }
                  else
                  {
                      return 0;
                  }
                  

                  }

                  inline AutoCAD::IAcadPoint* IAcadModelSpace::AddPoint(const variant_t & Point)
                  {
                  AutoCAD::IAcadPoint* qax_result = 0;
                  qRegisterMetaTypeAutoCAD::IAcadPoint*("IAcadPoint*", &qax_result);
                  qRegisterMetaTypeAutoCAD::IAcadPoint("IAcadPoint", qax_result);
                  void _a[] = {(void)&qax_result, (void*)&Point};
                  qt_metacall(QMetaObject::InvokeMetaMethod, 42, _a);
                  return qax_result;
                  }

                  call:
                  double ptV[3];
                  ptV[0] = 1000.0;
                  ptV[1] = 1000.0;
                  ptV[2] = 0.0;
                  SAFEARRAY *wektor;
                  variant_t vKoordynaty=SetVariant(&wektor,ptV,3);
                  ModelSpace->AddPoint(vKoordynaty);

                  But it's still wrong:Error calling IDispatch member AddPoint: Exception thrown by server
                  Code : -2147024809
                  Source :
                  Description:
                  Help :
                  Connect to the exception(int,QString,QString,QString) signal to catch this exception

                  J 1 Reply Last reply
                  0
                  • hskoglundH Offline
                    hskoglundH Offline
                    hskoglund
                    wrote on last edited by
                    #11

                    Hi, just checking, in 2019 you used 43:

                    qt_metacall(QMetaObject::InvokeMetaMethod, 43, _a);
                    

                    but this year you used 42:

                    qt_metacall(QMetaObject::InvokeMetaMethod, 42, _a);
                    

                    has AutoCad changed or?

                    1 Reply Last reply
                    0
                    • C china-Qter

                      This is the modified part,

                      variant_t Form::SetVariant(SAFEARRAY **wektor, double *koordynaty, unsigned long wymiar)
                      {
                      if(wymiar>0)
                      {
                      SAFEARRAYBOUND granice;
                      granice.lLbound=0;
                      granice.cElements=wymiar;
                      *wektor=SafeArrayCreate(VT_R8,1,&granice);

                          double HUGEP* pdFreq;
                          SafeArrayAccessData(*wektor,(void HUGEP* FAR*)&pdFreq);
                          for(DWORD i=0;i<wymiar;i++)
                          {
                              *pdFreq++=koordynaty[i]*skala;
                          }
                          SafeArrayUnaccessData(*wektor);
                          variant_t vKoordynaty;
                          vKoordynaty.vt=VT_ARRAY|VT_R8;
                          vKoordynaty.parray=*wektor;
                          return vKoordynaty;
                      }
                      else
                      {
                          return 0;
                      }
                      

                      }

                      inline AutoCAD::IAcadPoint* IAcadModelSpace::AddPoint(const variant_t & Point)
                      {
                      AutoCAD::IAcadPoint* qax_result = 0;
                      qRegisterMetaTypeAutoCAD::IAcadPoint*("IAcadPoint*", &qax_result);
                      qRegisterMetaTypeAutoCAD::IAcadPoint("IAcadPoint", qax_result);
                      void _a[] = {(void)&qax_result, (void*)&Point};
                      qt_metacall(QMetaObject::InvokeMetaMethod, 42, _a);
                      return qax_result;
                      }

                      call:
                      double ptV[3];
                      ptV[0] = 1000.0;
                      ptV[1] = 1000.0;
                      ptV[2] = 0.0;
                      SAFEARRAY *wektor;
                      variant_t vKoordynaty=SetVariant(&wektor,ptV,3);
                      ModelSpace->AddPoint(vKoordynaty);

                      But it's still wrong:Error calling IDispatch member AddPoint: Exception thrown by server
                      Code : -2147024809
                      Source :
                      Description:
                      Help :
                      Connect to the exception(int,QString,QString,QString) signal to catch this exception

                      J Offline
                      J Offline
                      JinCoder
                      wrote on last edited by JinCoder
                      #12
                      This post is deleted!
                      SGaistS 1 Reply Last reply
                      0
                      • J JinCoder

                        This post is deleted!

                        SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        @JinCoder hi and welcome to devnet,

                        Please use English as it is the main forum language. We have a dedicated international sub forum for people to interact in their main language.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        J 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          @JinCoder hi and welcome to devnet,

                          Please use English as it is the main forum language. We have a dedicated international sub forum for people to interact in their main language.

                          J Offline
                          J Offline
                          JinCoder
                          wrote on last edited by
                          #14

                          @SGaist Ok, I saw his user name is "china-Qter", so I used chinese.

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved