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

Windows COM automation Qt and AutoCAD

Scheduled Pinned Locked Moved Unsolved 3rd Party Software
comqaxbaseqaxobjectdumpcpptlb
14 Posts 5 Posters 4.8k 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