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.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.
  • 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