一,需求
将Qt 窗口封装成ActiveX 控件 供其它程序使用。
二,环境搭建
(1),QtCreator 新建不了active控件的工程,需要自己按照需要编写工程。
(2),vs 安装好助手后,自带了工程模板,但是我机器上编译会出错,暂时没有解决。
三,使用QtCreator 编写activeX控件
(1).pro文件
QT_CI_JENKINS_HOME=$$(JENKINS_HOME)
!isEmpty(QT_CI_JENKINS_HOME) {
message("Qt CI environment detected, suppressing example registration")
CONFIG += qaxserver_no_postlink
}
TEMPLATE = app
CONFIG += warn_off
QT += core gui concurrent axserver
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
comm/boxinteractorstyle.cpp \
comm/region.cpp \
comm/selectinteractorstyle.cpp \
comm/vtkpickercallback.cpp \
main.cpp \
widget.cpp
HEADERS += \
comm/boxinteractorstyle.h \
comm/region.h \
comm/selectinteractorstyle.h \
comm/vtkpickercallback.h \
widget.h
FORMS += \
widget.ui
INCLUDEPATH += $$PWD/3rd/VTK_8.2/include/vtk-8.2
LIBS +=$$PWD/3rd/VTK_8.2/lib/vtkChartsCore-8.2.lib
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DESTDIR = ./bin
UI_DIR = "$$OUT_PWD/temp/.ui"
RCC_DIR = "$$OUT_PWD/temp/.qrc"
MOC_DIR = "$$OUT_PWD/temp/.moc"
OBJECTS_DIR = "$$OUT_PWD/temp/.obj"
RESOURCES += \
paint.qrc
DEF_FILE = ActiveX.def
(2),.h 文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QListWidgetItem>
#include <ActiveQt>
#include "comm/selectinteractorstyle.h"
#include "comm/boxinteractorstyle.h"
#include "comm/vtkpickercallback.h"
//# 设置内存执行编码 UTF-8
#ifdef Q_OS_WIN
#pragma execution_character_set("UTF-8")
#endif
// ObjectSafety
//# 控件安全标记类
#include <QAxAggregated>
#include <objsafe.h>
#include <QUuid>
class ObjectSafety : public QAxAggregated, public IObjectSafety
{
public:
ObjectSafety(){
}
QAXAGG_IUNKNOWN;
long queryInterface(const QUuid &iid, void **iface)
{
*iface = NULL;
if (iid == IID_IObjectSafety)
{
*iface = (IObjectSafety*)this;
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
HRESULT WINAPI GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACESAFE_FOR_UNTRUSTED_CALLER;
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACESAFE_FOR_UNTRUSTED_CALLER;
return S_OK;
}
HRESULT WINAPI SetInterfaceSafetyOptions(REFIID riid, DWORD pdwSupportedOptions, DWORD pdwEnabledOptions)
{
return S_OK;
}
};
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
typedef enum StyleMode {
Box,Select
}StyleMode;
class Widget : public QWidget,public QAxBindable
{
Q_OBJECT
Q_CLASSINFO("ClassID", "{DD16845C-92CD-4AAB-A982-EB9840E74669}")
Q_CLASSINFO("InterfaceID", "{616F620B-91C5-4410-A74E-6B81C76FFFE0}")
Q_CLASSINFO("EventsID", "{E1816BBA-BF5D-4A31-9855-D6BA432055FF}")
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
private:
Ui::Widget *ui;
private:
QAxAggregated* createAggregate()
{
return new ObjectSafety;
}
};
#endif // WIDGET_H
(3),main.cpp 文件
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (!QAxFactory::isServer()) {
Widget w;
w.show();
return a.exec();
}
return a.exec();
}
//! [1]
QAXFACTORY_BEGIN("{EC08F8FC-2754-47AB-8EFE-56A54057F34E}", /* type library ID */ "{A095BA0C-224F-4933-A458-2DD7F6B85D8F}") /* application ID */
QAXCLASS(Widget)
QAXFACTORY_END()
//! [1]
(4).def 文件
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DumpIDL PRIVATE
四,编译完 注册
用qt再带的idc 命令
idc -regserver paintwork.exe
五,html 使用
只有IE 还支持activeX控件加载。
<html lang="en">
<head>
<meta name="GENERATOR" content="Microsoft Visual Studio">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>ActiveXCameraGui</title>
</head>
<body>
<object id="ActiveQtServer" style="width:1024px;height:1024px;" classid="CLSID:DD16845C-92CD-4AAB-A982-EB9840E74669">
<param name="Version" value="BTC">
</object>
<button onclick="alert(ActiveQtServer.Version())">Version</button>
<script>
window.onload = function () {
// var ret = ActiveQtServer.Version;
// alert(ret);//打印 初始化版本信息
//alert("Hello World!");//打印 Hello World!
};
</script>
</body>
</html>
六,效果