Results 1 to 16 of 16

Thread: ActiveX | from MFC to Qt5

  1. #1
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Question ActiveX | from MFC to Qt5

    I bought Fingerprint reader ZK7500, it SDK is written in MFC. I want to remake it to Qt.

    1) to code
    Qt Code:
    1. QAxWidget *ax = new QAxWidget();
    2. ax->setControl(QString::fromUtf8("{CA69969C-2F27-41D3-954D-A48B941C3BA7}"));
    To copy to clipboard, switch view to plain text mode 
    I received a warning
    Qt Code:
    1. QAxBase: Unhandled type LPSTR
    To copy to clipboard, switch view to plain text mode 

    This is critical?

    2) at MFC inbound events handled as follows:
    Qt Code:
    1. BEGIN_EVENTSINK_MAP(CDemoDlg, CDialog)
    2. //{{AFX_EVENTSINK_MAP(CDemoDlg)
    3. ON_EVENT(CDemoDlg, IDC_ZKFPENGX2, 8 /* OnImageReceived */, OnOnImageReceivedZkfpengx2, VTS_PBOOL)
    4. ON_EVENT(CDemoDlg, IDC_ZKFPENGX2, 10 /* OnCapture */, OnOnCaptureZkfpengx2, VTS_BOOL VTS_VARIANT)
    5. ON_EVENT(CDemoDlg, IDC_ZKFPENGX2, 9 /* OneEnroll */, OnOnEnrollZkfpengx2, VTS_BOOL VTS_VARIANT)
    6. ON_EVENT(CDemoDlg, IDC_ZKFPENGX2, 5 /* OnFeatureInfo */, OnOnFeatureInfoZkfpengx2, VTS_I4)
    7. //}}AFX_EVENTSINK_MAP
    8. END_EVENTSINK_MAP()
    To copy to clipboard, switch view to plain text mode 

    How to do it on Qt? I have not found *.TLB file with definitions of functions.

    3) I have many functions generated by MFC Wizard such as:
    Qt Code:
    1. void SaveJPG(LPCTSTR FileName)
    2. {
    3. static BYTE parms[] = VTS_BSTR ;
    4. InvokeHelper(0x18, DISPATCH_METHOD, VT_EMPTY, NULL, parms, FileName);
    5. }
    6. long InitEngine()
    7. {
    8. long result;
    9. InvokeHelper(0x1a, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
    10. return result;
    11. }
    12. ...
    To copy to clipboard, switch view to plain text mode 

    I found this topic, but did not work out. How it correctly to remake to Qt.

    Sorry for my Google Translate.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    Maybe check if the vendor has a real SDK, one that does not require any specific UI, at least not one abandoned years ago.

    Cheers,
    _

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    I have not found *.TLB file with definitions of functions.
    You can #import (using MSVC) the DLL file, and it will create the .tli and .tlh files with the interface information. See this.

    That might be enough to get you started wrapping the interface in Qt ActiveX methods calls.

  4. #4
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    Thanks for you answer.

    I'm found interface information with help Windows tool OLEVIEW.EXE (open only with administrator rights). In the branch Type Libraries found my lib.

    My solutions:

    1)

    Qt Code:
    1. class CZKFPEngX : public QAxObject
    2. {
    3. Q_OBJECT
    4. public:
    5. CZKFPEngX()
    6. {
    7. setControl(QString::fromUtf8("{CA69969C-2F27-41D3-954D-A48B941C3BA7}"));
    8. connect(this,SIGNAL(exception(int,QString,QString,QString)),this,SLOT(slotException(int,QString,QString,QString)));
    9. }
    10. ...
    11. };
    To copy to clipboard, switch view to plain text mode 


    2)
    Qt Code:
    1. CZKFPEngX zkfpEng;
    2. connect(&zkfpEng,SIGNAL(OnImageReceived(bool&)), SLOT(imageReceived(bool&)));
    3. connect(&zkfpEng,SIGNAL(OnEnroll(bool,QVariant)), SLOT(enroll(bool,QVariant)));
    4. connect(&zkfpEng,SIGNAL(OnCapture(bool,QVariant)), SLOT(capture(bool,QVariant)));
    5. connect(&zkfpEng,SIGNAL(OnFeatureInfo(int)), SLOT(featureInfo(int)));
    To copy to clipboard, switch view to plain text mode 
    3)

    Qt Code:
    1. void SaveJPG(QString FileName)
    2. {
    3. dynamicCall("SaveJPG(const QString&)",FileName);
    4. }
    5. int InitEngine()
    6. {
    7. int result = dynamicCall("InitEngine()").toInt();
    8. return result;
    9. }
    To copy to clipboard, switch view to plain text mode 

    New question
    4)
    I have method in CZKFPEngX:
    Qt Code:
    1. bool GetFingerImage(QVariant& AFingerImage)
    2. {
    3. //bool result;
    4. //static BYTE parms[] = VTS_PVARIANT ;
    5. //InvokeHelper(0x2e, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, AFingerImage);
    6. //return result;
    7.  
    8. bool result = dynamicCall("GetFingerImage(QVariant&)",AFingerImage).toBool(); //result is true, if finger was captured
    9. return result;
    10. }
    To copy to clipboard, switch view to plain text mode 

    When i'm invoke it from my dialog class:
    Qt Code:
    1. void CDemoDlg::test()
    2. {
    3. QVariant image;
    4. qDebug() << image.isNull();
    5. qDebug() << zkfpEng.GetFingerImage(image);
    6. qDebug() << image.isNull();
    7. QImage img = image.value<QImage>();
    8. if(!img.save("image.bmp","BMP"))
    9. qDebug() << "some error";
    10. }
    To copy to clipboard, switch view to plain text mode 
    at console:
    Qt Code:
    1. true
    2. true
    3. true
    4. some error
    To copy to clipboard, switch view to plain text mode 

    i.e. object object image is not written to by reference. With other similar methods the same situation. What am I doing wrong? Thanks.

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    A COM VARIANT is not a Qt QVariant. You can't pass a Qt QVariant by reference to a COM Dispatch function that expects a COM VARIANT pointer, which is what the COM method signature you have in the comment in GetFingerImage() is telling you.

    You will have to google some more for what a COM VARIANT really looks like and whether Qt's ActiveX module offers any conversion between them.

  6. #6
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    But at docs says:
    COM type___Qt property___in-parameter___out-parameter
    VARIANT___type-dependent___const QVariant&___QVariant&

    and this COM code:

    Qt Code:
    1. dispinterface IControl
    2. {
    3. properties:
    4. methods:
    5. [id(4)] int fillList([in, out] SAFEARRAY(VARIANT) *list);
    6. };
    To copy to clipboard, switch view to plain text mode 

    at Qt:
    Qt Code:
    1. QList<QVariant> varlist;
    2. QList<QVariant> parameters;
    3. parameters << QVariant(varlist);
    4. int n = object.dynamicCall("fillList(QList<QVariant>&)", parameters).toInt();
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    OK, it looks like the Qt Ax module does handle QVariant <-> VTS_PVARIANT conversion correctly. Do you know for certain that the reader creates something that can be converted to a QImage?

    Your qDebug() statements seem to say that even though the dynamicCall seems to succeed, the QVariant is still uninitialized.

    Try initializing the QVariant to a type before passing it in. I seem to remember from my ancient days in COM-land that this might be necessary in some cases.

    Qt Code:
    1. void CDemoDlg::test()
    2. {
    3. QVariant image( QVariant::Image ); // or QVariant::Bitmap or QVariant::Pixmap or QVariant::ByteArray
    4. qDebug() << image.isNull();
    5. qDebug() << zkfpEng.GetFingerImage(image);
    6. qDebug() << image.isNull();
    7. QImage img = image.value<QImage>();
    8. if(!img.save("image.bmp","BMP"))
    9. qDebug() << "some error";
    10. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    @#$%&,
    QVariant QAxBase::dynamicCall(const char * function, const QVariant & var1 = QVariant(), ...)

    need overload dynamicCall(const char * function, QList<QVariant> & vars)

    for this method it works:
    Qt Code:
    1. int IdentificationInFPCacheDB(int fpcHandle, QVariant pVerTemplate, int& Score, int& ProcessedFPNumber)
    2. {
    3. QList<QVariant> var;
    4. var << QVariant(fpcHandle) << pVerTemplate << QVariant(Score) << QVariant(ProcessedFPNumber);
    5. int result = dynamicCall("IdentificationInFPCacheDB(int,QVariant,int&,int&)",var).toInt();
    6. Score = var.at(2).toInt();
    7. ProcessedFPNumber = var.at(3).toInt();
    8. return result;
    9. }
    To copy to clipboard, switch view to plain text mode 

    but with QVariant still not working...

  9. #9
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    Try invoke directly through interface:

    Qt Code:
    1. class CZKFPEngX : public QAxObject
    2. {
    3. Q_OBJECT
    4. IDispatch *iface;
    5.  
    6. public:
    7. CZKFPEngX()
    8. {
    9. setControl(QString::fromUtf8("{CA69969C-2F27-41D3-954D-A48B941C3BA7}"));
    10. connect(this,SIGNAL(exception(int,QString,QString,QString)),this,SLOT(slotException(int,QString,QString,QString)));
    11.  
    12. iface = 0;
    13. QUuid id(QString::fromUtf8("{161A8D2D-3DDE-4744-BA38-08F900D10D6D}"));
    14. queryInterface(id,(void **)&iface);
    15. if (iface)
    16. {
    17. qDebug() << "Interface is loaded";
    18. }
    19. }
    20. ...
    21. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. int GetFingerImage(VARIANT* AFingerImage)
    2. {
    3. //BOOL result;
    4. //static BYTE parms[] = VTS_PVARIANT;
    5. //InvokeHelper(0x2e, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, AFingerImage);
    6. //return result;
    7.  
    8. int result = -1;
    9. DISPPARAMS pDispParams;
    10. VARIANTARG vArg[1];
    11. pDispParams.cArgs = 1;
    12. pDispParams.cNamedArgs = 0;
    13. pDispParams.rgdispidNamedArgs = 0;
    14. pDispParams.rgvarg = vArg;
    15. VariantInit(&pDispParams.rgvarg[0]);
    16. pDispParams.rgvarg[0].vt = VT_VARIANT | VT_BYREF;
    17. pDispParams.rgvarg[0].pvarVal = AFingerImage;
    18.  
    19. VARIANT pVarResult;
    20. EXCEPINFO pExcepInfo;
    21. UINT puArgErr = (UINT)-1;
    22. qDebug() << iface->Invoke(0x2e, IID_NULL, 0, DISPATCH_METHOD, &pDispParams, &pVarResult, &pExcepInfo, &puArgErr);
    23. qDebug() << pExcepInfo.bstrDescription
    24. << pExcepInfo.bstrHelpFile
    25. << pExcepInfo.bstrSource
    26. << pExcepInfo.dwHelpContext
    27. << pExcepInfo.pfnDeferredFillIn
    28. << pExcepInfo.scode
    29. << pExcepInfo.wCode;
    30.  
    31. result = pVarResult.boolVal;
    32.  
    33. return result;
    34. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void CDemoDlg::test()
    2. {
    3. VARIANT *image = new VARIANT;
    4. qDebug() << zkfpEng.GetFingerImage(image);
    5. }
    To copy to clipboard, switch view to plain text mode 

    at console:
    Qt Code:
    1. Interface is loaded
    2. -2147352567 //HRESULT of Invoke
    3. 0xb44c0c 0x0 0xb37774 0 false -2147418113 0 //exception info
    4. -1 //result
    To copy to clipboard, switch view to plain text mode 

    defines at winerror.h:
    -2147352567 ~ DISP_E_EXCEPTION
    -2147418113 ~ E_UNEXPECTED

    Where is mistake? Thanks.

  10. #10
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    Qt Code:
    1. int result;
    2. DISPPARAMS pDispParams;
    3. VARIANTARG vArg[1];
    4. pDispParams.cArgs = 1;
    5. pDispParams.cNamedArgs = 0;
    6. pDispParams.rgdispidNamedArgs = 0;
    7. pDispParams.rgvarg = vArg;
    8. VariantInit(&pDispParams.rgvarg[0]);
    9. pDispParams.rgvarg[0].vt = VT_VARIANT | VT_BYREF;
    10. pDispParams.rgvarg[0].pvarVal = AFingerImage;
    11.  
    12. VARIANT pVarResult;
    13. EXCEPINFO pExcepInfo;
    14. UINT puArgErr = (UINT)0;
    15.  
    16. HRESULT hr = iface->Invoke(0x2e, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &pDispParams, &pVarResult, &pExcepInfo, &puArgErr);
    To copy to clipboard, switch view to plain text mode 

    seems to work
    hr = S_OK

    variant vartype:
    Qt Code:
    1. qDebug() << AFingerImage.vt; //8209 ~ VT_ARRAY|VT_UI1
    To copy to clipboard, switch view to plain text mode 

    How get BMP format image from AFingerImage?

  11. #11
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    I think I keep a blog
    It's work now:
    Qt Code:
    1. long iLBound, iUBound;
    2. char * data;
    3. SafeArrayGetLBound(AFingerImage.parray, AFingerImage.parray->cDims, &iLBound);
    4. SafeArrayGetUBound(AFingerImage.parray, AFingerImage.parray->cDims, &iUBound);
    5. SafeArrayAccessData(AFingerImage.parray,(void**)(&data));
    6. long sz = iUBound - iLBound + 1;
    7. QByteArray ba = QByteArray::fromRawData(data,sz);
    8. FPImage.loadFromData(ba);
    9. SafeArrayUnaccessData(AFingerImage.parray);
    To copy to clipboard, switch view to plain text mode 

  12. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    Isn't COM fun?

  13. #13
    Join Date
    Oct 2015
    Location
    Saint-Petersburg, Russia
    Posts
    10
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: ActiveX | from MFC to Qt5

    that's horrible

  14. #14
    Join Date
    Dec 2018
    Posts
    7
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    hey, i know this is old but what Guuid did you use to get the iface here and where did you get it?

    Qt Code:
    1. iface = 0;
    2. QUuid id(QString::fromUtf8("{161A8D2D-3DDE-4744-BA38-08F900D10D6D}"));
    3. queryInterface(id,(void **)&iface);
    4. if (iface)
    To copy to clipboard, switch view to plain text mode 

  15. #15
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    what Guuid did you use to get the iface here and where did you get it?
    It's probably the IDispatch GUID for the fingerprint reader COM control, and as he said earlier in the thread, he got it by examining the COM DLL using the OLEVIEW utility from Microsoft. As I said also, you can retrieve the same information by using #import in your code to import the COM DLL and create .tli and .tlh header files that define the interfaces that are available in the DLL. Either way, you will have to find a COM interface that implements IDispatch.

    The GUID used in the setControl() call in the first post is the GUID of the COM CoClass exposed by the DLL, and that loads the DLL and creates an instance of the COM class. The queryInterface() call later uses that COM class to get a pointer to the IDispatch interface. Both of these methods are members of the QAxObject base class.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  16. #16
    Join Date
    Dec 2018
    Posts
    7
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: ActiveX | from MFC to Qt5

    Got a Qt to call methods over COM in a running Borland Builder app with this thread. Important to note that when invoking a method with multiple VARIANT* parameters the order of the parameters in the VARIANTARG array is applied in reverse order.

    Qt Code:
    1. void IGDAS::ReturnVideoFile(VARIANT& VideoFile, VARIANT& Angles, VARIANT& log)
    2. {
    3. DISPPARAMS pDispParams;
    4. VARIANTARG vArg[3];
    5. pDispParams.cArgs = 3;
    6. pDispParams.cNamedArgs = 0;
    7. pDispParams.rgdispidNamedArgs = nullptr;
    8. pDispParams.rgvarg = vArg;
    9.  
    10. VariantInit(&pDispParams.rgvarg[2]);
    11. pDispParams.rgvarg[2].vt = VT_VARIANT | VT_BYREF;
    12. pDispParams.rgvarg[2].pvarVal = &VideoFile;
    13.  
    14. VariantInit(&pDispParams.rgvarg[1]);
    15. pDispParams.rgvarg[1].vt = VT_VARIANT | VT_BYREF;
    16. pDispParams.rgvarg[1].pvarVal = &Angles;
    17.  
    18. VariantInit(&pDispParams.rgvarg[0]);
    19. pDispParams.rgvarg[0].vt = VT_VARIANT | VT_BYREF;
    20. pDispParams.rgvarg[0].pvarVal = &log;
    21.  
    22. VARIANT pVarResult;
    23. EXCEPINFO pExcepInfo;
    24. UINT puArgErr = (UINT)0;
    25. iface->Invoke(0x0E, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
    26. &pDispParams, &pVarResult, &pExcepInfo, &puArgErr);
    27. }
    To copy to clipboard, switch view to plain text mode 

    It would now be nice to know how to use invoke over COM on a method with not only an array of VARIANT* arguments but an additional argument of type int.

    Any help on this?

Similar Threads

  1. Activex and qml
    By codeman in forum Qt Quick
    Replies: 4
    Last Post: 7th September 2015, 18:11
  2. ActiveX-javascript invoke activex interface exception
    By zhy282289 in forum Qt Programming
    Replies: 0
    Last Post: 29th October 2012, 03:58
  3. ActiveX in QT
    By Ali Reza in forum Newbie
    Replies: 1
    Last Post: 21st June 2012, 15:54
  4. how to use WMI and ACTIVEX in Qt
    By sarang_neo in forum Newbie
    Replies: 5
    Last Post: 13th April 2011, 11:34
  5. ActiveX
    By franco.amato in forum Qt Programming
    Replies: 6
    Last Post: 29th December 2009, 18:06

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.