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