Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QT COM Support For Dual Interface

QT COM Support For Dual Interface

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 2 Posters 996 Views
  • 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.
  • M Offline
    M Offline
    Madhura
    wrote on 2 Jun 2023, 13:34 last edited by
    #1
    1. We have 2 separate projects in solution and we have generated idls and tlbs file from both the project.
    2. Added both the tlbs in client exe ( In other application which uses above TLB ) project
    3. We are calling CoCreateInstance from exe project.
    4. Is there any way to get Queryinterface of Dll class functions from main exe project, Refer below code

    As we gone through the COM architecture there is a process called Dual-Interface.

    In Dual-Interface we can find some macros like

    BEGIN_DUAL_INTERFACE_PART(DualAClick, IDualAClick)
    STDMETHOD(put_text)(THIS_ BSTR newText);
    END_DUAL_INTERFACE_PART(DualAClick)

    BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
    INTERFACE_PART(CAutoClickDoc, DIID_IAClick, Dispatch)
    INTERFACE_PART(CAutoClickDoc, IID_IDualAClick, DualAClick)
    END_INTERFACE_MAP()

    Question:
    Is there any similar Macro / Function / Class will help to implement in QT.

    For above sample MSCV link for reference: link text

    For more details what we actually need is represented with sample below:

    Project.exe
    Class MainClass:Qobject
    {
    Q_OBJECT
    Q_CLASSINFO("ClassID", "{XXXXX}")
    Q_CLASSINFO("InterfaceID", "{XXXXX}")
    Q_CLASSINFO("EventsID", "{XXXXX}")
    public Q_SLOTS:
    bool GetPath();
    }

    From Project.exe we have generated idl and tlb

    Project.dll
    Class SubClass:Qobject
    {
    Q_OBJECT
    Q_CLASSINFO("ClassID", "{XXXXX}")
    Q_CLASSINFO("InterfaceID", "{XXXXX}")
    Q_CLASSINFO("EventsID", "{XXXXX}")
    public Q_SLOTS:
    bool SetPath(Qstring path);
    }

    From Project.dll we have generated idl and tlb

    Client.exe

    Int main()
    {
    CComprt<IMainClass> maincls;
    CComprt<ISubClass > subcls;
    maincls.CocreateInstance(MainClass);
    // Here “maincls” has memory
    Subcls = maincls // not able to query the sub class
    If(Subcls != nullptr)
    Subcls->SetPath(“C:\path”)
    }

    1 Reply Last reply
    0
    • H Offline
      H Offline
      hskoglund
      wrote on 2 Jun 2023, 19:05 last edited by
      #2

      Hi, if you've implemented your COM classes with a Dual interface, that is good news because then you use Qt's COM support in the class QAxObject.

      First, add QT += axcontainer to your .pro file. Then add
      #include <QAxObject> to your .cpp file.

      After that you should be able to avoid doing CoCreateInstance() and instead lean on QAxObject. Here is the proverbial example (interacting with an Excel spreadsheet):

      auto excel     = new QAxObject("Excel.Application");
      auto workbooks = excel->querySubObject("Workbooks");
      auto workbook  = workbooks->querySubObject("Add");
      auto sheets    = workbook->querySubObject("Worksheets");
      // count # of worksheets
      int count = sheets->dynamicCall("Count()").toInt();
      

      And you can still do a QueryInterface on the QAxObject say like this:

      ...
      #include <quuid.h>
      #include <atlbase.h> 
      
      auto excel = new QAxObject("Excel.Application");
      CComPtr<IDispatch> pDispatch;
      excel->queryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
      ...
      
      M 1 Reply Last reply 4 Jun 2023, 05:28
      0
      • H hskoglund
        2 Jun 2023, 19:05

        Hi, if you've implemented your COM classes with a Dual interface, that is good news because then you use Qt's COM support in the class QAxObject.

        First, add QT += axcontainer to your .pro file. Then add
        #include <QAxObject> to your .cpp file.

        After that you should be able to avoid doing CoCreateInstance() and instead lean on QAxObject. Here is the proverbial example (interacting with an Excel spreadsheet):

        auto excel     = new QAxObject("Excel.Application");
        auto workbooks = excel->querySubObject("Workbooks");
        auto workbook  = workbooks->querySubObject("Add");
        auto sheets    = workbook->querySubObject("Worksheets");
        // count # of worksheets
        int count = sheets->dynamicCall("Count()").toInt();
        

        And you can still do a QueryInterface on the QAxObject say like this:

        ...
        #include <quuid.h>
        #include <atlbase.h> 
        
        auto excel = new QAxObject("Excel.Application");
        CComPtr<IDispatch> pDispatch;
        excel->queryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
        ...
        
        M Offline
        M Offline
        Madhura
        wrote on 4 Jun 2023, 05:28 last edited by
        #3

        @hskoglund
        But our requirement is to use only cocreateinstance, Because our
        Project is fully converted to visual studio solution.Is here any way to achieve same process using cocreateinstance ?

        Our client application will be in native C++ basically we use only cocreateinstance for COM-Object

        1 Reply Last reply
        0
        • H Offline
          H Offline
          hskoglund
          wrote on 4 Jun 2023, 09:30 last edited by
          #4

          Hi, a big plus of using Active Qt is that don't have to any CoCreateInstance() yourself. Most of the COM documentation is written before Internet started (in the previous century) so good examples can be hard to find :-(

          I found an old program of mine that queries the system monitor for uptime (it is written for Windows 2000 but should work equally well on Windows 10 or 11) and it does a CoCreateInstance:

          // convert the ProgID of the DLL you want to load to a  CLSID
              CLSID clsid;
              HRESULT hr = CLSIDFromString(L"SysMon.3",&clsid);
              if (FAILED(hr))
                  qFatal("CLSIDFromString() didn't work");
          
          // try to load the DLL
              CComPtr<IUnknown> pUnknown;
              hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(LPVOID*) &pUnknown);
              if (FAILED(hr))
                  qFatal("CoCreateInstance() didn't work");
          

          with Qt it is slightly easier:

           auto qtComObject = new QAxObject("SysMon.3");
          

          either way you load your .COM dll, now you can query into it either via Qt's QAxObject methods or the old way using QueryInterface. If found some old code that asks the .dll for its type info (note: this requires that the COM .dll has a dual interface implementation):

          #include "mainwindow.h"
          #include <QApplication>
          
          #include "qaxobject.h"
          #include "quuid.h"
          #include "qdebug.h"
          #include <atlbase.h>
          
          void partyOnTypeLibrary(CComPtr<ITypeLib> pTypeLib)
          {
          // BSTR to QString converter
              auto bstr2QString = [](BSTR bstr) { return QString::fromUtf16((ushort*) bstr); };
          
          // show type library's doc strings
              CComBSTR bstrName,bstrDocString;
              pTypeLib->GetDocumentation(-1,&bstrName,&bstrDocString,NULL,NULL);
              qDebug() << bstr2QString(bstrName) << bstr2QString(bstrDocString) << ":\n";
          
          // step thru all the type info
              for (UINT u = 0; (u < pTypeLib->GetTypeInfoCount()); ++u)
              {
              // get the iTypeInfo ptr
                  CComPtr<ITypeInfo> pTypeInfo;
                  if FAILED(pTypeLib->GetTypeInfo(u,&pTypeInfo))
                      continue;
          
              // get type flavor and name
                  TYPEKIND typeKind;
                  if FAILED(pTypeLib->GetTypeInfoType(u,&typeKind))
                      continue;
          
                  CComBSTR bstrName;
                  if FAILED(pTypeInfo->GetDocumentation(-1,&bstrName,NULL,NULL,NULL))
                      continue;
                  QString sName = bstr2QString(bstrName);
          
              // get the type attribute
                  TYPEATTR* pTypeAttr;
                  if FAILED(pTypeInfo->GetTypeAttr(&pTypeAttr))
                      continue;
          
              // check the type flavor, we support enums, interfaces and coclasses
                  if (TKIND_ENUM == typeKind)
                  {
                      QString sEnums;
                      for (int v = 0; (v < pTypeAttr->cVars); ++v)
                      {
                          VARDESC* pVarDesc;
                          if FAILED(pTypeInfo->GetVarDesc(v,&pVarDesc))
                              break;
          
                          if (v > 0)
                              sEnums += " ";
                          if (VAR_CONST == pVarDesc->varkind)
                              sEnums += QString::number(pVarDesc->lpvarValue->lVal);
          
                          pTypeInfo->ReleaseVarDesc(pVarDesc);
                      }
          
                      qDebug() << "Enum type:" << sName << sEnums;
                  }
          
                  if (TKIND_INTERFACE == typeKind)
                      qDebug() << "Interface type:" << sName;
          
                  if (TKIND_DISPATCH == typeKind)
                      qDebug() << "IDispatch callable type:" << sName;
          
              // any function descriptors? they usually exist for interfaces and IDispatch
                  for (int f = 0; (f < pTypeAttr->cFuncs); ++f)
                  {
                      FUNCDESC* pFuncDesc;
                      if FAILED(pTypeInfo->GetFuncDesc(f,&pFuncDesc))
                          break;
          
                      if (pFuncDesc->wFuncFlags > 0)
                          continue;   // skip these chaps (boring)
          
                      if (pFuncDesc->invkind > INVOKE_PROPERTYGET)
                          continue;   // skip put and putref properties
          
                  // get the prop/func name and all the arg names
                      QStringList slNames;
                      BSTR aBS[1000];     // 1000 should suffice
                      UINT uNames = 0;
                      if FAILED(pTypeInfo->GetNames(pFuncDesc->memid,aBS,1000,&uNames))
                          break;
          
                      for (uint u = 0; (u < uNames); ++u)
                          slNames.append(bstr2QString(aBS[u]));
          
                      QString sKind = "Property";
                      if (pFuncDesc->invkind == INVOKE_FUNC)
                          sKind = "Function";
                      QString sPropOrFuncName = slNames.first();
                      slNames.removeFirst();
          
                      qDebug() << sKind << sPropOrFuncName << slNames;
                  }
                  qDebug() << "";
          
              // we only care about coclasses at this point
                  if (TKIND_COCLASS != typeKind)
                      continue;
          
                  qDebug() << "CoClass:" << bstr2QString(bstrName) << ":";
          
              // step through the implemented types for this coclass
                  for (int i = 0; (i < pTypeAttr->cImplTypes); ++i)
                  {
                      HREFTYPE hRefType;
                      if FAILED(pTypeInfo->GetRefTypeOfImplType(i,&hRefType))
                          continue;
          
                      CComPtr<ITypeInfo> pRefTypeInfo;
                      if FAILED(pTypeInfo->GetRefTypeInfo(hRefType,&pRefTypeInfo))
                          continue;
          
                      CComBSTR bstrInterfaceName;
                      if FAILED(pRefTypeInfo->GetDocumentation(-1,&bstrInterfaceName,NULL,NULL,NULL))
                          continue;
          
                      qDebug() << "        " << bstr2QString(bstrInterfaceName);
                  }
              }
          }
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
          /*
          // convert to CLSID
              CLSID clsid;
              HRESULT hr = CLSIDFromString(L"SysMon.3",&clsid);
              if (FAILED(hr))
                  qFatal("CLSIDFromString() didn't work");
          
          // trying to load the DLL
              CComPtr<IUnknown> pUnknown;
              hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(LPVOID*) &pUnknown);
              if (FAILED(hr))
                  qFatal("CoCreateInstance() didn't work");
          */
          .// here we use Qt's QAxObject
              auto qtComObject = new QAxObject("SysMon.3");
          
              CComPtr<IDispatch> pDispatch;
          //    pUnknown->QueryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
              qtComObject->queryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
              if (nullptr == pDispatch)
                  qFatal("Error: an IDispatch interface was not found.");
          
          // get the ITypeInfo ptr
              UINT uTypeInfo;
              HRESULT hr = pDispatch->GetTypeInfoCount(&uTypeInfo);
              if (FAILED(hr) || (uTypeInfo < 1))
                  qFatal("Sorry, could not locate any type information");
              if (1 != uTypeInfo)
                  qFatal("Expected GetTypeInfoCount() to return 1");
          
              CComPtr<ITypeInfo> pTypeInfo;
              if FAILED(pDispatch->GetTypeInfo(0,LOCALE_SYSTEM_DEFAULT,&pTypeInfo))
                  qFatal("Error: GetTypeInfo() failed");
          
          // ok have ITypeInfo, use it to get the ITypeLib
              CComPtr<ITypeLib> pTypeLib;
              UINT uTypeInfoIndex;
              if FAILED(pTypeInfo->GetContainingTypeLib(&pTypeLib,&uTypeInfoIndex))
                  qFatal("Error: GetContainingTypeLib() failed");
          
          // party on this type library
             partyOnTypeLibrary(pTypeLib);
          }
          
          M 1 Reply Last reply 6 Jun 2023, 07:17
          0
          • M Offline
            M Offline
            Madhura
            wrote on 6 Jun 2023, 04:56 last edited by
            #5

            Hello,
            Thank for the support. We are using this sample and exposing the API inside C++ application.
            Can you suggest the use query interface or "CoCreateInstance" inside C++ application.

            1 Reply Last reply
            0
            • H hskoglund
              4 Jun 2023, 09:30

              Hi, a big plus of using Active Qt is that don't have to any CoCreateInstance() yourself. Most of the COM documentation is written before Internet started (in the previous century) so good examples can be hard to find :-(

              I found an old program of mine that queries the system monitor for uptime (it is written for Windows 2000 but should work equally well on Windows 10 or 11) and it does a CoCreateInstance:

              // convert the ProgID of the DLL you want to load to a  CLSID
                  CLSID clsid;
                  HRESULT hr = CLSIDFromString(L"SysMon.3",&clsid);
                  if (FAILED(hr))
                      qFatal("CLSIDFromString() didn't work");
              
              // try to load the DLL
                  CComPtr<IUnknown> pUnknown;
                  hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(LPVOID*) &pUnknown);
                  if (FAILED(hr))
                      qFatal("CoCreateInstance() didn't work");
              

              with Qt it is slightly easier:

               auto qtComObject = new QAxObject("SysMon.3");
              

              either way you load your .COM dll, now you can query into it either via Qt's QAxObject methods or the old way using QueryInterface. If found some old code that asks the .dll for its type info (note: this requires that the COM .dll has a dual interface implementation):

              #include "mainwindow.h"
              #include <QApplication>
              
              #include "qaxobject.h"
              #include "quuid.h"
              #include "qdebug.h"
              #include <atlbase.h>
              
              void partyOnTypeLibrary(CComPtr<ITypeLib> pTypeLib)
              {
              // BSTR to QString converter
                  auto bstr2QString = [](BSTR bstr) { return QString::fromUtf16((ushort*) bstr); };
              
              // show type library's doc strings
                  CComBSTR bstrName,bstrDocString;
                  pTypeLib->GetDocumentation(-1,&bstrName,&bstrDocString,NULL,NULL);
                  qDebug() << bstr2QString(bstrName) << bstr2QString(bstrDocString) << ":\n";
              
              // step thru all the type info
                  for (UINT u = 0; (u < pTypeLib->GetTypeInfoCount()); ++u)
                  {
                  // get the iTypeInfo ptr
                      CComPtr<ITypeInfo> pTypeInfo;
                      if FAILED(pTypeLib->GetTypeInfo(u,&pTypeInfo))
                          continue;
              
                  // get type flavor and name
                      TYPEKIND typeKind;
                      if FAILED(pTypeLib->GetTypeInfoType(u,&typeKind))
                          continue;
              
                      CComBSTR bstrName;
                      if FAILED(pTypeInfo->GetDocumentation(-1,&bstrName,NULL,NULL,NULL))
                          continue;
                      QString sName = bstr2QString(bstrName);
              
                  // get the type attribute
                      TYPEATTR* pTypeAttr;
                      if FAILED(pTypeInfo->GetTypeAttr(&pTypeAttr))
                          continue;
              
                  // check the type flavor, we support enums, interfaces and coclasses
                      if (TKIND_ENUM == typeKind)
                      {
                          QString sEnums;
                          for (int v = 0; (v < pTypeAttr->cVars); ++v)
                          {
                              VARDESC* pVarDesc;
                              if FAILED(pTypeInfo->GetVarDesc(v,&pVarDesc))
                                  break;
              
                              if (v > 0)
                                  sEnums += " ";
                              if (VAR_CONST == pVarDesc->varkind)
                                  sEnums += QString::number(pVarDesc->lpvarValue->lVal);
              
                              pTypeInfo->ReleaseVarDesc(pVarDesc);
                          }
              
                          qDebug() << "Enum type:" << sName << sEnums;
                      }
              
                      if (TKIND_INTERFACE == typeKind)
                          qDebug() << "Interface type:" << sName;
              
                      if (TKIND_DISPATCH == typeKind)
                          qDebug() << "IDispatch callable type:" << sName;
              
                  // any function descriptors? they usually exist for interfaces and IDispatch
                      for (int f = 0; (f < pTypeAttr->cFuncs); ++f)
                      {
                          FUNCDESC* pFuncDesc;
                          if FAILED(pTypeInfo->GetFuncDesc(f,&pFuncDesc))
                              break;
              
                          if (pFuncDesc->wFuncFlags > 0)
                              continue;   // skip these chaps (boring)
              
                          if (pFuncDesc->invkind > INVOKE_PROPERTYGET)
                              continue;   // skip put and putref properties
              
                      // get the prop/func name and all the arg names
                          QStringList slNames;
                          BSTR aBS[1000];     // 1000 should suffice
                          UINT uNames = 0;
                          if FAILED(pTypeInfo->GetNames(pFuncDesc->memid,aBS,1000,&uNames))
                              break;
              
                          for (uint u = 0; (u < uNames); ++u)
                              slNames.append(bstr2QString(aBS[u]));
              
                          QString sKind = "Property";
                          if (pFuncDesc->invkind == INVOKE_FUNC)
                              sKind = "Function";
                          QString sPropOrFuncName = slNames.first();
                          slNames.removeFirst();
              
                          qDebug() << sKind << sPropOrFuncName << slNames;
                      }
                      qDebug() << "";
              
                  // we only care about coclasses at this point
                      if (TKIND_COCLASS != typeKind)
                          continue;
              
                      qDebug() << "CoClass:" << bstr2QString(bstrName) << ":";
              
                  // step through the implemented types for this coclass
                      for (int i = 0; (i < pTypeAttr->cImplTypes); ++i)
                      {
                          HREFTYPE hRefType;
                          if FAILED(pTypeInfo->GetRefTypeOfImplType(i,&hRefType))
                              continue;
              
                          CComPtr<ITypeInfo> pRefTypeInfo;
                          if FAILED(pTypeInfo->GetRefTypeInfo(hRefType,&pRefTypeInfo))
                              continue;
              
                          CComBSTR bstrInterfaceName;
                          if FAILED(pRefTypeInfo->GetDocumentation(-1,&bstrInterfaceName,NULL,NULL,NULL))
                              continue;
              
                          qDebug() << "        " << bstr2QString(bstrInterfaceName);
                      }
                  }
              }
              
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
              /*
              // convert to CLSID
                  CLSID clsid;
                  HRESULT hr = CLSIDFromString(L"SysMon.3",&clsid);
                  if (FAILED(hr))
                      qFatal("CLSIDFromString() didn't work");
              
              // trying to load the DLL
                  CComPtr<IUnknown> pUnknown;
                  hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(LPVOID*) &pUnknown);
                  if (FAILED(hr))
                      qFatal("CoCreateInstance() didn't work");
              */
              .// here we use Qt's QAxObject
                  auto qtComObject = new QAxObject("SysMon.3");
              
                  CComPtr<IDispatch> pDispatch;
              //    pUnknown->QueryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
                  qtComObject->queryInterface(QUuid(IID_IDispatch),(void**) &pDispatch);
                  if (nullptr == pDispatch)
                      qFatal("Error: an IDispatch interface was not found.");
              
              // get the ITypeInfo ptr
                  UINT uTypeInfo;
                  HRESULT hr = pDispatch->GetTypeInfoCount(&uTypeInfo);
                  if (FAILED(hr) || (uTypeInfo < 1))
                      qFatal("Sorry, could not locate any type information");
                  if (1 != uTypeInfo)
                      qFatal("Expected GetTypeInfoCount() to return 1");
              
                  CComPtr<ITypeInfo> pTypeInfo;
                  if FAILED(pDispatch->GetTypeInfo(0,LOCALE_SYSTEM_DEFAULT,&pTypeInfo))
                      qFatal("Error: GetTypeInfo() failed");
              
              // ok have ITypeInfo, use it to get the ITypeLib
                  CComPtr<ITypeLib> pTypeLib;
                  UINT uTypeInfoIndex;
                  if FAILED(pTypeInfo->GetContainingTypeLib(&pTypeLib,&uTypeInfoIndex))
                      qFatal("Error: GetContainingTypeLib() failed");
              
              // party on this type library
                 partyOnTypeLibrary(pTypeLib);
              }
              
              M Offline
              M Offline
              Madhura
              wrote on 6 Jun 2023, 07:17 last edited by
              #6

              @hskoglund
              We are having 2 different tlbs and in this case both are not able to communicate while using queryinterface it returns NULL

              Kindly refer above sample as we provided.

              1 Reply Last reply
              0
              • H Offline
                H Offline
                hskoglund
                wrote on 6 Jun 2023, 08:17 last edited by
                #7

                Hi, I looked at the sample you mentioned "TN065: Dual-Interface Support for OLE Automation Servers"
                However, this sample is from the previous century.
                To get it running ok you need Microsoft Visual Studio 2008 or earlier, later versions of Visual Studio might not compile it correctly.
                It is written 100% in MFC not Qt so how to make this sample work is not a question for this forum I think :-(

                M 1 Reply Last reply 6 Jun 2023, 10:08
                1
                • H hskoglund
                  6 Jun 2023, 08:17

                  Hi, I looked at the sample you mentioned "TN065: Dual-Interface Support for OLE Automation Servers"
                  However, this sample is from the previous century.
                  To get it running ok you need Microsoft Visual Studio 2008 or earlier, later versions of Visual Studio might not compile it correctly.
                  It is written 100% in MFC not Qt so how to make this sample work is not a question for this forum I think :-(

                  M Offline
                  M Offline
                  Madhura
                  wrote on 6 Jun 2023, 10:08 last edited by
                  #8

                  @hskoglund

                  Is there any thing we need to add in (Project.exe) and another project (project.dll) to link each other and I can queryinterface from project.exe to get project.dll functions.

                  where project.exe and project.dll are different projects.

                  hskoglund : (note: this requires that the COM .dll has a dual interface implementation):

                  As you mentioned is there any sample we can check how to write a QT-COM in dual interface implementation.

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    hskoglund
                    wrote on 6 Jun 2023, 10:23 last edited by
                    #9

                    If you use Qt to develop a COM app, then you always get a dual interface implementation for free (it's built-in).
                    There are some examples available, to get started check the COM App Example.
                    .

                    M 1 Reply Last reply 6 Jun 2023, 11:30
                    0
                    • H hskoglund
                      6 Jun 2023, 10:23

                      If you use Qt to develop a COM app, then you always get a dual interface implementation for free (it's built-in).
                      There are some examples available, to get started check the COM App Example.
                      .

                      M Offline
                      M Offline
                      Madhura
                      wrote on 6 Jun 2023, 11:30 last edited by
                      #10

                      @hskoglund

                      Yes we have created the QT-COM sample from QT documentation.from refrence link : ActiveQT COM app

                      We are able to connect main.exe and able to call its classes using tlb.

                      We have new tlb generated from different project and need to Queryinterface this new tlb (Call functions ) from our exe.

                      1 Reply Last reply
                      0
                      • H Offline
                        H Offline
                        hskoglund
                        wrote on 6 Jun 2023, 13:24 last edited by
                        #11

                        Please convert all your COM projects to Qt, then you will never have to do any calls to CoCreateInstance() and QueryInterface().

                        M 1 Reply Last reply 6 Jun 2023, 14:58
                        0
                        • H hskoglund
                          6 Jun 2023, 13:24

                          Please convert all your COM projects to Qt, then you will never have to do any calls to CoCreateInstance() and QueryInterface().

                          M Offline
                          M Offline
                          Madhura
                          wrote on 6 Jun 2023, 14:58 last edited by
                          #12

                          @hskoglund

                          @hskoglund : Qt to develop a COM app, then you always get a dual interface implementation for free

                          As you mentioned dual interface is automatically implementes in QT.

                          Is there any mapping done between the classes, Is there any macros available or any other way we can do it ?

                          In Microsoft there are some macro which will help us to map the classes : "BEGIN_INTERFACE_MAP"

                          BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
                          INTERFACE_PART(CAutoClickDoc, DIID_IAClick, Dispatch)
                          INTERFACE_PART(CAutoClickDoc, IID_IDualAClick, DualAClick)
                          END_INTERFACE_MAP()

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            hskoglund
                            wrote on 6 Jun 2023, 15:43 last edited by
                            #13

                            Hi, the most important macros are QAXFACTORY_BEGIN, QAXCLASS and QAXTYPE.
                            You can find them inside the COM App example.

                            M 1 Reply Last reply 7 Jun 2023, 08:16
                            0
                            • H hskoglund
                              6 Jun 2023, 15:43

                              Hi, the most important macros are QAXFACTORY_BEGIN, QAXCLASS and QAXTYPE.
                              You can find them inside the COM App example.

                              M Offline
                              M Offline
                              Madhura
                              wrote on 7 Jun 2023, 08:16 last edited by
                              #14

                              @hskoglund
                              In C++ COM we have "BEGIN_INTERFACE_MAP" below is one example:

                              BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
                              INTERFACE_PART(CAutoClickDoc, DIID_IAClick, Dispatch)
                              INTERFACE_PART(CAutoClickDoc, IID_IDualAClick, DualAClick)
                              END_INTERFACE_MAP()

                              Here CDocument and DualAClick both are different projects, not related to each other.

                              But using BEGIN_INTERFACE_MAP macro, the client project can access DualAClick by QueryInterface on CDocument.

                              For e.g.
                              CComPtr<CDocument> cDoc;
                              CoCreateInstance(cDoc);
                              DualAClick pDAC = cDoc.QueryInterface (IDualAClick);

                              We have used below macro which will provide all data in single idl and tlb not for separate idl and tlb.

                              QAXFACTORY_BEGIN("{UUID}", "{UUID}")
                              QAXCLASS(MainClass)
                              QAXTYPE(SubClass)
                              QAXFACTORY_END()

                              Is there any Macro similar to BEGIN_INTERFACE_MAP in QT.

                              1 Reply Last reply
                              0
                              • H Offline
                                H Offline
                                hskoglund
                                wrote on 7 Jun 2023, 09:03 last edited by
                                #15

                                Yes that is the QAXFACTORY_BEGIN() macro.

                                1 Reply Last reply
                                0

                                9/15

                                6 Jun 2023, 10:23

                                • Login

                                • Login or register to search.
                                9 out of 15
                                • First post
                                  9/15
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved