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.9k 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
    #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