首先,调用ocx控件需要保证ocx本身是已经注册了的。如果没有注册请先按“Win+R”输入"cmd"打开命令窗口。然后输入regsvr32 + ocx来进行注册。输入regsvr32 /u +ocx来进行卸载。
ocx注册实际上是将控件注册到了注册表里,可以在注册表里查询到控件的信息。
注册后,我们可以使用QT相关类通过控件的uuid来进行调用。
如果不知道控件的uuid是多少,可以使用oleview.exe来查询(需要管理员权限打开)
在使用时,需要知道控件的头文件,同时需要通过数据类型对照表将对应的类型转换到Qt的类型。那么如果只有控件,没有头文件该怎么办呢?
我们可以使用Qt安装目录下的dumpcpp.exe来生成头文件与cpp文件。
我的路径是:C:\Qt\Qt5.12.11\5.12.11\msvc2017\bin\dumpcpp.exe,可以自行进入对应安装目录查找。
在已经注册了ocx并且知道id的情况下,在该目录打开cmd,执行dumpcpp.exe {id}
QT中提供了QAxBase、QAxWidget、QAxObject、QAxScript来实现对Active控件的使用
在使用时需要在pro文件中添加QT +=axcontainer
QAxBase是一个抽象类,不能实例化,他提供了API然后被QAxWidget和QAxObject继承。如果COM对象实现IDispatch接口,则该对象的属性和方法将作为Qt属性和插槽提供。他可以在COM组件的数据类型和QT对应的数据类型之间进行转换,有些COM的类型没有等价的Qt数据结构。数据类型对照表将放置在本文最后。下面是摘抄的官方示例:
- dispinterface IControl
- {
- properties:
- [id(1)] BSTR text;
- [id(2)] IFontDisp *font;
-
- methods:
- [id(6)] void showColumn([in] int i);
- [id(3)] bool addColumn([in] BSTR t);
- [id(4)] int fillList([in, out] SAFEARRAY(VARIANT) *list);
- [id(5)] IDispatch *item([in] int i);
- };
-
- QAxObject object("
" ); -
- QString text = object.property("text").toString();
- object.setProperty("font", QFont("Times New Roman", 12));
-
- connect(this, SIGNAL(clicked(int)), &object, SLOT(showColumn(int)));
- bool ok = object.dynamicCall("addColumn(const QString&)", "Column 1").toBool();
-
- QList
varlist; - QList
parameters; - parameters << QVariant(varlist);
- int n = object.dynamicCall("fillList(QList
&)" , parameters).toInt(); -
- QAxObject *item = object.querySubItem("item(int)", 5);
通过示例可以看到,使用控件的CLSID示例化一个QAxObject对象就可以加载这个控件。
通过使用QObject::setProperty ()和QObject::property ())可以直接调用ocx的idl文件中的属性。不支持具有多个参数的属性
通过dynamicCall (“方法(参数类型)”,参数) ;的方式可以调用ocx的方法。
如果COM对象实现IDispatch接口,那么可以通过信号槽的方式来调用。
connect(buttonBack, SIGNAL(clicked()), webBrowser, SLOT(GoBack()));
- callocx = new QAxWidget(parent);
- callocx->setControl(QString::fromUtf8("{21D328F3-B846-4a1e-9130-159163EC26D4}"));
- callocx->setProperty("Visible",true);
- callocx->show();
- callocx->dynamicCall("etBkColor(QColor)",QColor(255,255,142));
这样创建完运行时,会有一个单独的窗口显示ocx窗口。如果想要嵌入到自己的窗口里,可以在自己的窗口里创建一个布局,然后将QAxWidget添加入布局
ui->horizontalLayout->addWidget(callocx);
const QString | |||
href="https://runebook.dev/zh-CN/docs/qt/qdatetime" QDateTime | const QDateTime | href="https://runebook.dev/zh-CN/docs/qt/qdatetime" QDateTime | |
const QColor | |||
const QList | |||
const QList | |||
href="https://runebook.dev/zh-CN/docs/qt/qbytearray" QByteArray | const QByteArray | href="https://runebook.dev/zh-CN/docs/qt/qbytearray" QByteArray | |
href="https://runebook.dev/zh-CN/docs/qt/qstringlist" QStringList | const QStringList | href="https://runebook.dev/zh-CN/docs/qt/qstringlist" QStringList | |
const QVariant | |||
const QFont | |||
const QPixmap | |||
href="https://runebook.dev/zh-CN/docs/qt/qaxobject" QAxObject | href="https://runebook.dev/zh-CN/docs/qt/qaxobject" QAxObject | ||
href="https://runebook.dev/zh-CN/docs/qt/qaxobject" QAxObject | href="https://runebook.dev/zh-CN/docs/qt/qaxobject" QAxObject | ||