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
Qt 6.11 is out! See what's new in the release blog

Windows COM automation Qt and AutoCAD

Scheduled Pinned Locked Moved Unsolved 3rd Party Software
comqaxbaseqaxobjectdumpcpptlb
14 Posts 5 Posters 7.1k 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.
  • N Offline
    N Offline
    nadamus
    wrote on last edited by nadamus
    #2

    @nadamus said in Windows COM automation Qt and AutoCAd:

    OK
    My research shows that code most probably means : 2147024809 ERROR_INVALID_PARAMENTER - E_INVALIDARG
    So most probably it connects with sending these coordinates with list of Qvariants. Anyone can point me a direction where look for solution?
    Regards
    Adam

    1 Reply Last reply
    0
    • 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